Skip to content

fix(docs): escape curly braces and always fence examples for MDX#585

Draft
xke wants to merge 1 commit into
mainfrom
fix/mdx-safe-doc-generation
Draft

fix(docs): escape curly braces and always fence examples for MDX#585
xke wants to merge 1 commit into
mainfrom
fix/mdx-safe-doc-generation

Conversation

@xke
Copy link
Copy Markdown

@xke xke commented May 15, 2026

User description

Summary

The Publish Docs workflow has been generating MDX files that fail Mintlify's MDX parser on the consuming side (rungalileo/docs-official). Recent docs-official PRs (#902, #906) both hit acorn parse errors that required manual MDX patching. This fix addresses the root cause in create_docs.py.

Bugs fixed

  1. Unescaped {...} in body prose. description, returns, raises, and notes text was emitted raw. Any docstring that included a Python dict literal, f-string format spec, or RST literal block with {...} would produce MDX that acorn tried to parse as a JSX expression and rejected. Example failure: experiment.mdx:498:38 parsing {agg.avg:.3f} in a :: literal block.

  2. Examples only fenced when prefixed with >>>. Plain-Python example sections (no doctest prefix) were emitted unfenced, so any { inside them tripped the same JSX parser. Example failure: dataset.mdx:21:17 parsing {"input": ...}.

  3. escape_curly_braces was scoped inside write_function's params loop and applied nowhere else — including write_class params, which had no escaping at all.

Changes

  • Lift escape_curly_braces to module scope so all three writers (write_function, write_class, write_module) can use it.
  • Add render_examples helper that wraps each example in a python fence unconditionally and strips >>> / ... doctest prefixes line-by-line.
  • Apply escape_curly_braces to every description, param desc, raise desc, return desc, and note text across the three writers.
  • Replace the conditional fence opener with unconditional fencing via render_examples.

Net: +56 / -65 lines (consolidation via helpers).

Test plan

  • python3 -c "import ast; ast.parse(open('scripts/create_docs.py').read())" — file parses
  • Smoke tests on real broken inputs (RST literal blocks, inline code preservation, fenced-block preservation, doctest-prefix stripping, empty/None safety) — all pass
  • Run Publish Docs workflow manually after merge and verify the generated PR against docs-official passes CI without manual MDX patches

Out of scope

This fix prevents MDX parse errors but does not convert RST :: literal blocks into proper fenced code blocks — those will still render with literal :: and an indented but unhighlighted block. That's a bigger refactor (would require walking the description string with an RST-aware parser) and worth filing separately if rendering quality matters.

🤖 Generated with Claude Code


Generated description

Below is a concise technical summary of the changes proposed in this PR:
Update create_docs.py to escape curly braces in descriptions, params, raises, returns, and notes so MDX consumers no longer misinterpret prose as JSX, and consolidate the helper for these writers. Ensure every documented example runs through the new fenced render_examples helper that strips doctest prefixes before emitting python code blocks.

TopicDetails
MDX escaping Escape prose across write_function, write_class, and write_module with the module-level escape_curly_braces helper so descriptions, params, raises, returns, and notes never emit raw {...} sequences.
Modified files (1)
  • scripts/create_docs.py
Latest Contributors(2)
UserCommitDate
xian@galileo.aifix(docs): escape curl...May 15, 2026
fernando.correia@galil...chore: update ruff tar...April 07, 2026
Example fencing Fence examples through the new render_examples helper that strips doctest >>>/... prefixes and emits a consistent python code block every time a function, class, or module declares examples.
Modified files (1)
  • scripts/create_docs.py
Latest Contributors(2)
UserCommitDate
xian@galileo.aifix(docs): escape curl...May 15, 2026
fernando.correia@galil...chore: update ruff tar...April 07, 2026
Review this PR on Baz | Customize your next review

The autogenerated MDX docs in docs-official have been failing CI
with acorn parse errors because the generator emits unescaped
`{...}` in body prose (e.g. RST literal blocks, dict literals
in docstring descriptions) and unfenced Python in Examples
sections that don't use the doctest `>>>` prefix.

Changes:
- Lift `escape_curly_braces` to module scope so all three writers
  can use it.
- Add `render_examples` helper that always wraps each example in
  a python code fence and strips doctest prefixes line-by-line.
- Apply `escape_curly_braces` to every description, param desc,
  raise desc, return desc, and note text in write_function,
  write_class, and write_module.
- Replace the conditional ``` opener (only fenced when example
  starts with `>>>`) with unconditional fencing.

This eliminates the recurring CI failures on docs-official PRs
generated by the Publish Docs workflow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.27%. Comparing base (df4b61b) to head (5bcbbfb).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #585   +/-   ##
=======================================
  Coverage   83.27%   83.27%           
=======================================
  Files         125      125           
  Lines       10617    10617           
=======================================
  Hits         8841     8841           
  Misses       1776     1776           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread scripts/create_docs.py
Comment on lines +539 to +541
parts.append("```python")
parts.append("\n".join(stripped).rstrip())
parts.append("```\n")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

render_examples() now wraps every parsed example in an outer ```python fence even when the example text already has Markdown/prose, so nested fences get stored in examples[].code and the MDX render breaks. Can we detect/prevent pre-fenced blocks or split prose vs code before adding the wrapper fence?

Finding type: Breaking Changes | Severity: 🟠 Medium


Want Baz to fix this for you? Activate Fixer

Other fix methods

Fix in Cursor

Prompt for AI Agents
Before applying, verify this suggestion against the current code. In
scripts/create_docs.py around lines 524-542 inside `render_examples(parts, examples)`,
fix the example formatting to avoid nesting Markdown fences. Right now the function
always appends an outer ```python fence and then dumps the entire `ex['code']`, which
can already contain triple-backtick blocks plus explanatory prose, causing broken MDX
rendering. Refactor `render_examples` to detect when `code` already includes
triple-backtick fences (and in that case append the content without wrapping again, or
parse/split prose from fenced code before fencing); keep the doctest `>>>` / `...`
stripping behavior only for lines that are actual doctest prompts. Ensure the output
matches the previous behavior of only adding fences when the example truly contains
doctest snippets rather than pre-fenced Numpydoc sections.

Comment thread scripts/create_docs.py
Comment on lines 731 to 732
parts.append("**Arguments**\n")
for p in md.get("params", []):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The params rendering block is duplicated in write_class and write_function, repeating the same doc.get('params') iteration, escaping, and bullet markup—should we extract it into a shared helper like append_param_list(parts, params) so future formatting/escaping changes only touch one place?

Finding type: Code Dedup and Conventions | Severity: 🟢 Low


Want Baz to fix this for you? Activate Fixer

@xke xke marked this pull request as draft May 15, 2026 07:10
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.

1 participant