Skip to content

Automate C++ API cross-referencing, add ROS/EPick coverage, and generic UI conventions - #4

Open
bcastets-robotiq wants to merge 1 commit into
mainfrom
Doc-update
Open

bcastets-robotiq wants to merge 1 commit into
mainfrom
Doc-update

Conversation

@bcastets-robotiq

Copy link
Copy Markdown
Collaborator

Summary

Renames the Adaptive gripper product folder (2F hande -> Adaptive grippers), adds the EPick product and MuJoCo simulation entry, and brings every product's ROS support tables in line with what's actually documented upstream (robotiq/ros) - including a Legacy convention for the archived ROS1-Industrial packages, so they stop reading as an actively-maintained "third party" driver in the summary tables.

Generic pipeline/site additions, reusable well beyond this one update:

  • scripts/sync-external-docs.js - converts a submodule's own GitHub-style > **Note:**/> **Warning:** blockquotes into real Docusaurus admonitions during sync, and links a generated API member's return/parameter types using Doxygen's own resolved data (its XML <type> ref when present, falling back to its classic HTML output when the XML export omits one) instead of doxygen2docusaurus's flat, unlinked <definition> string.
  • scripts/generate-tools-table.js - self-installs a linked list of a tool page's own sub-sections (API reference, guides) and a guide folder's own contents list, ordered and placed via a ## Contents heading convention.
  • scripts/check-submodule-pins.js (new, wired into ci.yml) - fails CI if a submodule's pin, or external-jobs.js's declared branch, isn't actually reachable from that repo's real default branch - catches forgetting to revert a WIP-branch prototyping session before merging.
  • src/remark/ - external links open in a new tab site-wide, and `Robotiq` renders as the brand wordmark, both via small remark/rehype plugins.
  • docs/contribute/ - updated to document all of the above for future tool onboarding.

Test plan

  • Full npm run build + npm test pass against the current external/2f85_cpp pin (grippers main tip).
  • node scripts/check-submodule-pins.js passes for both submodules.
  • Verified the C++ API reference cross-linking fix against several real cases (return types with/without an XML ref, parameter types resolved only via Doxygen's HTML, and a genuinely unlinkable case left correctly as plain text).
  • Live review of the renamed/new ROS and EPick pages once deployed.

🤖 Generated with Claude Code

Supported by a massive ecosystem of pre-built libraries for everything from
data science to robotics, Python enables teams to quickly assemble functional
proofs-of-concept, pivot instantly based on testing, and validate core
software behaviors before committing to costly, production-grade infrastructure.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is our responsibility to explain why one would use Python.

| Script | Description |
|---|---|
| `build_launch_docker_ros2.sh` | Builds the Docker image and launches a container with sensor devices mapped in |
| `sensor_install.sh` | Sets up udev rules and permissions for bare-metal (non-Docker) use |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are adding documentation for ROS directly to the doc site. Shouldn't it be left in the ros repo, with the doc site pointing to it as an external module?

The ROS versions pages are almost entirely duplication. I think we should organize the doc more like in the ROS repo, where the doc explains how to use all versions at once , and differences are highlighted inline.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will check next week

if (memberXml) {
result = {
returnType: memberXml.match(/<type>([\s\S]*?)<\/type>/)?.[1] ?? null,
params: [...memberXml.matchAll(/<param>([\s\S]*?)<\/param>/g)]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getMemberFields includes <templateparamlist> params and takes the first <type> as the return type, so templated members get misaligned param types and a bogus return type.

E.g. Robotiq::waitUntil / waitFor in group__wait.xml have <templateparamlist><param><type>typename Predicate</type></param></templateparamlist> before the real params. returnType becomes typename Predicate (not bool) and params = ['typename Predicate','Predicate','Platform &',…] while the doxyMemberNameParamType cells are ['Predicate','Platform &',…]. Every cell is then matched against the wrong param, so the Platform link Doxygen's own HTML has is silently lost (and a class return type would lose its link too).

Suggest stripping the <templateparamlist>…</templateparamlist> block before matching <param>, and reading the return <type> after it.

// is the *whole* <type> field (qualifiers, "&"/"*" and all), so this
// has to be a prefix check, not an exact match; a plainText that
// exactly equals the link text (no trailing qualifier) still passes.
if (!plainText.startsWith(m[2])) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefix match means qualified types are never linked. plainText.startsWith(m[2]) (and cellHtml.startsWith(resolved.plainText) in linkifyLeadingText) require the type name to be a prefix of the whole cell text, so const DeviceProfile &amp; never matches DeviceProfile even though Doxygen's HTML links it. The comments in resolveTypeLink / linkifyLeadingText say a leading const is handled; it isn't.

Suggest matching the identifier at a word boundary inside the text and splicing the <a> at that offset.

// has to be a prefix check, not an exact match; a plainText that
// exactly equals the link text (no trailing qualifier) still passes.
if (!plainText.startsWith(m[2])) continue;
const linkText = m[2];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First-prefix-wins picks the wrong link for identifiers that share a prefix. Iterating <a class="el"> in the memname block and returning the first whose text is a prefix of plainText: for foo(Gripper &g, GripperStatus s) where GripperStatus has no <ref> in XML, 'GripperStatus'.startsWith('Gripper') is true → Gripper class URL, and linkifyLeadingText renders <a href=…/gripper>Gripper</a>Status.

Compare against the full leading identifier (word boundary), not a prefix.

const pinned = execFileSync('git', ['rev-parse', 'HEAD'], { cwd, encoding: 'utf8' }).trim();
const defaultBranch = fetchDefaultBranch(repoUrl);

if (declaredBranch !== defaultBranch) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declared branch ≠ remote default is a hard failure, though the message itself says it may be deliberate. A submodule intentionally pinned to a stable non-default branch can never pass CI. Also two mismatches with this:

  • .github/workflows/ci.yml:70-74 describes the step as "reachable from external-jobs.js's declared branch", but the script tests the remote default branch.
  • Header comment (line 16) says 2f85_cpp declares documentation-update; external-jobs.js declares main.

Suggest: check reachability from the declared branch, and downgrade declared-vs-default to a warning (or compare separately). Fix the ci.yml step name and the stale header.

fs.writeFileSync(indexPath, [...before, '', block, ...after].join('\n'), 'utf8');
}

function ensureSubpagesBlock(indexPath) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUBPAGES/GUIDES blocks in tracked index.mdx files are derived from gitignored, sync-generated output (API/index.md, docs/*.md). Running node scripts/generate-tools-table.js on a fresh clone, after a doxygen failure, or via npm run preview before the API job has run: collectSubpages finds no API/index.md and collectFolderGuides finds no guides → the tracked Adaptive grippers/SDK/C++/index.mdx loses its "API Reference" box and docs/index.mdx's guide list is emptied, leaving a dirty diff that's easy to commit by mistake (and CI then "fixes" it back).

Either generate these lists at build time (component/plugin reading the folder) or skip the rewrite when the expected inputs are absent.

Comment thread docs/intro.mdx
{/* AUTO-GENERATED-OTHER-TABLE:END */} No newline at end of file
{/* AUTO-GENERATED-OTHER-TABLE:END */}

) No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray ) after the OTHER table end marker — renders as a literal ) paragraph at the bottom of the landing page. It's outside the marker pair, so generate-tools-table.js will keep it forever. Delete this line.

