Skip to content

ci/docs: escape MDX-incompatible patterns in gen-docs output#1076

Open
lennessyy wants to merge 6 commits into
mainfrom
fix/gen-docs-mdx-escaping
Open

ci/docs: escape MDX-incompatible patterns in gen-docs output#1076
lennessyy wants to merge 6 commits into
mainfrom
fix/gen-docs-mdx-escaping

Conversation

@lennessyy

@lennessyy lennessyy commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add escapeMDXDescription() to escape patterns in command descriptions that break Docusaurus MDX compilation:
    • Heading IDs ({#custom-id}) — converted to MDX-compatible {/* #custom-id */} comment syntax, preserving custom anchors
    • Angle-bracket placeholders (<base64-encoded-cert>, <key>, etc.) — escaped with backslashes so MDX doesn't interpret them as HTML tags (lowercase-only to avoid escaping real HTML tags)
    • Curly braces in JSON examples ('YourKey={"your": "value"}') — escaped so MDX doesn't interpret them as JSX expressions
  • Code fences and inline code (backtick spans) are left untouched
  • Fix encodeJSONExample() regex to correctly match patterns like 'YourKey={"your": "value"}' (the previous regex was non-greedy and failed on these)
  • Align the JSON escaping regex between escapeMDXDescription and encodeJSONExample so both handle nested JSON like '{"a": {"b": "c"}}'
  • Add cross-reference comments between the two escaping functions so maintainers understand the split: encodeJSONExample handles option description table cells, escapeMDXDescription handles command description body text
  • No changes to commands.yaml — the escaping is applied automatically during generation

Context

The documentation site uses Docusaurus with MDX, which has a stricter parser than standard Markdown. New CLI commands added since early 2026 (task queue fairness weights, cloud connectivity rules, etc.) introduced angle-bracket placeholders and JSON examples in descriptions that MDX interprets as JSX. The {#id} heading syntax also breaks under Docusaurus 3.10's MDX parser. These patterns worked in standard Markdown but break the docs site build.

Test plan

  • Regenerated docs from latest CLI + cloud-cli and verified clean Docusaurus build
  • Verified code fences, inline backtick spans, and real HTML tags are not affected
  • Verified heading IDs are converted to working {/* #id */} anchors

🤖 Generated with Claude Code

The generated MDX docs contain patterns that break Docusaurus MDX
compilation: heading IDs ({#id}), bare angle-bracket placeholders
(<name>), and curly braces in JSON examples within descriptions.

Add escapeMDXDescription() to handle these cases in command
descriptions, complementing the existing encodeJSONExample() that
already handles option descriptions. Also fix the one heading ID
instance in commands.yaml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lennessyy lennessyy requested a review from a team as a code owner June 2, 2026 19:16
lennessyy and others added 3 commits June 2, 2026 12:36
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Docusaurus supports {/* #id */} for custom heading IDs in MDX.
Convert {#id} to this format so custom anchors are preserved.
Revert commands.yaml changes since the YAML can keep the
standard {#id} syntax.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The encodeJSONExample regex was not matching patterns like
'YourKey={"your": "value"}' where the closing brace isn't at
the end. Use a broader pattern that matches any single-quoted
string containing curly braces.

Revert commands.yaml since the heading ID conversion in
escapeMDXDescription handles {#id} automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lennessyy lennessyy changed the title Escape MDX-incompatible patterns in gen-docs output docs: escape MDX-incompatible patterns in gen-docs output Jun 4, 2026
@lennessyy lennessyy changed the title docs: escape MDX-incompatible patterns in gen-docs output ci/docs: escape MDX-incompatible patterns in gen-docs output Jun 4, 2026
Align reJSONInSingleQuotes with encodeJSONExample to use [^']*
inside braces instead of [^}]*, so nested JSON like
'{"a": {"b": "c"}}' is handled correctly.

Add cross-reference comments between encodeJSONExample and
escapeMDXDescription so maintainers understand why there are
two escaping functions for the same class of issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jsundai

jsundai commented Jul 6, 2026

Copy link
Copy Markdown

Thanks, harani-mukkala! 🙌

@chaptersix

Copy link
Copy Markdown
Contributor

We should consider by PR first.

chaptersix added a commit that referenced this pull request Jul 8, 2026
…#1112)

## Summary

This consolidates the excellent groundwork in #980, #1076, and #981 into
a single change, and verifies the result against a real Docusaurus
3.10.1 build. Huge thanks to @lennessyy — the approach here is entirely
built on those PRs; this just stitches them together and irons out a few
interactions between them.

gen-docs now escapes the patterns that break Docusaurus MDX (JSX)
compilation, on **every** path that writes a command description
(including the new split paths):

- bare angle-bracket placeholders in prose (e.g.
`<base64-encoded-cert>`, `<key>`) → `\<...\>`
- single-quoted JSON examples (e.g. `'{"a":"b"}'`, `'Key={"a":"b"}'`) →
braces escaped in body text, backticked in option tables
- custom heading IDs (e.g. `## Heading {#id}`) → `{/* #id */}`, the form
that compiles under Docusaurus 3.10 and still produces the custom anchor

Fenced code blocks and inline code spans are left untouched.

It also adds the `-subdir` flag (subcommands of the named command are
written to a subdirectory, e.g. `-subdir cloud` → `cloud/*.mdx`, with
deeper subcommands nested as headings), and a generic auto-generated
notice.

## What changed relative to the existing PRs

All three PRs were on the right track. The differences here are about
how they interact:

- **#1076 (MDX escaping):** kept as the core of this change, including
the `{#id}` → `{/* #id */}` heading conversion — which I confirmed is
exactly right for the 3.10 upgrade (see verification below). Escaping is
now also applied to the `-subdir` split output, so cloud docs get the
same treatment. Re-added unit tests for the escaping logic.
- **#980 (`-subdir`):** kept the split mechanism. Unified the
`encodeJSONExample` regex so it matches both `'{...}'` and `'Key={...}'`
(the standalone-vs-key-value cases the two PRs handled separately).
Intentionally did **not** carry over #980's index-page generation:
`command-reference/index.mdx` and `cloud/index.mdx` are hand-maintained
on the docs site (custom ordering, the `ReleaseNoteHeader` component),
so gen-docs deliberately does not emit them — generating them would
overwrite that curated content. The companion docs PR restores those
files after each regeneration.
- **#981 (generic notice):** folded in — the previous notice pointed at
paths that no longer exist and don't hold for cloud-cli inputs.

## Companion PR
temporalio/documentation#4836
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.

4 participants