fix(muya): give each repeated footnote reference its own id and backref by Jocs · Pull Request #5492 · marktext/marktext · GitHub
Skip to content

fix(muya): give each repeated footnote reference its own id and backref - #5492

Merged
Jocs merged 1 commit into
developfrom
fix/footnote-duplicate-ref-id-5488
Sep 21, 2026
Merged

Jocs merged 1 commit into
developfrom
fix/footnote-duplicate-ref-id-5488

Conversation

@Jocs

@Jocs Jocs commented Sep 21, 2026

Copy link
Copy Markdown
Member

Closes #5488

Problem

Every reference to a given note was rendered with the same id:

a<sup class="footnote-ref"><a href="#fn-1" id="fnref-1">1</a></sup>
 b<sup class="footnote-ref"><a href="#fn-1" id="fnref-1">1</a></sup>.

id must be unique in a document, and the consequence is not only formal: the note carried a single ↩ pointing at fnref-1, so the second and later references were unreachable — the arrow always landed on the first one.

Fix

Number the occurrences. The first reference keeps fnref-N; later ones take a -k suffix, and the note gets one arrow per reference — bare for the first, numbered after that, so they can be told apart:

a<sup class="footnote-ref"><a href="#fn-1" id="fnref-1">1</a></sup>
 b<sup class="footnote-ref"><a href="#fn-1" id="fnref-1-2">1</a></sup>.

<li id="fn-1"><p>shared
  <a href="#fnref-1" class="footnote-backref">↩</a>
  <a href="#fnref-1-2" class="footnote-backref">↩2</a></p></li>

This is the shape GFM emits. pandoc takes the other route and duplicates the note itself (two entries numbered 1 and 2), which loses the "one note, cited twice" relationship — muya's reuse is the better behaviour, so only the id allocation and the backref set change here.

A note referenced once is untouched: same single fnref-N, same bare ↩.

Out of scope

The editor's inline renderer still puts id="noteref-{identifier}" on every reference (packages/muya/src/inlineRenderer/renderer/footnoteIdentifier.ts), so the same duplication exists in the contenteditable DOM. Fixing that needs document-wide occurrence numbering, which the per-block inline renderer has no access to, and the current behaviour there is benign — Footnote's backlink calls getElementById, which lands on the first reference. Noted in #5488 rather than bundled here.

Tests

New in packages/muya/src/state/__tests__/footnoteHtml.spec.ts:

  • three references to one note produce fnref-1, fnref-1-2, fnref-1-3, and three backref arrows labelled ↩, ↩2, ↩3, each pointing at its own reference
  • a note referenced once still gets exactly one bare ↩

The first fails on develop; the second passes either way and pins the common case against the change.

Verification

muya unit suite 1987 ✅, CommonMark/GFM conformance 1347 ✅, eslint + tsc ✅, desktop unit suite 861 ✅, desktop build ✅.

Every reference to the same note carried `id="fnref-N"`, so a note cited
more than once produced duplicate ids — invalid HTML, and the note's single
backlink arrow could only ever reach the first of them.

Number the occurrences: the first keeps `fnref-N`, later ones take a
`-k` suffix, and the note gets one arrow per reference (bare for the first,
numbered after that). This is the shape GFM emits; pandoc instead duplicates
the note itself, which loses the "one note, cited twice" relationship.

The editor's inline renderer still emits `id="noteref-{identifier}"` per
reference. Left alone here: the fix needs document-wide occurrence numbering
that the per-block inline renderer doesn't have, and in a contenteditable
DOM the current behaviour (backlink lands on the first reference) is benign.

Closes #5488

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Jocs
Jocs force-pushed the fix/footnote-duplicate-ref-id-5488 branch from 30c2e2b to bbd4207 Compare September 21, 2026 23:30
@Jocs
Jocs merged commit 96e368b into develop Sep 21, 2026
csells added a commit to csells/MarkText that referenced this pull request Sep 25, 2026
Upstream's export numbers every reference to a note with its own id
(fnref-N, fnref-N-2, ...) and one backref per reference, and leaves a
reference inside a note body literal (marktext#5492). The document-model export gave
repeated references one shared id and a single backref, and resolved
references inside note bodies; render them as upstream does through Muya's
shared footnote helpers.
csells added a commit to csells/MarkText that referenced this pull request Sep 25, 2026
Upstream's export numbers every reference to a note with its own id
(fnref-N, fnref-N-2, ...) and one backref per reference, and leaves a
reference inside a note body literal (marktext#5492). The document-model export gave
repeated references one shared id and a single backref, and resolved
references inside note bodies; render them as upstream does through Muya's
shared footnote helpers.
csells added a commit to csells/MarkText that referenced this pull request Oct 13, 2026
Upstream's export numbers every reference to a note with its own id
(fnref-N, fnref-N-2, ...) and one backref per reference, and leaves a
reference inside a note body literal (marktext#5492). The document-model export gave
repeated references one shared id and a single backref, and resolved
references inside note bodies; render them as upstream does through Muya's
shared footnote helpers.
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.

[Bug] Referencing the same footnote twice emits a duplicate DOM id and an unreachable backlink

1 participant