fix(muya): preserve fenced code block info string on round-trip (#4770)#4846
Merged
Conversation
A fenced code block's info string was reduced to its first word on save:
only `meta.lang` (used for syntax highlighting) was kept, and the
serializer emitted just that word. So ```` ```{example, listing1-name} ````
was rewritten to ```` ```{example, ```` — and ```` ```js title="app.js" ````
lost its attributes — the moment the document was saved.
`meta.lang` must stay a single word: the code-block content adds a
`language-${lang}` class and a lang with spaces would break
`classList.add`. So preserve the full info string additively in a new
optional `meta.info`, set at parse time when the info string carries more
than the language word, and emit it on serialize. The language word still
drives highlighting; the fence now round-trips losslessly.
Serialization only trusts `meta.info` while `lang` is still its first
word, so editing the language (which rewrites `lang`) correctly drops the
stale attributes instead of re-emitting them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9bb602c to
9912028
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #4770. A fenced code block's info string was truncated to its first word when the document was saved:
```{example, listing1-name}→```{example,(a Pandoc/RMarkdown attribute block)```js title="app.js"→```js(a language followed by attributes)Root cause
At parse time (
markdownToState._buildCodeState) the info string is reduced to its first word formeta.lang, which drives syntax highlighting:The serializer then emitted only
meta.lang, so everything after the first space was lost on save.meta.langmust stay a single word — the code-block content renderer doeswrapper.classList.add(\language-${lang}`), and alangcontaining spaces would breakclassList.add. So wideninglang` to the full info string is not an option.Fix
Preserve the full info string additively in a new optional
meta.info, set at parse time only when the info string carries more than the language word, and emit it on serialize:meta.lang(first word) still drives highlighting / thelanguage-*class / diagram detection — unchanged.meta.info(full string) makes the fence round-trip losslessly.meta.infoonly whilelangis still its first word, so editing the language (which rewriteslang) correctly drops the now-stale attributes rather than re-emitting them.Plain single-word languages and language-less fences produce no
meta.infoand are byte-identical to before.Tests
New
codeFenceInfoString.spec.ts(markdown → state → markdown round-trip):```{example, listing1-name}```js title="app.js"```jsand language-less```unchanged (no regression)RED before the fix (both info-string cases truncated), GREEN after. Full muya unit suite (1389), CommonMark/GFM spec conformance (1347), and typecheck all pass.
🤖 Generated with Claude Code