Skip to content

fix(markdown): escape leading block syntax when serializing paragraphs - #8140

Open
lazerg wants to merge 2 commits into
ueberdosis:mainfrom
lazerg:fix/issue-8134-escaped-block-serialization
Open

fix(markdown): escape leading block syntax when serializing paragraphs#8140
lazerg wants to merge 2 commits into
ueberdosis:mainfrom
lazerg:fix/issue-8134-escaped-block-serialization

Conversation

@lazerg

@lazerg lazerg commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Fixes

Fixes #8134

Changes and Review

The serializer already escaped inline markdown, but not block markers at the start of a line. So a paragraph holding # not a heading was written back without its backslash and re-parsed as a real heading (same for -, +, ordered-list numbers and ---). Serializing now escapes a leading block marker on the first line of a top-level paragraph, so escaped block syntax stays a paragraph across a parse → serialize → parse round-trip. To check, parse \# not a heading, extract the markdown, and parse it again, or run the new round-trip tests in conversion.spec.ts.

Checklist

  • I have added a changeset if necessary.
  • I have added tests if possible.
  • I have made sure to test my changes myself.

Responsibility

  • I have reviewed and understand these changes, and I take responsibility for this PR, even if an AI agent created it.

@lazerg
lazerg requested a review from a team as a code owner July 29, 2026 04:10
@netlify

netlify Bot commented Jul 29, 2026

Copy link
Copy Markdown

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit d39dd40
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/6a69832dd7c2e300084ba3cf
😎 Deploy Preview https://deploy-preview-8140--tiptap-embed.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@changeset-bot

changeset-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d39dd40

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 74 packages
Name Type
@tiptap/markdown Patch
@tiptap/core Patch
@tiptap/extension-audio Patch
@tiptap/extension-blockquote Patch
@tiptap/extension-bold Patch
@tiptap/extension-bubble-menu Patch
@tiptap/extension-bullet-list Patch
@tiptap/extension-code-block-lowlight Patch
@tiptap/extension-code-block Patch
@tiptap/extension-code Patch
@tiptap/extension-collaboration-caret Patch
@tiptap/extension-collaboration Patch
@tiptap/extension-color Patch
@tiptap/extension-details Patch
@tiptap/extension-document Patch
@tiptap/extension-drag-handle-react Patch
@tiptap/extension-drag-handle-vue-2 Patch
@tiptap/extension-drag-handle-vue-3 Patch
@tiptap/extension-drag-handle Patch
@tiptap/extension-emoji Patch
@tiptap/extension-file-handler Patch
@tiptap/extension-find-and-replace Patch
@tiptap/extension-floating-menu Patch
@tiptap/extension-font-family Patch
@tiptap/extension-hard-break Patch
@tiptap/extension-heading Patch
@tiptap/extension-highlight Patch
@tiptap/extension-horizontal-rule Patch
@tiptap/extension-image Patch
@tiptap/extension-invisible-characters Patch
@tiptap/extension-italic Patch
@tiptap/extension-link Patch
@tiptap/extension-list Patch
@tiptap/extension-mathematics Patch
@tiptap/extension-mention Patch
@tiptap/extension-node-range Patch
@tiptap/extension-ordered-list Patch
@tiptap/extension-paragraph Patch
@tiptap/extension-ruby-text Patch
@tiptap/extension-strike Patch
@tiptap/extension-subscript Patch
@tiptap/extension-superscript Patch
@tiptap/extension-table-of-contents Patch
@tiptap/extension-table Patch
@tiptap/extension-text-align Patch
@tiptap/extension-text-style Patch
@tiptap/extension-text Patch
@tiptap/extension-twitch Patch
@tiptap/extension-typography Patch
@tiptap/extension-underline Patch
@tiptap/extension-unique-id Patch
@tiptap/extension-youtube Patch
@tiptap/extensions Patch
@tiptap/html Patch
@tiptap/pm Patch
@tiptap/react Patch
@tiptap/starter-kit Patch
@tiptap/static-renderer Patch
@tiptap/suggestion Patch
@tiptap/vue-2 Patch
@tiptap/vue-3 Patch
@tiptap/extension-character-count Patch
@tiptap/extension-dropcursor Patch
@tiptap/extension-focus Patch
@tiptap/extension-gapcursor Patch
@tiptap/extension-history Patch
@tiptap/extension-list-item Patch
@tiptap/extension-list-keymap Patch
@tiptap/extension-placeholder Patch
@tiptap/extension-table-cell Patch
@tiptap/extension-table-header Patch
@tiptap/extension-table-row Patch
@tiptap/extension-task-item Patch
@tiptap/extension-task-list Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: dc314961-70d0-470e-9a1b-314ee230ca77

📥 Commits

Reviewing files that changed from the base of the PR and between 9edad85 and d39dd40.

📒 Files selected for processing (2)
  • packages/markdown/__tests__/conversion.spec.ts
  • packages/markdown/src/MarkdownManager.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/markdown/tests/conversion.spec.ts
  • packages/markdown/src/MarkdownManager.ts