Comment thread docs/intro.mdx
Robotiq hardware communication protocols are described in detail in the product
manuals, which serve as the reference for developing custom drivers.
Lots of software tools are available to work with `Robotiq` products. Some of
those tools are developped and maintained by `Robotiq` and some other by the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "developped" → "developed" (also lines 14, 15), and "developpers" → "developers" (line 11).

│ │ ├── index.mdx
│ │ └── ROS2-Humble/ …
│ └── 2F hande/
│ └── Adaptive grippers/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tree below (lines ~66-70) still lists ROS2-Rolling/, ROS2-Iron/, ROS1-Jade/, which this PR removes, and omits the ROS2-Jazzy/ / ROS2-Lyrical/ pages that now exist. Same in adding-a-tool.mdx:130, which calls Adaptive grippers/ROS/ a "seven-distro example" — it's six now.

…ic UI conventions

Renames the Adaptive gripper product folder (2F hande -> Adaptive grippers),
adds the EPick product and MuJoCo simulation entry, and brings the ROS
support tables for every product in line with what's actually documented
upstream (robotiq/ros), including a Legacy convention for archived
ROS1-Industrial packages that no longer counts as "third party" in the
summary tables. Also moves the Adaptive grippers Isaac Sim entry from
"third party" (pointing at NVIDIA's own generic embedded-assets docs) to
Robotiq-maintained, syncing a new submodule (robotiq/isaacsim_assets) and
its gripper simulation guide the same way every other Robotiq-maintained
tool page already works.

Generic pipeline/site additions, reusable well beyond this one bump:
- scripts/sync-external-docs.js: converts a submodule's own GitHub-style
  `> **Note:**`/`> **Warning:**` blockquotes into real Docusaurus
  admonitions during sync, links a generated API member's return/
  parameter types using Doxygen's own resolved data (its XML `<type>` ref
  when present, falling back to its classic HTML output when the XML
  export omits one) instead of doxygen2docusaurus's flat, unlinked
  `<definition>` string, and fixes its H1-stripping regex to handle a
  synced file's Windows CRLF line endings correctly.
- scripts/generate-tools-table.js: self-installs a linked list of a tool
  page's own sub-sections (API reference, guides) and a guide folder's own
  contents list, ordered and placed via a `## Contents` heading convention.
- scripts/check-submodule-pins.js (new, wired into ci.yml): fails CI if a
  submodule's pin, or `external-jobs.js`'s declared branch, isn't actually
  reachable from that repo's real default branch — catches forgetting to
  revert a WIP-branch prototyping session before merging.
- src/remark/: external links open in a new tab site-wide, and `` `Robotiq` ``
  renders as the brand wordmark, both via small remark/rehype plugins.
- docs/contribute/: updated to document all of the above for future tool
  onboarding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants