From 7d16896c34d81b98e9bdcda2ef5a9c4c7e932448 Mon Sep 17 00:00:00 2001 From: Sergey Drymchenko <2linreal@gmail.com> Date: Mon, 20 Jul 2026 19:42:21 +0300 Subject: [PATCH 1/2] T-028 markdown support docs T-026 jetbrains parser --- ARCHITECTURE.md | 56 +- .../JetBrains-Markdown-Apache-2.0.txt | 206 +++ docs/MarkdownSerialization.md | 321 ++++ editor/api/android/editor.api | 869 ++++++++++ editor/api/desktop/editor.api | 869 ++++++++++ editor/api/editor.klib.api | 1075 ++++++++++++ editor/build.gradle.kts | 2 + .../linreal/cascade/editor/core/SpanStyle.kt | 8 +- .../htmlserialization/DefaultTagDecoders.kt | 4 +- .../htmlserialization/HtmlDecodeEngine.kt | 307 ++-- .../htmlserialization/HtmlFragmentDecoder.kt | 107 ++ .../editor/htmlserialization/HtmlTokenizer.kt | 4 +- .../markdown/DefaultMarkdownBlockEncoders.kt | 168 ++ .../DefaultMarkdownEncoderFallbacks.kt | 49 + .../DefaultMarkdownListOutlineEncoder.kt | 127 ++ .../markdown/DefaultMarkdownSpanEncoders.kt | 65 + .../ExperimentalCascadeMarkdownApi.kt | 21 + .../editor/markdown/MarkdownAstDecoder.kt | 1445 +++++++++++++++++ .../editor/markdown/MarkdownCodecContracts.kt | 65 + .../editor/markdown/MarkdownCodecLimits.kt | 67 + .../editor/markdown/MarkdownDecodeEngine.kt | 78 + .../editor/markdown/MarkdownDecodeState.kt | 87 + .../markdown/MarkdownDefinitionTable.kt | 68 + .../markdown/MarkdownEncodeContextImpl.kt | 68 + .../editor/markdown/MarkdownEncodeEngine.kt | 282 ++++ .../editor/markdown/MarkdownEntities.kt | 242 +++ .../editor/markdown/MarkdownEscaping.kt | 366 +++++ .../editor/markdown/MarkdownFidelityReport.kt | 162 ++ .../editor/markdown/MarkdownHtmlBridge.kt | 258 +++ .../editor/markdown/MarkdownInlineRenderer.kt | 578 +++++++ .../editor/markdown/MarkdownPolicies.kt | 151 ++ .../editor/markdown/MarkdownProfile.kt | 342 ++++ .../markdown/MarkdownProfileSupportSet.kt | 262 +++ .../editor/markdown/MarkdownResults.kt | 152 ++ .../cascade/editor/markdown/MarkdownSchema.kt | 109 ++ .../markdown/MarkdownSerializationExt.kt | 124 ++ .../cascade/editor/markdown/MarkdownSource.kt | 167 ++ .../editor/markdown/MarkdownSourceRange.kt | 99 ++ .../editor/markdown/MarkdownWarnings.kt | 329 ++++ .../cascade/editor/richtext/LinkUrlPolicy.kt | 38 +- .../editor/serialization/RichTextSchema.kt | 9 +- .../editor/CascadeEditorBlockStringsTest.kt | 2 +- .../cascade/editor/HtmlLinkAttributesTest.kt | 30 +- .../cascade/editor/LinkUrlPolicyTest.kt | 37 + .../cascade/editor/RichTextSchemaTest.kt | 38 +- .../HtmlFragmentDecoderTest.kt | 169 ++ .../editor/markdown/MarkdownAnalyzeTest.kt | 90 + .../editor/markdown/MarkdownAstDecoderTest.kt | 42 + .../editor/markdown/MarkdownCorpusFixtures.kt | 108 ++ .../editor/markdown/MarkdownCorpusTest.kt | 55 + .../markdown/MarkdownDifferentialTest.kt | 105 ++ .../editor/markdown/MarkdownEncodeTest.kt | 231 +++ .../editor/markdown/MarkdownEntityTest.kt | 139 ++ .../editor/markdown/MarkdownEscalationTest.kt | 242 +++ .../editor/markdown/MarkdownEscapingTest.kt | 262 +++ .../editor/markdown/MarkdownFuzzTest.kt | 63 + .../editor/markdown/MarkdownHardBreakTest.kt | 100 ++ .../markdown/MarkdownHostileTextFixtures.kt | 64 + .../editor/markdown/MarkdownHtmlBridgeTest.kt | 116 ++ .../markdown/MarkdownInlineBasicsTest.kt | 263 +++ .../markdown/MarkdownInlineEncodeTest.kt | 288 ++++ .../editor/markdown/MarkdownLinkDecodeTest.kt | 222 +++ .../markdown/MarkdownListOutlineEncodeTest.kt | 159 ++ .../editor/markdown/MarkdownLoweringTest.kt | 234 +++ .../markdown/MarkdownNoThrowGuaranteeTest.kt | 58 + .../markdown/MarkdownOutOfSupportTest.kt | 61 + .../markdown/MarkdownPreservationTest.kt | 228 +++ .../editor/markdown/MarkdownProfileTest.kt | 46 + .../markdown/MarkdownReferenceCorpusTest.kt | 70 + .../markdown/MarkdownReferenceProfiles.kt | 10 + .../editor/markdown/MarkdownResultsTest.kt | 212 +++ .../editor/markdown/MarkdownRoundTripTest.kt | 41 + .../editor/markdown/MarkdownSchemaTest.kt | 92 ++ .../markdown/MarkdownSerializationExtTest.kt | 143 ++ .../editor/markdown/MarkdownSourceTest.kt | 162 ++ .../markdown/MarkdownSpanOverlapTest.kt | 232 +++ .../markdown/MarkdownStrictProfileTest.kt | 83 + .../MarkdownSupportSetBlockGenerator.kt | 219 +++ .../editor/markdown/MarkdownSupportSetTest.kt | 147 ++ .../MarkdownPerformanceBaselineTest.kt | 68 + gradle/libs.versions.toml | 2 + .../kotlin/io/github/linreal/cascade/App.kt | 6 + .../linreal/cascade/navigation/AppScreen.kt | 3 + .../linreal/cascade/screens/LandingScreen.kt | 8 + .../markdownfield/MarkdownFieldScreen.kt | 901 ++++++++++ .../markdownfield/MarkdownFieldScreenModel.kt | 168 ++ .../examples/01-personal-weekly-note.md | 22 + .../02-engineering-task-description.md | 30 + .../markdownfield/examples/03-bug-report.md | 35 + .../examples/04-meeting-notes.md | 30 + .../examples/05-release-checklist.md | 27 + .../examples/06-hard-break-daily-log.md | 14 + .../examples/07-customer-support-handoff.md | 24 + .../examples/08-product-requirements.md | 36 + .../examples/09-reference-links-research.md | 21 + .../examples/10-html-formatting-note.md | 13 + .../examples/11-pipe-table-dashboard.md | 14 + .../examples/12-code-language-design-note.md | 16 + .../examples/13-front-matter-and-image.md | 19 + .../examples/14-footnotes-and-math.md | 16 + .../examples/15-block-html-embed.md | 13 + .../examples/16-entities-and-escaping.md | 13 + .../screens/markdownfield/examples/README.md | 56 + .../cascade/navigation/AppScreenTest.kt | 2 + .../MarkdownFieldScreenModelTest.kt | 105 ++ 105 files changed, 16175 insertions(+), 156 deletions(-) create mode 100644 THIRD_PARTY_NOTICES/JetBrains-Markdown-Apache-2.0.txt create mode 100644 docs/MarkdownSerialization.md create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/htmlserialization/HtmlFragmentDecoder.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/DefaultMarkdownBlockEncoders.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/DefaultMarkdownEncoderFallbacks.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/DefaultMarkdownListOutlineEncoder.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/DefaultMarkdownSpanEncoders.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/ExperimentalCascadeMarkdownApi.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownAstDecoder.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownCodecContracts.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownCodecLimits.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownDecodeEngine.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownDecodeState.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownDefinitionTable.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEncodeContextImpl.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEncodeEngine.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEntities.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEscaping.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownFidelityReport.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownHtmlBridge.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownInlineRenderer.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownPolicies.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownProfile.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownProfileSupportSet.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownResults.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSchema.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSerializationExt.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSource.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSourceRange.kt create mode 100644 editor/src/commonMain/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownWarnings.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/htmlserialization/HtmlFragmentDecoderTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownAnalyzeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownAstDecoderTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownCorpusFixtures.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownCorpusTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownDifferentialTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEncodeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEntityTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEscalationTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownEscapingTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownFuzzTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownHardBreakTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownHostileTextFixtures.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownHtmlBridgeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownInlineBasicsTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownInlineEncodeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownLinkDecodeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownListOutlineEncodeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownLoweringTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownNoThrowGuaranteeTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownOutOfSupportTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownPreservationTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownProfileTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownReferenceCorpusTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownReferenceProfiles.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownResultsTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownRoundTripTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSchemaTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSerializationExtTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSourceTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSpanOverlapTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownStrictProfileTest.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSupportSetBlockGenerator.kt create mode 100644 editor/src/commonTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownSupportSetTest.kt create mode 100644 editor/src/desktopTest/kotlin/io/github/linreal/cascade/editor/markdown/MarkdownPerformanceBaselineTest.kt create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/MarkdownFieldScreen.kt create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/MarkdownFieldScreenModel.kt create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/01-personal-weekly-note.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/02-engineering-task-description.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/03-bug-report.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/04-meeting-notes.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/05-release-checklist.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/06-hard-break-daily-log.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/07-customer-support-handoff.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/08-product-requirements.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/09-reference-links-research.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/10-html-formatting-note.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/11-pipe-table-dashboard.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/12-code-language-design-note.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/13-front-matter-and-image.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/14-footnotes-and-math.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/15-block-html-embed.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/16-entities-and-escaping.md create mode 100644 sample/src/commonMain/kotlin/io/github/linreal/cascade/screens/markdownfield/examples/README.md create mode 100644 sample/src/commonTest/kotlin/io/github/linreal/cascade/screens/markdownfield/MarkdownFieldScreenModelTest.kt diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 2e9fb3d..f93e763 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -71,7 +71,7 @@ Block-based editor (Craft/Notion-like) for Compose Multiplatform. Unidirectional | Unknown block type | `core/UnknownBlockType.kt` | `UnknownBlockType` (implements `CustomBlockType`) | | Document serialization | `serialization/DocumentSchema.kt` | `DocumentSchema` (encode/decode full document) | | Rich text serialization | `serialization/RichTextSchema.kt` | `RichTextSchema` | -| Link URL policy | `richtext/LinkUrlPolicy.kt` | `LinkUrlPolicy`, `LinkValidationResult`, `LinkValidationError` | +| Link URL policy | `richtext/LinkUrlPolicy.kt` | `LinkUrlPolicy` (`validate` user-entry normalization, `validateStoredTarget` codec/persistence preservation), `LinkValidationResult`, `LinkValidationError` | | Link hit tester | `richtext/LinkHitTester.kt` | `LinkHitTester` (internal) | | Link state | `richtext/LinkState.kt` | `LinkState`, `LinkTarget` | | Link state calculator | `richtext/LinkStateCalculator.kt` | `LinkStateCalculator` (internal) | @@ -93,11 +93,34 @@ Block-based editor (Craft/Notion-like) for Compose Multiplatform. Unidirectional | HTML schema entry point | `htmlserialization/HtmlSchema.kt` | `HtmlSchema` (`decode` and `encode` wired through profile-driven engines) | | HTML decode limits | `htmlserialization/HtmlDecodeLimits.kt` | `HtmlDecodeLimits` (input-size bound; `loadFromHtml` / `HtmlSchema.decodeWithReport` `limits` param) | | HTML parser internals | `htmlserialization/HtmlParser.kt`, `htmlserialization/HtmlPolicyApplier.kt`, `htmlserialization/HtmlTokenizer.kt`, `htmlserialization/HtmlTreeBuilder.kt`, `htmlserialization/HtmlNode.kt`, `htmlserialization/HtmlToken.kt` | `HtmlParser.parse()` (internal), `HtmlPolicyApplier`, `HtmlNode`, `HtmlToken` | -| HTML decode engine | `htmlserialization/HtmlDecodeEngine.kt`, `htmlserialization/TagDecodeContextImpl.kt`, `htmlserialization/HtmlNodeViewMapper.kt`, `htmlserialization/DefaultTagDecoders.kt`, `htmlserialization/PreservedHtmlBlockType.kt` | `HtmlDecodeEngine` (internal; normalizes indentation + numbered lists after decode), `TagDecodeContextImpl`, default tag decoders, `PreservedHtmlBlockType`; default list-item decoders honor `class="cascade-indent-N"` as the lossless default-profile list-depth escape hatch, while default `
` plain code blocks, inline `` spans |
-| `HtmlLinkAttributesTest.kt` | Default `` URL normalization, missing/blank href warning/drop behavior, and `` highlight color decode |
+| `HtmlLinkAttributesTest.kt` | Default `` stored-target preservation (relative/fragment/mailto/tel/custom-scheme hrefs kept exactly), missing/blank href warning/drop behavior, and `` highlight color decode |
+| `htmlserialization/HtmlFragmentDecoderTest.kt` | Internal fragment entry points: inline ``/`` span decode, block fragment quote/paragraph decode, root inline runs kept, text-leaf reparser hook plumbing (invocation, span contribution, throw degradation), empty fragments |
+| `markdown/MarkdownSourceTest.kt` | Source layer: CRLF/LF/CR/mixed line maps, BOM recording and location lookup past it, final-newline state, verbatim slicing across line boundaries, first/last/empty-line and clamped location lookups |
+| `markdown/MarkdownResultsTest.kt` | Results model: Success-with-empty-payload vs Aborted-with-null-payload invariants, Fatal-warning requirement on abort, per-member impact classification, decode range / encode blockId+textRange addressing, decided default limits |
+| `markdown/MarkdownEscapingTest.kt` | Positional escaping: line-start `#`/`>`/`=`/bullets/ordered markers (incl. after embedded newlines), flanking-based `*`/`_`/`~` escaping, intraword underscores, code-span fence widening/padding, link destination angle form, link text, hostile fixture sweep |
+| `markdown/MarkdownProfileTest.kt` | Encoder/policy/support-set defaults and profile immutability |
+| `markdown/MarkdownAstDecoderTest.kt` | JetBrains adapter projection: BOM, CRLF/lone-CR normalization, original UTF-16 warning ranges, and character-exact preserved CRLF slices |
+| `markdown/MarkdownNoThrowGuaranteeTest.kt` | No-throw boundary: hostile inputs plus every decode resource limit aborts without a partial payload |
+| `markdown/MarkdownSchemaTest.kt` | Public `MarkdownSchema`: empty input/document success, canonical decode→encode, input/output-limit abort→null, CRLF output, throwing consumer encoder containment, custom support claims |
+| `markdown/MarkdownSupportSetTest.kt` | Default claim: built-in blocks/spans, empty-text/preserved/stale-numbering/invalid-outline/non-normalized-span/nested-link rejection, Highlight range, §5.12 value exclusions (trailing/leading space, tab), `\r` rejection, HardBreak merge/front-matter/empty-text claim |
+| `markdown/MarkdownRoundTripTest.kt` | 1000 generated in-support documents satisfy `decode(encode(doc)) == doc` modulo BlockIds (seed `0x5CA1AB1E`, self-adapting span palette + hostile-fragment mixing) |
+| `markdown/MarkdownOutOfSupportTest.kt` | Deterministic degraded output + warnings for out-of-set documents (empty paragraph, custom span, preserved pipe table) |
+| `markdown/MarkdownHardBreakTest.kt` | HardBreak mode: literal `\n`, blank-line→empty-paragraph runs, setext/indented-code disabled, trailing-blank round-trip, empty-text claim, 300-doc property round-trip |
+| `markdown/MarkdownAnalyzeTest.kt` | `analyze`: Native/RawFallback, preserved-count, abort→null encode, BOM/CRLF/canonical `wouldRewriteSource`, Strip-policy suppressed DataLoss, custom-support-set branch |
+| `markdown/MarkdownSerializationExtTest.kt` | Editor extensions: live-text export, hard replacement + runtime/ history clearing on success, over-limit untouched, aborted-apply rejection, non-spans span stripping, trailing-scaffold in both modes |
+| `markdown/MarkdownHtmlBridgeTest.kt` | HTML bridge: ``/`` decode+encode round-trip, inner-warning DataLoss + analyze RawFallback, empty-island preservation, unmatched-flood termination, partial overlap island |
+| `markdown/MarkdownStrictProfileTest.kt` | `withoutHtmlBridge()`: inline HTML stripped with DataLoss, analyze RawFallback, no raw HTML through any emission path (spans/verbatim/preservedHtml/`", preserveHtml)!!
+ val content = withScript.single().content
+ assertTrue(
+ content is BlockContent.Custom && content.typeId == MARKDOWN_PRESERVED_HTML_TYPE_ID,
+ "expected preserved html, got $content",
+ )
+ val encoded = MarkdownSchema.encode(withScript, strict) ?: ""
+ assertFalse(encoded.contains("