Repository navigation
Fidelity constructs: implement the semantic-verdict rows (definitions table, link titles, task lists, math, HTML residue) #722
Description
Migrated from ExaDev/markdown-codec#66 ahead of that repository's archival. Concerns packages/markdown-codec.
Implementation half of the construct inventory from ExaDev/markdown-codec#63 (closed, verdict table preserved there), feeding the harmonised vocabulary that has since landed in document-schema.js (src/construct.ts, published in 4.3.1: anchor, link with a title field, field, division, provenance). The pole-case finding still holds -- markdown needs no new generic construct kind, every semantic verdict lands on a mechanism the schema already defines.
Re-verified against the current monorepo code (packages/markdown-codec on the ExaDev/documents.js default branch) rather than carried over blind. One row has shipped since the original issue; every other row is unchanged and still open.
- Footnotes (
[^n]marker + definition) -- shipped in feat: read and write GitHub footnotes, with definitions as anchor constructs markdown-codec#69, confirmed still in place:lowerFootnoteDefinition(packages/markdown-codec/src/lower/lower.ts:256-260) wraps the definition body in aconstructStart/constructEndpair carrying{ kind: 'anchor', anchorType: 'footnote', name }; the reference marker is carried as a marked run (md/footnote-reference-preserved-as-text), which is the documented remaining gap -- a run-level anchor extent still doesn't exist, so the marker can't be a construct itself. - Reference link definitions (
[label]: dest "title") -- package-level definitions table, the same facility the styles table rides. Still dies at lowering:extractDefinitionsbuilds the map (packages/markdown-codec/src/block/definitions.ts:66),parseMarkdownreturns it asreferences(packages/markdown-codec/src/block/block.ts:854), butlowerParsedMarkdownreads onlyparsed.document.childrenand never touchesparsed.references(packages/markdown-codec/src/lower/lower.ts:314) -- the map is built and immediately discarded. - Link/image titles -- now that
document-schema.js'slinkconstruct descriptor has atitlefield for exactly this case (an annotated extent a flat run field can't express), this row is unblocked but not implemented. Still dropped on every path: inline links and images both sinkLINK_TITLE_DROPPED(packages/markdown-codec/src/lower/inline.ts:77-78,86-87), and the resolved-image-block path does the same (packages/markdown-codec/src/lower/lower.ts:98-99). The definitions table's own titles die with the discarded map above. - GFM task lists -- a real checked/task field on the list-membership representation. Still the degraded encoding:
applyTaskCheckboxprepends a checkbox-glyph text run to the item's first paragraph (packages/markdown-codec/src/lower/lower.ts:165-173), and state is lost entirely when the item's first block is a table or resolved image (documentedfalse-return case, same function). - Code fence info string -- the language word as an annotation on the code representation, not a dropped diagnostic. Still dropped when non-empty:
CODE_BLOCK_INFO_STRING_DROPPED(packages/markdown-codec/src/lower/lower.ts:120). - Math (
$$blocks,\(...\)inline, Parse $$ display-math blocks and \( \) inline math markdown-codec#53) --ContentFormulawith the canonical-plus-source pattern. Still preserved as literal LaTeX text, unparsed by design:lowerMathBlock(packages/markdown-codec/src/lower/lower.ts:143-145), inline via a font marker (packages/markdown-codec/src/lower/inline.ts:65). Converting LaTeX to a canonical form is a documents.js-level question (Math write path: pptx formula support, odp formula write, and deciding LaTeX-to-MathML conversion #563), not something this package alone can close. - Frontmatter, the unmapped half -- mapped keys already reach
ContentDocument.metadata; the unmapped remainder needs a package-level residue channel. Unchanged: the flatkey: valuereader only recognisestitle/author/subject/creator/date/keywordsand drops anything else viaFRONT_MATTER_KEY_UNMAPPED(packages/markdown-codec/src/lower/front-matter.ts, the keyswitchwith itsdefaultsink call). - Multi-block list item boundary -- item identity on the list-membership model. Still flattened:
ContentListMembershipcarries only numId/level, solowerListItemreportsLIST_ITEM_MULTI_BLOCK_FLATTENEDwhenever an item directly contains more than one block (packages/markdown-codec/src/lower/lower.ts:177-180), and a table directly inside an item loses membership entirely (LIST_ITEM_BLOCK_UNLISTED,packages/markdown-codec/src/lower/lower.ts:282-284). - Blockquote container / nesting depth -- a container representation in the schema tree. Still carried degraded as
indentLeftPtplus aQuotestyleId, with depth beyond level 1 approximate:lowerBlockquote(packages/markdown-codec/src/lower/lower.ts:152-154). - Raw HTML blocks (all seven kinds) and raw HTML inline -- per-node/per-run
sourceresidue channel, restorable on re-emission.document-schema.js#22's residue channel (channel 2, per its ownconstruct.tsheader comment) still hasn't shipped, so this is still blocked at the schema layer, not just unimplemented here. Current behaviour unchanged: preserved as literal text (styleIdHTMLPreformattedfor block-level), or dropped underrawHtml: 'drop'(packages/markdown-codec/src/lower/lower.ts:132-136). - Code fence info-string remainder -- pandoc-style
{.class #id}attributes quarantined beside the semantic language word. Same residue-channel blocker as raw HTML above.
Decisions still needed, carried over unresolved:
- Info-string split: the language-word/residue-remainder divide is a design proposal, not an observed distribution -- real-world prevalence of pandoc-style attribute syntax versus bare language words is unsurveyed. Measure before freezing.
- Frontmatter: the flat
key: valuereader matches the de facto convention, but how often real documents use nested shapes it silently skips is unmeasured; the residue half needs the package channel from Two-channel fidelity: harmonised semantic construct vocabulary plus a quarantined residue channel document-schema.js#22 as well. - Pandoc inline footnotes (
^[...]) have no GFM analogue -- the inventory treats the marker-plus-tail-definition pair as the scope and inline notes as out of scope; confirm or widen deliberately rather than by omission.
Original issue: ExaDev/markdown-codec#66
Activity
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 4.8.0 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 1.0.9 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 4.1.0 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 5.1.1 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 4.4.2 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 3.2.0 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 4.4.0 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 3.2.0 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 2.1.32 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 1.26.38 🎉
The release is available on GitHub release
Your semantic-release bot 📦🚀
github-actions commentedon Aug 21, 2026
🎉 This issue has been resolved in version 1.1.1 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 23, 2026
🎉 This issue has been resolved in version 1.0.0 🎉
The release is available on:
Your semantic-release bot 📦🚀
github-actions commentedon Aug 24, 2026
🎉 This issue has been resolved in version 1.2.0 🎉
The release is available on:
Your semantic-release bot 📦🚀