Skip to content

Number footnotes by reference order, and carry source positions - #4

Merged
elementmerc merged 1 commit into
mainfrom
fix/footnote-numbers-and-source-positions
Jun 15, 2026
Merged

elementmerc merged 1 commit into
mainfrom
fix/footnote-numbers-and-source-positions

Conversation

@elementmerc

Copy link
Copy Markdown
Owner

What

Two changes to the renderer, bundled.

Footnotes render as numbers, not labels. A footnote marker was showing the footnote's internal label (the word after the caret), so a reference to [^scripts] appeared as the word "scripts" stuck onto the end of the sentence instead of a superscript number. Now each footnote gets a number by the order it's first referenced (the GFM convention), the number is mirrored on the note at the bottom, and the note links back to where it was cited. The numbering runs in the existing pre-pass, the same way citations are already numbered, so the inline marker and the bottom list can't disagree. The demo theme gains the footnote styling it never had.

Source positions (data-line). The renderer can now stamp each top-level block with its 1-based source line, gated behind RenderOptions so default output stays byte-identical. The parser captures those lines through directive segmentation and footnote relocation; the wasm boundary exposes a positions-on entry point. This is the groundwork the editor extension needs to map a rendered block back to its source for scroll-sync.

Verification

  • cargo test --workspace green; new tests cover reference-order numbering, the label-never-shown invariant, and the back-link.
  • CommonMark conformance: 652/652 (100%) unchanged (footnotes don't touch the spec path).
  • cargo clippy --workspace --all-targets -D warnings clean; cargo fmt --check clean.
  • Verified on the real demo articles: languages.alt numbers 1, 2; cs-lewis.alt numbers 1 to 4, all in reference order.

Merging deploys the playground via the Pages workflow.

A footnote marker was rendering the footnote's internal label (the word
after the caret) as its visible text, so a reference to [^scripts] showed
up as "scripts" jammed onto the end of the sentence instead of a small
superscript number. Readers expect the GFM convention: a number assigned
by the order each footnote is first referenced, mirrored on the note at
the bottom, with a link back to where it was cited. Numbering is done in
the existing pre-pass, the same way citations are already numbered, so the
inline marker and the definition list can never disagree. The demo theme
gains the matching footnote styling it never had.

Folded in alongside it: the renderer can now stamp each top-level block
with a data-line attribute giving its 1-based source line, gated behind
RenderOptions so default output stays byte-identical. The parser captures
those lines through directive segmentation and footnote relocation, and
the wasm boundary exposes a positions-on entry point. This is what lets an
editor map a rendered block back to its source for scroll-sync.
@elementmerc
elementmerc merged commit 9d7defe into main Jun 15, 2026
5 checks passed
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