Skip to content

fix(muya): preserve fenced code block info string on round-trip (#4770)#4846

Merged
Jocs merged 1 commit into
developfrom
fix/code-fence-info-string-4770
Jul 4, 2026
Merged

fix(muya): preserve fenced code block info string on round-trip (#4770)#4846
Jocs merged 1 commit into
developfrom
fix/code-fence-info-string-4770

Conversation

@Jocs

@Jocs Jocs commented Jul 4, 2026

Copy link
Copy Markdown
Member

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 for meta.lang, which drives syntax highlighting:

const lang = (infoString || '').match(/\S*/)?.[0] ?? ''

The serializer then emitted only meta.lang, so everything after the first space was lost on save.

meta.lang must stay a single word — the code-block content renderer does wrapper.classList.add(\language-${lang}`), and a langcontaining spaces would breakclassList.add. So widening lang` 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 / the language-* class / diagram detection — unchanged.
  • meta.info (full string) makes the fence round-trip losslessly.
  • Serialization uses meta.info only while lang is still its first word, so editing the language (which rewrites lang) correctly drops the now-stale attributes rather than re-emitting them.

Plain single-word languages and language-less fences produce no meta.info and are byte-identical to before.

Tests

New codeFenceInfoString.spec.ts (markdown → state → markdown round-trip):

  • preserves ```{example, listing1-name}
  • preserves ```js title="app.js"
  • plain ```js and language-less ``` unchanged (no regression)
  • an edited language wins over a now-stale stored info string

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

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>
@Jocs Jocs force-pushed the fix/code-fence-info-string-4770 branch from 9bb602c to 9912028 Compare July 4, 2026 13:40
@Jocs Jocs merged commit 5f54c09 into develop Jul 4, 2026
7 checks passed
@Jocs Jocs deleted the fix/code-fence-info-string-4770 branch July 4, 2026 13:54
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] Marktext removes attributes from code block

1 participant