Markdown parsing and writing
MarkdownCodec turns stored Markdown into the editor’s blocks and spans and back. It has no UI of its own; the UI tests exercise it indirectly. Decisions: D-02, D-08, D-13.
| Behavior | Shared (MarkdownCodecTest) |
|---|---|
| Blocks parse into text and block types without Markdown syntax showing | parsesBlocksWithoutExposingSyntax |
| Writing produces canonical Markdown | serializesCanonicalMarkdown |
| Bold, italic, strikethrough, code and links survive a round trip | inlineStylesRoundTrip |
Long runs of * or _ are emphasis, not literal text | longDelimiterRunsAreEmphasisNotText |
| Literal Markdown characters typed as text are escaped | escapesLiteralMarkdownCharacters |
Text that looks like a numbered item (1.) at a paragraph start is escaped | numberedParagraphTextIsEscaped |
| Empty paragraphs between content are preserved | emptyParagraphsBetweenContentArePreserved |
| A literal non-breaking space in text is escaped | literalNbspTextIsEscaped |
| Unsupported syntax (tables, horizontal rules, HTML) is kept verbatim as raw blocks | unsupportedSyntaxIsPreservedVerbatim |
| Writing what was parsed gives the same Markdown again (fixed point) | serializationIsAFixedPoint |
| An empty document | emptyDocument |
| Task items and their checked state are derived | derivesTaskItems |
Related: search matches visible text, not syntax (NotesCoreTest.searchMatchesVisibleTextNotSyntax, see search.md); diffs compare visible text (see history.md).
Gaps
- Mermaid fences (D-13: imported, shown as code, exported unchanged) have no test of their own.
- Images and footnotes are not checked to survive a save (tables, rules and HTML are).
- Nested lists deeper than one level and numbered-list renumbering (
RichText.listNumbers) have no direct test. - Very large notes (parse and write time) are untested.