Skip to content

Inline parser & better parity with stock renderer#54

Merged
benjaminleonard merged 23 commits into
mainfrom
inline-parser
Jun 8, 2026
Merged

Inline parser & better parity with stock renderer#54
benjaminleonard merged 23 commits into
mainfrom
inline-parser

Conversation

@benjaminleonard

@benjaminleonard benjaminleonard commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Adds a vendored TypeScript port of Asciidoctor's inline substitution pipeline (src/asciidoc/inline/). Previously, inline content was a raw HTML string from getContent() passed through dangerouslySetInnerHTML. Now prepareDocument runs the full six-pass substitution pipeline (specialcharacters → quotes → attributes → replacements → macros → post-replacements) and produces an InlineNode[] AST that templates can render as a real React tree.

The main payoff is inlineOverrides: consumers can now swap in their own React components for individual inline node types (links, xrefs, footnotes, images, kbd, etc.) without owning the whole block template.

Parity with stock Asciidoctor goes from ~85% to ~95% across a corpus of ~2000 real documents (cannot include in the repo directly). The remaining ~5% is documented in the README's "Known differences" section — mostly the two #-in-code cases, a placeholder-leak bug, and some footnote edge cases.

Other things in this PR:

  • RenderInline component for rendering inline ASTs as React elements, with a dangerouslySetInnerHTML fallback for passthrough HTML that straddles sibling nodes
  • All block templates updated to use RenderInline / useInlineRenderMode() instead of html-react-parser
  • Document-wide footnote and counter state tracked across blocks in source order
  • Cross-reference resolution, including natural xrefs (<<Section Title>>), xref style overrides, and bibliography xrefs with external URL and citation body on the anchor node
  • 12 new example fixtures; 79 total, 78 passing (the one failure is {set:cellbgcolor}, not implemented)
  • Expanded README with usage examples for block and inline overrides

Fixes #44

Canary: npm install @oxide/react-asciidoc@1.3.0-canary.5535dcb

@benjaminleonard benjaminleonard added the major Increment the major version when merged label May 29, 2026
…mbers only

STATUS.md no longer enumerates failing docs (some RFDs are public) — totals and
category counts only. CONTEXT.md carries the durable parity workflow extracted
from HANDOFF, minus the historical fix log.
Bug 1 — straddling `pass:q[…]` corrupted when overrides registered

`src/asciidoc/RenderInline.tsx` — `useInlineRenderMode` now returns `react: !hasRawInline(nodes)` unconditionally. Removed the now-unused `hasOverrides` computation and rewrote the two doc comments (the function header and the `hasRawInline` header) to document the new behavior and state the trade-off you called out: an override targeting a node *inside* a straddling run won't apply, which is rare and cosmetic, versus the old behavior corrupting visible content.

## Bug 2 — `\email@email.com` kept its backslash

`src/asciidoc/inline/parser.ts:1487` — the bare-email handler now special-cases `prefix === '\\'`, returning `{ type: 'text', text: m[0].slice(1) }` (backslash stripped, unlinked). The `> : /` lead chars still `return null` (whole match left literal), and the comment now distinguishes the escape case from the genuine non-linking-context cases.
React 19 hydration fix on June 5 that added `<tbody>` to the admonition/colist/dlist/hdlist table templates but never updated the test normalizer to account for it.
@benjaminleonard benjaminleonard marked this pull request as ready for review June 8, 2026 14:16
@benjaminleonard benjaminleonard merged commit a193872 into main Jun 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

major Increment the major version when merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTML "tags" not escaped in code blocks

1 participant