Skip to content

fix(files): collapse blank-line runs to markdown standard (no empty-paragraph explosion / reflow) - #6198

Merged
waleedlatif1 merged 1 commit into
stagingfrom
files-blank-doc-investigation
Aug 3, 2026
Merged

fix(files): collapse blank-line runs to markdown standard (no empty-paragraph explosion / reflow)#6198
waleedlatif1 merged 1 commit into
stagingfrom
files-blank-doc-investigation

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • A collaborative markdown file rendered its first section, then a huge blank scroll gap, with the rest of the content pushed ~1,959 empty lines below the fold. Root cause: @tiptap/markdown reconstructs one empty paragraph per blank line, and parseMarkdownToDoc only stripped trailing empties — so a pathological blank run (an agent/paste artifact) exploded into ~1,959 empty paragraph nodes baked into the doc.
  • Same root cause produced the reflow on open: the static preview renders empty <p></p> collapsed (invisible), but the mounted ProseMirror editor gives each a trailing-break line, so gaps appeared ~0.5s after open.
  • Fix: parseMarkdownToDoc now collapses all top-level empty paragraphs (leading, interior, trailing) to standard markdown spacing. A blank run between blocks is insignificant in CommonMark, so this makes the editor render the file the way every other renderer does (GitHub, the download, our own static preview), and neutralizes any pathological source.
  • Removed the now-vestigial EMPTY_PARAGRAPH_SPACING routing that forced blank-run docs onto the slow O(n²) whole-parse (it existed only to preserve empties we now strip) — blank runs now take the fast linear chunked path; chunked+strip == whole+strip.
  • Serializer intentionally not changed — a global blank-run collapse there would corrupt blank lines inside fenced code blocks.

Type of Change

  • Bug fix

Testing

  • Rewrote the empty-paragraph suite to the collapse contract (edges, between blocks, one/many blanks, around lists, CRLF/CR) + a "4,000-newline run → 0 empty paragraphs" regression test.
  • Verified the critical guard still holds: blank lines inside fenced code blocks are preserved (not collapsed).
  • Round-trip-safety idempotency confirmed (files stay editable, normalize on first save); no spurious dirty-on-open.
  • lint, api-validation, typecheck (sim), and 530 tests across the markdown-editor + collab-doc suites pass.
  • Not improvement(files): cache stream binding meta, tighten file cache-control, prune dead persist path #6149: an attribution experiment proved the meta-cache change is byte-identical to the old per-frame rebuild; not round-trip amplification either (idempotent).
  • Audited every LOC across correctness / regression / UX (3 subagents) + reuse / simplification / efficiency / altitude (/simplify) — all clean.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…aragraph explosion / reflow)

parseMarkdownToDoc now strips ALL top-level empty paragraphs (leading, interior, trailing),
not just trailing. A run of blank lines between blocks is insignificant in markdown
(CommonMark collapses it), but @tiptap/markdown reconstructs one empty paragraph per blank
line — which made the mounted editor render vertical gaps that exist nowhere else the file
is viewed (GitHub, download, our own static preview), let a pathological blank run explode
into thousands of empty nodes, and caused the visible reflow on open (static preview
collapses empty <p>; the live editor gives each a trailing-break line). Collapsing on parse
keeps normal one-blank-line spacing, matches every standard renderer, and stays idempotent
so the round-trip-safety probe still reaches a fixed point (files stay editable; existing
files normalize on next cold-open + save). Serializer is intentionally NOT changed — a
global blank-run collapse there would corrupt blank lines inside fenced code blocks.
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 2, 2026 10:15pm

Request Review

@cursor

cursor Bot commented Aug 2, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes core markdown parse/normalization for all collaborative files; behavior is intentional (blank-run collapse) but alters how extra blank lines in source are represented in the editor until save.

Overview
Fixes collaborative markdown files that showed a huge blank scroll gap and reflow on open when the source contained a pathological run of blank lines (e.g. agent/paste artifacts). @tiptap/markdown used to create one empty paragraph per blank line, and parsing only stripped trailing empties—so thousands of empty nodes could bake into the doc and reflow after the static preview mounted.

parseMarkdownToDoc now removes all top-level empty paragraphs (leading, interior, trailing) via stripEmptyParagraphs, aligning editor rendering with CommonMark and other renderers while keeping serialize→parse idempotent so files stay editable.

The EMPTY_PARAGRAPH_SPACING guard that forced blank-run documents onto the slow whole-document parse is removed; those docs use the fast chunked path because chunked parse + strip matches whole parse + strip.

postProcessSerializedMarkdown is unchanged on purpose—global blank collapse there would corrupt significant blank lines inside fenced code. Comments now document that interior blank runs are normalized on parse instead.

Tests are rewritten around the collapse contract (including a 4,000-newline regression) rather than chunked-vs-whole empty-paragraph parity.

Reviewed by Cursor Bugbot for commit e28623b. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR normalizes markdown parsing by removing all top-level empty paragraphs and allows blank-line-heavy documents to use the chunked parser, preventing pathological empty-node expansion and editor reflow.

  • Replaces trailing-only empty-paragraph cleanup with top-level empty-paragraph filtering.
  • Removes blank-line runs from the conditions that force whole-document parsing.
  • Updates parser, idempotency, line-ending, list-boundary, and pathological-run regression tests.
  • Documents why serializer-level global blank-line collapsing remains unsafe for fenced code and verbatim snippets.

Confidence Score: 5/5

The PR appears safe to merge, with parsing, serialization, dirty-state, and collaboration paths converging on the same idempotent blank-line normalization.

The changed filter targets only structurally empty top-level paragraphs, context-sensitive markdown constructs retain dedicated handling, and the normalized editor and persistence paths remain consistent.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/markdown-parse.ts Collapses top-level parser-generated empty paragraphs and routes blank-run documents through the chunked parser while retaining whole-document handling for context-sensitive constructs.
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/markdown-parse.test.ts Replaces empty-paragraph preservation assertions with normalization, idempotency, line-ending, list-boundary, and 4,000-newline regression coverage.
apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/markdown-fidelity.ts Clarifies that interior blank-run cleanup occurs during parsing rather than serialization to preserve whitespace inside fenced and verbatim content.

Reviews (1): Last reviewed commit: "fix(files): collapse blank-line runs to ..." | Re-trigger Greptile

@waleedlatif1
waleedlatif1 merged commit 5460133 into staging Aug 3, 2026
27 checks passed
@waleedlatif1
waleedlatif1 deleted the files-blank-doc-investigation branch August 3, 2026 01:11
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.

1 participant