Skip to content

fix(muya): preserve code fence length on serialize - #4755

Merged
Jocs merged 1 commit into
developfrom
fix/1841-code-fence-length
Jun 27, 2026
Merged

Jocs merged 1 commit into
developfrom
fix/1841-code-fence-length

Conversation

@Jocs

@Jocs Jocs commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary

A fenced code block written with more than three backticks — which is required when the block's own content contains a line — was always re-serialized (`getMarkdown` / source-mode toggle) with exactly three backticks. The inner then closed the block early and the saved markdown was corrupt.

Root cause: ICodeBlockState.meta had no fence-length field, markdownToState never captured it, and stateToMarkdown._serializeCodeBlock hard-coded ```.

Fix:

  • capture the opening fence length on parse from the token's raw text, stored in meta.fenceLength only when it exceeds the default 3 (ordinary blocks keep their existing state shape)
  • serialize a fence of max(3, stored, longestAllBacktickLineInBody + 1), so the output is both faithful to the original length and always long enough to be valid

Verification

Unit test src/state/__tests__/codeFenceLength.spec.ts, RED→GREEN:

  • a 4-backtick block wrapping a ``` line keeps a ≥4 fence and round-trips without corruption
  • byte-stable round trip
  • ordinary 3-backtick blocks are unchanged

Full state suite + CommonMark/GFM conformance lock unaffected (2 unrelated parityExportHtml failures are a pre-existing worktree ?inline-CSS fs-deny, fail on clean develop too, pass in CI).

Fixes #1841

A fenced code block written with more than three backticks (required when
the block body itself contains a ``` line) was always re-serialized with
exactly three backticks, so the inner fence closed the block early and the
saved markdown was corrupt. Capture the opening fence length on parse
(stored in meta only when it exceeds the default 3) and emit a fence long
enough for both the original length and any all-backtick line in the body.

Fixes #1841

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@Jocs
Jocs merged commit 45775ce into develop Jun 27, 2026
7 checks passed
hisaboh added a commit to hisaboh/remarks that referenced this pull request Jun 27, 2026
upstream が持ち込んだ主なもの:
- list serialization 刷新(空項目保持 marktext#4696/marktext#4697、markerOverride/_isLooseParentList)
- code fence 長の保持 marktext#4755、ソースモード undo/redo、math/diagram スクロール
- flush()/_flushOperationCache() による pending-edit 同期 marktext#2938
- plain-inline-spaces 保持の paste marktext#4706、大規模依存アップグレード marktext#4597 ほか

採用/保持の判断:
- フォーク保持: CLAUDE.md、setWrapCodeBlocks、PDF 描画
- 両立: fence info(フォーク) + fenceLength(upstream)、whole-line paste(フォーク) +
  plain-inline-spaces(upstream)、@tauri-apps/cli 保持 + upstream バージョンアップ採用
- upstream 採用: flush 機構(フォークの flushPendingChanges / _commitOperationCache /
  _rafHandle / _isGoing を除去、呼び出し側 editor.vue を flush() に更新)

波及修正:
- フォークの空 paragraph 往復保持を top-level (_listType 空) に限定し、upstream の
  空リスト項目処理と両立(muya unit 10件の回帰を解消)
- pnpm-lock.yaml をマージ後 package.json から再生成

検証(全緑): muya lint:types / check-circular / unit 1397 / conformance 1347、
desktop typecheck / unit 695、build:tauri 成功・実機動作確認 OK

Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.

Length of code block's fences is not kept

1 participant