📝 Walkthrough

Summary

  • Fixes Markdown serialization so escaped block markers (like \#, \-, ordered list prefixes, and ---) are properly escaped when they appear at the start of a line inside a paragraph.
  • Prevents parse → serialize → parse round-trips from turning those paragraphs into headings, list items, or thematic breaks.
  • Updates MarkdownManager to detect “line start” while serializing inline text and applies escapeBlockSyntax at that boundary.
  • Adds round-trip and edge-case tests in packages/markdown/__tests__/conversion.spec.ts (headings, bullets, ordered lists, thematic breaks/Setext, and table pipe lines), plus checks that mid-line markers are not escaped.
  • Adds a patch changeset for @tiptap/markdown describing the behavior change.

Walkthrough

Markdown serialization now preserves escaped block syntax at paragraph line starts, preventing headings and lists from being created during parse–serialize–parse round-trips. Tests cover heading, list, ordered-list, and thematic-break markers, with a patch changeset added.

Changes

Markdown escape round-trip

Layer / File(s) Summary
Escape block syntax during serialization
packages/markdown/src/MarkdownManager.ts
Line-start context is passed into Markdown text encoding so block-leading markers are escaped when serializing paragraph text.
Validate escaped Markdown round-trips
packages/markdown/__tests__/conversion.spec.ts, .changeset/markdown-escape-block-syntax.md
Tests cover escaping rules and confirm escaped markers remain paragraphs after parsing; a patch changeset documents the behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Paragraph
  participant MarkdownManager
  participant MarkdownParser
  Paragraph->>MarkdownManager: serialize leading block marker text
  MarkdownManager->>MarkdownManager: escape marker with line-start context
  MarkdownManager-->>MarkdownParser: emit escaped Markdown
  MarkdownParser-->>Paragraph: parse text as paragraph
Loading

Suggested labels: area: markdown, complexity: medium, impact: medium

Suggested reviewers: bdbch

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: escaping leading block syntax during Markdown serialization.
Description check ✅ Passed The description matches the template and covers fixes, changes, verification, checklist, and responsibility.
Linked Issues check ✅ Passed The code and tests address #8134 by preserving escaped block syntax through parse → serialize → parse round-trips.
Out of Scope Changes check ✅ Passed The changes stay within scope: serializer logic, tests, and a changeset entry for the same Markdown bug fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added area: markdown Markdown parsing and serialization complexity: medium Moderate change, possibly multiple files impact: medium Affects some users or workflows labels Jul 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/markdown/__tests__/conversion.spec.ts (1)

782-817: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Expand the round-trip test matrix.

Please add cases for Title\n\\---, Title\n\\===, escaped GFM table rows, indented markers such as \\# text, and a thematic-break round-trip. These are explicitly part of the PR objective and are not covered by the current tests.

As per coding guidelines, deterministic user-visible behavior should be covered by unit tests.

Also applies to: 819-831

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/markdown/__tests__/conversion.spec.ts` around lines 782 - 817,
Expand the serialization round-trip tests around the existing leading block
syntax cases in the conversion test suite. Add deterministic cases covering
“Title” followed by escaped thematic breaks using \--- and \===, escaped GFM
table rows, indented escaped markers such as “  \# text”, and a thematic-break
round-trip; assert each expected serialized result and preserve the existing
paragraph helper and test style.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/markdown/src/MarkdownManager.ts`:
- Around line 1128-1143: Update escapeBlockSyntax() to process the beginning of
every line in text, not only the overall string start, while allowing up to
three leading spaces. Escape ATX headings, unordered and multi-digit
ordered-list markers, thematic breaks, Setext heading underlines, and table rows
so inputs such as Title followed by --- or lines beginning with | cannot become
block syntax when reparsed.

---

Nitpick comments:
In `@packages/markdown/__tests__/conversion.spec.ts`:
- Around line 782-817: Expand the serialization round-trip tests around the
existing leading block syntax cases in the conversion test suite. Add
deterministic cases covering “Title” followed by escaped thematic breaks using
\--- and \===, escaped GFM table rows, indented escaped markers such as “  \#
text”, and a thematic-break round-trip; assert each expected serialized result
and preserve the existing paragraph helper and test style.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3fb60ee0-3a46-4001-95a7-0d6d21298a74

📥 Commits

Reviewing files that changed from the base of the PR and between 5158212 and 9edad85.

📒 Files selected for processing (3)
  • .changeset/markdown-escape-block-syntax.md
  • packages/markdown/__tests__/conversion.spec.ts
  • packages/markdown/src/MarkdownManager.ts

Comment thread packages/markdown/src/MarkdownManager.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: markdown Markdown parsing and serialization complexity: medium Moderate change, possibly multiple files impact: medium Affects some users or workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Markdown serialization does not preserve escaped blocks after round-trip

1 participant