PR: #511: feat(matter): markdown serialization core + plain preset [Story-2024] by @ankitmaheshwari-com
View PR →

Files changed

6 file(s), +206 / -46 lines

Path Role + -
package.jsonConfig+1-0
pnpm-lock.yamlConfig+22-0
src/components/shared/editable-surface-preset.test.tsComponent+58-0
src/components/shared/editable-surface-preset.tsComponent+74-0
src/components/shared/editable-surface.stories.tsxComponent+21-0
src/components/shared/editable-surface.tsxComponent+30-46

Story-2024: Markdown serialization core + plain preset (substrate keystone)

This is the KEYSTONE of the editing-substrate epic (EPIC-2023). It installs markdown as the serialization substrate under EditableSurface and introduces a preset seam so later stories can turn on real formatting without touching the primitive again. Ships exactly one preset — plain — which reproduces today's behaviour with zero data migration and no visible change.

What landed

Why plain loads & saves as literal text (not via markdown)

The obvious reading — "plain just runs stored strings through setContent(md, { contentType: "markdown" }) ↔ getMarkdown()" — corrupts real data. Probing the installed library against representative counsel prose showed:

Stored valueMarkdown round-trip result
Claim is < ₹42 CrClaim is &lt; ₹42 Cr — < HTML-escaped
See <Exhibit-7> nowSee  now — <Exhibit-7> parsed as an HTML tag and dropped
# Summaryrendered as an <h1> heading — visible change
a **bold** clauserendered bold — visible change

So markdown-parsing the plain preset would break three acceptance criteria at once (literal < stays safe, zero migration, no visible change). The plain preset therefore keeps the literal text path — toContent builds a paragraph-per-line ProseMirror doc with no HTML/markdown parsing, and toValue is getText({ blockSeparator: "\n" }). A bare string round-trips as itself; a <, a leading #, and ** all render verbatim. The markdown machinery is installed for later presets, not applied to plain data. When Story-B adds light/full, it flips those two functions to the markdown path and adds a toolbar — resolvePreset is the only file that changes.

Files

Deliberately deferred (not this story)

Verification

pnpm lint (clean), pnpm build (green), and the full pnpm test suite (996 tests, incl. the new round-trip test) all pass. The PlainPresetLiteralText Storybook story demonstrates a value containing <, <Exhibit-7>, and a leading # saving byte-for-byte unchanged.