Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

AST renderer gaps

These are node shapes that myst-to-md doesn’t render cleanly, found by running our renderer over real deployed pages. Being able to render these probably requires changing mystmd upstream. We try to describe what would need to be done in each case below.

renderMd (src/render.ts) delegates to myst-to-md’s writeMd, which targets parsed mdast. Deployed page JSON is post-transform mdast, so some node shapes it never expected to see turn up. This table is the tally from running renderMd over every heading-anchored section in tests/fixtures/ (see the round-trip and golden sections blocks in tests/render.test.ts).

Node typeSeen inWhat myst-to-md doesFallbackUpstream issue?
outputs (notebook cell-output wrapper)mystmd-guide/page.interactive-notebooks.jsonWarns Unsupported node type: outputs and drops the whole subtree (children, e.g. output, are never visited)None — output content is silently omitted from the markdownMaybe — myst-to-md could special-case executed-notebook output the way it special-cases container[kind=figure], since deployed sites always carry these
container[kind=figure] with no resolvable image node and no source fieldmystmd-guide/page.interactive-notebooks.json (e.g. #static-images, img:mpl)Throws (Cannot read properties of undefined (reading 'label')) — it does `#${node.source.label}` unguarded when no image is foundrenderMd pre-pass (guardThrowingContainers in src/render.ts) swaps the whole container for {type: 'code', value: JSON.stringify(node)} before calling writeMd, so the section still renders instead of crashing. Ugly but visible; see the #static-images golden snapshotYes — the throw is a real bug independent of this project (unguarded property access), worth filing against myst-to-md
myst (raw passthrough source)mystmd-guide/page.website-style.jsonWarns Unsupported node type: myst and drops itNone — the node’s .value field is actually already-valid MyST markdown, but per project rules gaps aren’t patched inline, only documentedMaybe — a handler that emits node.value verbatim would be a natural, low-risk addition upstream
grid node child not recognized as cardmystmd-guide/page..json, mystmd-guide/page.website-style.json, jupyterbook/* (any page with a grid/card directive)Warns Unexpected grid node child is not card: undefined (validator bug: checks child.kind !== 'card', but card nodes carry type: 'card' and have no kind field, so this always fires)None needed — rendering still succeeds despite the false-positive warning (see #get-involved, #project-goals golden snapshots)Yes — validator checks the wrong field; harmless today but noisy and worth a small upstream fix
tabSet node child not recognized as tabItemmystmd-guide/page..json (3 warnings in the sweep) — same validator pattern as grid/card (child.kind !== 'tabItem')Same false-positive warning as aboveNone neededSame as grid/card
embed (resolved cross-project embed)mystmd-guide/page.website-style.json (#style-sheet golden snapshot)Silent content loss, no warning: the handler (writeStaticDirective('embed', {argsKey: 'label'})) ignores the node’s resolved children (real prose) and reads node.label, but deployed AST stores it at node.source.label — output is a bare empty ```{embed} directiveNone yet — invisible to the warning tally, found only by reading the golden snapshot against the fixtureYes — worst gap found: silent loss of resolved content; handler should render children when present

Notes