fix(markdown): stable round-trip for tables, captions, and audio#2720
fix(markdown): stable round-trip for tables, captions, and audio#2720nperez0111 merged 4 commits intomainfrom
Conversation
- Headerless tables no longer grow an empty row each save (#739): emit no `<thead>` when every header cell is blank. - Image/video captions now round-trip via raw `<figure>`+`<figcaption>` HTML so the `caption` prop is preserved (and not duplicated as a stray paragraph below the image). The descriptor (alt / data-name) is dropped when it would duplicate the caption text. - Audio blocks serialize to raw `<audio>` HTML instead of `[](url)` link syntax, so they round-trip back into an audio block instead of being lost as a link. - Markdown video parser routes alt text into `data-name` and `parseVideoElement` reads it back, mirroring image alt → name. - `audio` added to HTML block-tag set so a standalone `<audio>` line is recognized as a block. - Adds round-trip snapshot tests covering all default blocks (`markdown/defaultBlocks`), tables with header rows (`markdown/tableWithHeaderRow`), and the no-name/no-caption image case (`image/urlOnly`).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAudio now serializes as real ChangesMedia and Figure Serialization Round-Trip
Sequence Diagram(s)sequenceDiagram
participant Exporter
participant Parser
participant VideoBlock
participant Tests
Exporter->>Exporter: detect media blocks
Exporter->>Exporter: serialize audio as raw HTML (escape attrs)
Exporter->>Exporter: serialize figure or shorthand based on caption and media
Exporter->>Tests: emit Markdown/HTML output
Tests->>Parser: feed emitted Markdown/HTML
Parser->>Parser: treat audio as raw HTML block
Parser->>VideoBlock: parse data-name into video block object
Parser->>Tests: return reconstructed blocks for assertions
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)when header cells are blank, preventing empty headers from being parsed as real rows, achieving stable round-trips for headerless tables.
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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
`@tests/src/unit/core/formatConversion/exportParseEquality/exportParseEqualityTestInstances.ts`:
- Around line 958-963: The test comment for the testCase named
"markdown/defaultBlocks" wrongly states that captions are dropped during
markdown round-trip; update the comment to remove "captions" from the list of
dropped features and instead note that captioned image/video/audio blocks now
survive the round-trip as raw <figure> HTML (or otherwise record that captions
are preserved as HTML). Edit the block comment above the testCase definition to
reflect this corrected behavior so the snapshot description matches current
functionality.
- Around line 715-740: The comment above the testCase is misleading: it states
"a table with no header row" but the testCase named
"markdown/tableWithHeaderRow" and the table content include headerRows: 1 and a
header row; update the comment to reflect that this is testing a table with a
header row (or alternatively change headerRows to 0 and remove header cells if
you intend a headerless test). Locate the testCase object (testCase.name
"markdown/tableWithHeaderRow", the table content with headerRows: 1) and either
correct the comment to describe a headered table round-trip or modify
headerRows/cells to create a truly headerless case to match the original issue.
🪄 Autofix (Beta)
❌ Autofix failed (check again to retry)
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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c2708b53-b872-47ef-a473-77f14590f68d
⛔ Files ignored due to path filters (16)
tests/src/unit/core/formatConversion/export/__snapshots__/blocknoteHTML/image/urlOnly.htmlis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/html/image/urlOnly.htmlis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/audio/basic.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/audio/noName.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/image/basic.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/image/nested.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/image/noName.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/image/urlOnly.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/image/withCaption.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/markdown/video/withCaption.mdis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/export/__snapshots__/nodes/image/urlOnly.jsonis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/exportParseEquality/__snapshots__/markdown/markdown/defaultBlocks.jsonis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/exportParseEquality/__snapshots__/markdown/markdown/table.jsonis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/exportParseEquality/__snapshots__/markdown/markdown/tableWithHeaderRow.jsonis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/exportParseEquality/__snapshots__/markdown/markdown/video.jsonis excluded by!**/__snapshots__/**tests/src/unit/core/formatConversion/parse/__snapshots__/markdown/video.jsonis excluded by!**/__snapshots__/**
📒 Files selected for processing (5)
packages/core/src/api/exporters/markdown/htmlToMarkdown.tspackages/core/src/api/parsers/markdown/markdownToHtml.tspackages/core/src/blocks/Video/parseVideoElement.tstests/src/unit/core/formatConversion/export/exportTestInstances.tstests/src/unit/core/formatConversion/exportParseEquality/exportParseEqualityTestInstances.ts
The image-with-caption case now serializes to raw `<figure>` HTML and parses back with `caption: "Caption"` preserved (previously the caption was lost into a stray paragraph block).
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/mantine
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-docx-exporter
@blocknote/xl-email-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
commit: |
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. ❌ Failed to clone repository into sandbox. Please try again. |
…y/exportParseEqualityTestInstances.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…ival Captions on image/video/audio now survive round-trip via raw `<figure>` HTML — they shouldn't have been listed as a dropped feature.
Summary
Fixes #739.
Fixes several markdown round-trip issues so that exporting BlockNote blocks to markdown and parsing them back produces a stable result.
Rationale
captionprop ended up inname.[](url)and parsed back as a plain link, losing the block entirely.Changes
markdownToHtml.ts: when every header cell is blank, emit<tbody>-only (no<thead>), so a markdown table with an empty header parses as a headerless table.htmlToMarkdown.ts: image/video with a caption serialize to raw<figure><img|video><figcaption>...</figcaption></figure>HTML, so the caption survives the round-trip via BlockNote's existing figure parser. The descriptor (alt/data-name) is dropped when it would duplicate the caption text. Image/video without a caption keep the prettierform.htmlToMarkdown.ts: audio always serializes to raw<audio>HTML (with<figure>wrapping when captioned).markdownToHtml.ts: video URLs inroute alt →data-name.audioadded to the HTML block-tag set.parseVideoElement.ts: readdata-nameintoname, mirroringparseImageElementreadingalt.markdown/defaultBlocks(covers every default block type),markdown/tableWithHeaderRow, and a newimage/urlOnlyexport case to lock in that figure-wrapping is only used when needed.markdown/tablesnapshot is regenerated — the old snapshot encoded the bug (3 rows +headerRows: 1from a 2-row input).Impact
Markdown export output changes for media blocks:
<figure>HTML rather thanplus a caption paragraph.<audio>HTML rather than[](url)link syntax.The pretty
markdown is preserved for the simple no-caption case.Testing
All existing tests pass plus the new snapshots. 651/651 conversion tests, 844/844 in
tests/, 422 + 3 skipped inpackages/core.Checklist
Summary by CodeRabbit
Bug Fixes
Tests