@latentic/live-markdown 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +2 -2
- package/dist/chunk-V6TY7KAL.js +8 -0
- package/dist/chunk-V6TY7KAL.js.map +1 -0
- package/dist/codemirror/CodeMirrorMarkdownEditor.d.ts +106 -0
- package/dist/codemirror/CodeMirrorMarkdownEditor.js +482 -0
- package/dist/codemirror/CodeMirrorMarkdownEditor.js.map +1 -0
- package/dist/codemirror/byteOffset.d.ts +17 -0
- package/dist/codemirror/byteOffset.js +19 -0
- package/dist/codemirror/byteOffset.js.map +1 -0
- package/dist/codemirror/caretLayer.d.ts +19 -0
- package/dist/codemirror/caretLayer.js +44 -0
- package/dist/codemirror/caretLayer.js.map +1 -0
- package/dist/codemirror/clipboard/copyRich.d.ts +37 -0
- package/dist/codemirror/clipboard/copyRich.js +72 -0
- package/dist/codemirror/clipboard/copyRich.js.map +1 -0
- package/dist/codemirror/clipboard/htmlToMarkdown.d.ts +20 -0
- package/dist/codemirror/clipboard/htmlToMarkdown.js +91 -0
- package/dist/codemirror/clipboard/htmlToMarkdown.js.map +1 -0
- package/dist/codemirror/clipboard/pasteMarkdown.d.ts +18 -0
- package/dist/codemirror/clipboard/pasteMarkdown.js +41 -0
- package/dist/codemirror/clipboard/pasteMarkdown.js.map +1 -0
- package/dist/codemirror/code/codeHighlight.d.ts +13 -0
- package/dist/codemirror/code/codeHighlight.js +15 -0
- package/dist/codemirror/code/codeHighlight.js.map +1 -0
- package/dist/codemirror/code/codeLangAffordance.d.ts +17 -0
- package/dist/codemirror/code/codeLangAffordance.js +80 -0
- package/dist/codemirror/code/codeLangAffordance.js.map +1 -0
- package/dist/codemirror/code/codeLanguageMenu.d.ts +40 -0
- package/dist/codemirror/code/codeLanguageMenu.js +184 -0
- package/dist/codemirror/code/codeLanguageMenu.js.map +1 -0
- package/dist/codemirror/code/codePalette.d.ts +39 -0
- package/dist/codemirror/code/codePalette.js +53 -0
- package/dist/codemirror/code/codePalette.js.map +1 -0
- package/dist/codemirror/code/fenceAutoClose.d.ts +30 -0
- package/dist/codemirror/code/fenceAutoClose.js +171 -0
- package/dist/codemirror/code/fenceAutoClose.js.map +1 -0
- package/dist/codemirror/code/fenceCaretGuard.d.ts +28 -0
- package/dist/codemirror/code/fenceCaretGuard.js +66 -0
- package/dist/codemirror/code/fenceCaretGuard.js.map +1 -0
- package/dist/codemirror/code/fenceDeleteGuards.d.ts +22 -0
- package/dist/codemirror/code/fenceDeleteGuards.js +105 -0
- package/dist/codemirror/code/fenceDeleteGuards.js.map +1 -0
- package/dist/codemirror/code/fenceTabIndent.d.ts +8 -0
- package/dist/codemirror/code/fenceTabIndent.js +50 -0
- package/dist/codemirror/code/fenceTabIndent.js.map +1 -0
- package/dist/codemirror/code/highlightFence.d.ts +25 -0
- package/dist/codemirror/code/highlightFence.js +45 -0
- package/dist/codemirror/code/highlightFence.js.map +1 -0
- package/dist/codemirror/code/index.d.ts +9 -0
- package/dist/codemirror/code/index.js +8 -0
- package/dist/codemirror/code/index.js.map +1 -0
- package/dist/codemirror/core/codeContext.d.ts +32 -0
- package/dist/codemirror/core/codeContext.js +22 -0
- package/dist/codemirror/core/codeContext.js.map +1 -0
- package/dist/codemirror/core/editorTestHarness.d.ts +31 -0
- package/dist/codemirror/core/editorTestHarness.js +69 -0
- package/dist/codemirror/core/editorTestHarness.js.map +1 -0
- package/dist/codemirror/core/editorTheme.d.ts +39 -0
- package/dist/codemirror/core/editorTheme.js +498 -0
- package/dist/codemirror/core/editorTheme.js.map +1 -0
- package/dist/codemirror/core/hostFacets.d.ts +58 -0
- package/dist/codemirror/core/hostFacets.js +27 -0
- package/dist/codemirror/core/hostFacets.js.map +1 -0
- package/dist/codemirror/core/hrWidget.d.ts +22 -0
- package/dist/codemirror/core/hrWidget.js +22 -0
- package/dist/codemirror/core/hrWidget.js.map +1 -0
- package/dist/codemirror/core/htmlEscape.d.ts +6 -0
- package/dist/codemirror/core/htmlEscape.js +12 -0
- package/dist/codemirror/core/htmlEscape.js.map +1 -0
- package/dist/codemirror/core/index.d.ts +13 -0
- package/dist/codemirror/core/index.js +9 -0
- package/dist/codemirror/core/index.js.map +1 -0
- package/dist/codemirror/core/inlineScan.d.ts +49 -0
- package/dist/codemirror/core/inlineScan.js +31 -0
- package/dist/codemirror/core/inlineScan.js.map +1 -0
- package/dist/codemirror/core/lineStructure.d.ts +47 -0
- package/dist/codemirror/core/lineStructure.js +64 -0
- package/dist/codemirror/core/lineStructure.js.map +1 -0
- package/dist/codemirror/core/linkResolution.d.ts +36 -0
- package/dist/codemirror/core/linkResolution.js +58 -0
- package/dist/codemirror/core/linkResolution.js.map +1 -0
- package/dist/codemirror/core/paint.d.ts +118 -0
- package/dist/codemirror/core/paint.js +42 -0
- package/dist/codemirror/core/paint.js.map +1 -0
- package/dist/codemirror/core/parseToEnd.d.ts +24 -0
- package/dist/codemirror/core/parseToEnd.js +38 -0
- package/dist/codemirror/core/parseToEnd.js.map +1 -0
- package/dist/codemirror/core/plugin.d.ts +32 -0
- package/dist/codemirror/core/plugin.js +161 -0
- package/dist/codemirror/core/plugin.js.map +1 -0
- package/dist/codemirror/core/registry.d.ts +38 -0
- package/dist/codemirror/core/registry.js +133 -0
- package/dist/codemirror/core/registry.js.map +1 -0
- package/dist/codemirror/core/testKeys.d.ts +17 -0
- package/dist/codemirror/core/testKeys.js +11 -0
- package/dist/codemirror/core/testKeys.js.map +1 -0
- package/dist/codemirror/core/treeAt.d.ts +31 -0
- package/dist/codemirror/core/treeAt.js +10 -0
- package/dist/codemirror/core/treeAt.js.map +1 -0
- package/dist/codemirror/extensions/footnoteExtension.d.ts +9 -0
- package/dist/codemirror/extensions/footnoteExtension.js +14 -0
- package/dist/codemirror/extensions/footnoteExtension.js.map +1 -0
- package/dist/codemirror/extensions/highlightExtension.d.ts +9 -0
- package/dist/codemirror/extensions/highlightExtension.js +14 -0
- package/dist/codemirror/extensions/highlightExtension.js.map +1 -0
- package/dist/codemirror/extensions/index.d.ts +12 -0
- package/dist/codemirror/extensions/index.js +19 -0
- package/dist/codemirror/extensions/index.js.map +1 -0
- package/dist/codemirror/extensions/loader.d.ts +24 -0
- package/dist/codemirror/extensions/loader.js +33 -0
- package/dist/codemirror/extensions/loader.js.map +1 -0
- package/dist/codemirror/extensions/mathExtension.d.ts +9 -0
- package/dist/codemirror/extensions/mathExtension.js +14 -0
- package/dist/codemirror/extensions/mathExtension.js.map +1 -0
- package/dist/codemirror/extensions/mermaidExtension.d.ts +9 -0
- package/dist/codemirror/extensions/mermaidExtension.js +12 -0
- package/dist/codemirror/extensions/mermaidExtension.js.map +1 -0
- package/dist/codemirror/extensions/tableExtension.d.ts +13 -0
- package/dist/codemirror/extensions/tableExtension.js +39 -0
- package/dist/codemirror/extensions/tableExtension.js.map +1 -0
- package/dist/codemirror/extensions/types.d.ts +39 -0
- package/dist/codemirror/extensions/types.js +1 -0
- package/dist/codemirror/extensions/types.js.map +1 -0
- package/dist/codemirror/extensions/wikilinkExtension.d.ts +9 -0
- package/dist/codemirror/extensions/wikilinkExtension.js +14 -0
- package/dist/codemirror/extensions/wikilinkExtension.js.map +1 -0
- package/dist/codemirror/features/blockCommandSteps.d.ts +20 -0
- package/dist/codemirror/features/blockCommandSteps.js +83 -0
- package/dist/codemirror/features/blockCommandSteps.js.map +1 -0
- package/dist/codemirror/footnote/footnotePlugin.d.ts +10 -0
- package/dist/codemirror/footnote/footnotePlugin.js +78 -0
- package/dist/codemirror/footnote/footnotePlugin.js.map +1 -0
- package/dist/codemirror/footnote/footnoteScanRule.d.ts +9 -0
- package/dist/codemirror/footnote/footnoteScanRule.js +12 -0
- package/dist/codemirror/footnote/footnoteScanRule.js.map +1 -0
- package/dist/codemirror/footnote/index.d.ts +2 -0
- package/dist/codemirror/footnote/index.js +2 -0
- package/dist/codemirror/footnote/index.js.map +1 -0
- package/dist/codemirror/format/blockCommands.d.ts +17 -0
- package/dist/codemirror/format/blockCommands.js +176 -0
- package/dist/codemirror/format/blockCommands.js.map +1 -0
- package/dist/codemirror/format/formatCommands.d.ts +11 -0
- package/dist/codemirror/format/formatCommands.js +132 -0
- package/dist/codemirror/format/formatCommands.js.map +1 -0
- package/dist/codemirror/format/index.d.ts +4 -0
- package/dist/codemirror/format/index.js +3 -0
- package/dist/codemirror/format/index.js.map +1 -0
- package/dist/codemirror/highlight/highlightPlugin.d.ts +10 -0
- package/dist/codemirror/highlight/highlightPlugin.js +66 -0
- package/dist/codemirror/highlight/highlightPlugin.js.map +1 -0
- package/dist/codemirror/highlight/highlightScanRule.d.ts +8 -0
- package/dist/codemirror/highlight/highlightScanRule.js +12 -0
- package/dist/codemirror/highlight/highlightScanRule.js.map +1 -0
- package/dist/codemirror/highlight/index.d.ts +2 -0
- package/dist/codemirror/highlight/index.js +2 -0
- package/dist/codemirror/highlight/index.js.map +1 -0
- package/dist/codemirror/html/htmlWidget.d.ts +23 -0
- package/dist/codemirror/html/htmlWidget.js +67 -0
- package/dist/codemirror/html/htmlWidget.js.map +1 -0
- package/dist/codemirror/html/index.d.ts +4 -0
- package/dist/codemirror/html/index.js +2 -0
- package/dist/codemirror/html/index.js.map +1 -0
- package/dist/codemirror/image/imageActionMenu.d.ts +14 -0
- package/dist/codemirror/image/imageActionMenu.js +112 -0
- package/dist/codemirror/image/imageActionMenu.js.map +1 -0
- package/dist/codemirror/image/imageEditEvent.d.ts +20 -0
- package/dist/codemirror/image/imageEditEvent.js +6 -0
- package/dist/codemirror/image/imageEditEvent.js.map +1 -0
- package/dist/codemirror/image/imageInsertHandlers.d.ts +13 -0
- package/dist/codemirror/image/imageInsertHandlers.js +64 -0
- package/dist/codemirror/image/imageInsertHandlers.js.map +1 -0
- package/dist/codemirror/image/imageWidget.d.ts +49 -0
- package/dist/codemirror/image/imageWidget.js +83 -0
- package/dist/codemirror/image/imageWidget.js.map +1 -0
- package/dist/codemirror/image/index.d.ts +8 -0
- package/dist/codemirror/image/index.js +5 -0
- package/dist/codemirror/image/index.js.map +1 -0
- package/dist/codemirror/interaction/clickModel.d.ts +43 -0
- package/dist/codemirror/interaction/clickModel.js +99 -0
- package/dist/codemirror/interaction/clickModel.js.map +1 -0
- package/dist/codemirror/interaction/cursorModel.d.ts +10 -0
- package/dist/codemirror/interaction/cursorModel.js +58 -0
- package/dist/codemirror/interaction/cursorModel.js.map +1 -0
- package/dist/codemirror/interaction/deleteNormalizer.d.ts +18 -0
- package/dist/codemirror/interaction/deleteNormalizer.js +157 -0
- package/dist/codemirror/interaction/deleteNormalizer.js.map +1 -0
- package/dist/codemirror/interaction/flankingGuard.d.ts +20 -0
- package/dist/codemirror/interaction/flankingGuard.js +48 -0
- package/dist/codemirror/interaction/flankingGuard.js.map +1 -0
- package/dist/codemirror/interaction/index.d.ts +7 -0
- package/dist/codemirror/interaction/index.js +6 -0
- package/dist/codemirror/interaction/index.js.map +1 -0
- package/dist/codemirror/interaction/visiblePosition.d.ts +43 -0
- package/dist/codemirror/interaction/visiblePosition.js +98 -0
- package/dist/codemirror/interaction/visiblePosition.js.map +1 -0
- package/dist/codemirror/list/bulletWidget.d.ts +61 -0
- package/dist/codemirror/list/bulletWidget.js +84 -0
- package/dist/codemirror/list/bulletWidget.js.map +1 -0
- package/dist/codemirror/list/index.d.ts +4 -0
- package/dist/codemirror/list/index.js +3 -0
- package/dist/codemirror/list/index.js.map +1 -0
- package/dist/codemirror/list/listContinuation.d.ts +28 -0
- package/dist/codemirror/list/listContinuation.js +61 -0
- package/dist/codemirror/list/listContinuation.js.map +1 -0
- package/dist/codemirror/list/listIndent.d.ts +8 -0
- package/dist/codemirror/list/listIndent.js +95 -0
- package/dist/codemirror/list/listIndent.js.map +1 -0
- package/dist/codemirror/list/taskCheckboxWidget.d.ts +42 -0
- package/dist/codemirror/list/taskCheckboxWidget.js +47 -0
- package/dist/codemirror/list/taskCheckboxWidget.js.map +1 -0
- package/dist/codemirror/math/index.d.ts +3 -0
- package/dist/codemirror/math/index.js +2 -0
- package/dist/codemirror/math/index.js.map +1 -0
- package/dist/codemirror/math/mathPlugin.d.ts +10 -0
- package/dist/codemirror/math/mathPlugin.js +73 -0
- package/dist/codemirror/math/mathPlugin.js.map +1 -0
- package/dist/codemirror/math/mathScanRule.d.ts +16 -0
- package/dist/codemirror/math/mathScanRule.js +18 -0
- package/dist/codemirror/math/mathScanRule.js.map +1 -0
- package/dist/codemirror/math/mathWidget.d.ts +15 -0
- package/dist/codemirror/math/mathWidget.js +36 -0
- package/dist/codemirror/math/mathWidget.js.map +1 -0
- package/dist/codemirror/mermaid/index.d.ts +4 -0
- package/dist/codemirror/mermaid/index.js +3 -0
- package/dist/codemirror/mermaid/index.js.map +1 -0
- package/dist/codemirror/mermaid/mermaidPlugin.d.ts +25 -0
- package/dist/codemirror/mermaid/mermaidPlugin.js +78 -0
- package/dist/codemirror/mermaid/mermaidPlugin.js.map +1 -0
- package/dist/codemirror/mermaid/mermaidRender.d.ts +42 -0
- package/dist/codemirror/mermaid/mermaidRender.js +136 -0
- package/dist/codemirror/mermaid/mermaidRender.js.map +1 -0
- package/dist/codemirror/mermaid/mermaidWidget.d.ts +42 -0
- package/dist/codemirror/mermaid/mermaidWidget.js +142 -0
- package/dist/codemirror/mermaid/mermaidWidget.js.map +1 -0
- package/dist/codemirror/selectionLayer.d.ts +43 -0
- package/dist/codemirror/selectionLayer.js +135 -0
- package/dist/codemirror/selectionLayer.js.map +1 -0
- package/dist/codemirror/table/cellDividerWidget.d.ts +9 -0
- package/dist/codemirror/table/cellDividerWidget.js +19 -0
- package/dist/codemirror/table/cellDividerWidget.js.map +1 -0
- package/dist/codemirror/table/index.d.ts +5 -0
- package/dist/codemirror/table/index.js +4 -0
- package/dist/codemirror/table/index.js.map +1 -0
- package/dist/codemirror/table/tableArmed.d.ts +27 -0
- package/dist/codemirror/table/tableArmed.js +43 -0
- package/dist/codemirror/table/tableArmed.js.map +1 -0
- package/dist/codemirror/table/tableCell.d.ts +19 -0
- package/dist/codemirror/table/tableCell.js +15 -0
- package/dist/codemirror/table/tableCell.js.map +1 -0
- package/dist/codemirror/table/tableCellNav.d.ts +51 -0
- package/dist/codemirror/table/tableCellNav.js +47 -0
- package/dist/codemirror/table/tableCellNav.js.map +1 -0
- package/dist/codemirror/table/tableContextMenu.d.ts +22 -0
- package/dist/codemirror/table/tableContextMenu.js +139 -0
- package/dist/codemirror/table/tableContextMenu.js.map +1 -0
- package/dist/codemirror/table/tableEditCommands.d.ts +29 -0
- package/dist/codemirror/table/tableEditCommands.js +86 -0
- package/dist/codemirror/table/tableEditCommands.js.map +1 -0
- package/dist/codemirror/table/tableExcerpt.d.ts +29 -0
- package/dist/codemirror/table/tableExcerpt.js +34 -0
- package/dist/codemirror/table/tableExcerpt.js.map +1 -0
- package/dist/codemirror/table/tableField.d.ts +6 -0
- package/dist/codemirror/table/tableField.js +37 -0
- package/dist/codemirror/table/tableField.js.map +1 -0
- package/dist/codemirror/table/tableGeometry.d.ts +33 -0
- package/dist/codemirror/table/tableGeometry.js +28 -0
- package/dist/codemirror/table/tableGeometry.js.map +1 -0
- package/dist/codemirror/table/tableInline.d.ts +37 -0
- package/dist/codemirror/table/tableInline.js +105 -0
- package/dist/codemirror/table/tableInline.js.map +1 -0
- package/dist/codemirror/table/tableModel.d.ts +45 -0
- package/dist/codemirror/table/tableModel.js +98 -0
- package/dist/codemirror/table/tableModel.js.map +1 -0
- package/dist/codemirror/tablev2/bridgeRules.d.ts +48 -0
- package/dist/codemirror/tablev2/bridgeRules.js +42 -0
- package/dist/codemirror/tablev2/bridgeRules.js.map +1 -0
- package/dist/codemirror/tablev2/cellEditingSurface.d.ts +79 -0
- package/dist/codemirror/tablev2/cellEditingSurface.js +70 -0
- package/dist/codemirror/tablev2/cellEditingSurface.js.map +1 -0
- package/dist/codemirror/tablev2/cellText.d.ts +11 -0
- package/dist/codemirror/tablev2/cellText.js +12 -0
- package/dist/codemirror/tablev2/cellText.js.map +1 -0
- package/dist/codemirror/tablev2/inlineCellSurface.d.ts +38 -0
- package/dist/codemirror/tablev2/inlineCellSurface.js +162 -0
- package/dist/codemirror/tablev2/inlineCellSurface.js.map +1 -0
- package/dist/codemirror/tablev2/overlayCellSurface.d.ts +36 -0
- package/dist/codemirror/tablev2/overlayCellSurface.js +150 -0
- package/dist/codemirror/tablev2/overlayCellSurface.js.map +1 -0
- package/dist/codemirror/tablev2/tableEditingSteps.d.ts +12 -0
- package/dist/codemirror/tablev2/tableEditingSteps.js +518 -0
- package/dist/codemirror/tablev2/tableEditingSteps.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2HoverControls.d.ts +23 -0
- package/dist/codemirror/tablev2/tableV2HoverControls.js +89 -0
- package/dist/codemirror/tablev2/tableV2HoverControls.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2Interaction.d.ts +29 -0
- package/dist/codemirror/tablev2/tableV2Interaction.js +224 -0
- package/dist/codemirror/tablev2/tableV2Interaction.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2Selection.d.ts +45 -0
- package/dist/codemirror/tablev2/tableV2Selection.js +81 -0
- package/dist/codemirror/tablev2/tableV2Selection.js.map +1 -0
- package/dist/codemirror/tablev2/tableV2Sync.d.ts +13 -0
- package/dist/codemirror/tablev2/tableV2Sync.js +13 -0
- package/dist/codemirror/tablev2/tableV2Sync.js.map +1 -0
- package/dist/codemirror/tablev2/tableWidgetV2.d.ts +46 -0
- package/dist/codemirror/tablev2/tableWidgetV2.js +139 -0
- package/dist/codemirror/tablev2/tableWidgetV2.js.map +1 -0
- package/dist/codemirror/updateBus.d.ts +29 -0
- package/dist/codemirror/updateBus.js +26 -0
- package/dist/codemirror/updateBus.js.map +1 -0
- package/dist/codemirror/wikilink/index.d.ts +3 -0
- package/dist/codemirror/wikilink/index.js +2 -0
- package/dist/codemirror/wikilink/index.js.map +1 -0
- package/dist/codemirror/wikilink/wikilinkPlugin.d.ts +40 -0
- package/dist/codemirror/wikilink/wikilinkPlugin.js +89 -0
- package/dist/codemirror/wikilink/wikilinkPlugin.js.map +1 -0
- package/dist/codemirror/wikilink/wikilinkScanRule.d.ts +9 -0
- package/dist/codemirror/wikilink/wikilinkScanRule.js +13 -0
- package/dist/codemirror/wikilink/wikilinkScanRule.js.map +1 -0
- package/dist/frontmatter.d.ts +79 -0
- package/dist/frontmatter.js +58 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/imageInsert.d.ts +66 -0
- package/dist/imageInsert.js +111 -0
- package/dist/imageInsert.js.map +1 -0
- package/dist/imageSrcResolver.d.ts +55 -0
- package/dist/imageSrcResolver.js +49 -0
- package/dist/imageSrcResolver.js.map +1 -0
- package/dist/index.d.ts +35 -880
- package/dist/index.js +128 -5989
- package/dist/index.js.map +1 -1
- package/dist/links/wikilink.d.ts +26 -0
- package/dist/links/wikilink.js +54 -0
- package/dist/links/wikilink.js.map +1 -0
- package/dist/links/workspaceLink.d.ts +34 -0
- package/dist/links/workspaceLink.js +60 -0
- package/dist/links/workspaceLink.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { EditorState, Facet } from '@codemirror/state';
|
|
2
|
+
import { Decoration } from '@codemirror/view';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The rendering contract: one polymorphic shape for "how does a Lezer node
|
|
6
|
+
* render", replacing three parallel dispatch surfaces (a data-entry union, a
|
|
7
|
+
* widget-name union + builders map, and a contextual-override switch).
|
|
8
|
+
*
|
|
9
|
+
* NodeRule = (ctx) => Paint — one function per node NAME
|
|
10
|
+
* Paint = which CM6 mechanism — a CLOSED union
|
|
11
|
+
*
|
|
12
|
+
* The openness is split on the right axis: CONSTRUCTS grow (every new node
|
|
13
|
+
* adds a rule — one entry, one place, usually one line via the combinators
|
|
14
|
+
* below), while the ways to PAINT don't (line class / span mark / hide /
|
|
15
|
+
* widget / nothing — CodeMirror's own vocabulary). The single switch over
|
|
16
|
+
* `Paint` lives in the painter (plugin.ts) and never changes when a
|
|
17
|
+
* construct is added.
|
|
18
|
+
*
|
|
19
|
+
* Context (the bare-URL lesson: a node name can mean different things in
|
|
20
|
+
* different parents) is not a bolt-on — every rule IS a function of context;
|
|
21
|
+
* simple rules just ignore it.
|
|
22
|
+
*
|
|
23
|
+
* Extensions contribute rules through {@link nodeRulesFacet}: a plugin that
|
|
24
|
+
* introduces node names ships its rules alongside its grammar, touching no
|
|
25
|
+
* core file.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
interface NodeLike {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly from: number;
|
|
31
|
+
readonly to: number;
|
|
32
|
+
readonly parent: NodeLike | null;
|
|
33
|
+
readonly firstChild: NodeLike | null;
|
|
34
|
+
readonly nextSibling: NodeLike | null;
|
|
35
|
+
readonly prevSibling: NodeLike | null;
|
|
36
|
+
getChild(type: string): NodeLike | null;
|
|
37
|
+
}
|
|
38
|
+
/** Everything a rule may consult. */
|
|
39
|
+
interface NodeContext {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly from: number;
|
|
42
|
+
readonly to: number;
|
|
43
|
+
/** The parent node's name — the common contextual discriminator. */
|
|
44
|
+
readonly parentName: string | undefined;
|
|
45
|
+
/** Full structural node, for rules that need siblings/children. */
|
|
46
|
+
readonly node: NodeLike;
|
|
47
|
+
/** Rules are pure over state — no view dependency, so non-editor
|
|
48
|
+
* renderers (table cells) can invoke the same rules. */
|
|
49
|
+
readonly state: EditorState;
|
|
50
|
+
}
|
|
51
|
+
/** One painting instruction, in CodeMirror's own vocabulary. */
|
|
52
|
+
type Paint =
|
|
53
|
+
/** Stamp a line class — on the node's first line, or every spanned line. */
|
|
54
|
+
{
|
|
55
|
+
readonly paint: "lineClass";
|
|
56
|
+
readonly className: string;
|
|
57
|
+
readonly span: "first" | "all";
|
|
58
|
+
}
|
|
59
|
+
/** Style the node's span. */
|
|
60
|
+
| {
|
|
61
|
+
readonly paint: "mark";
|
|
62
|
+
readonly className: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Hide a range (default: the node, plus its one separator space when
|
|
66
|
+
* line-leading) and make it atomic to caret motion. `atomicTo` widens the
|
|
67
|
+
* atom past the hidden range (marker + space move as one unit).
|
|
68
|
+
*/
|
|
69
|
+
| {
|
|
70
|
+
readonly paint: "hide";
|
|
71
|
+
readonly range?: {
|
|
72
|
+
readonly from: number;
|
|
73
|
+
readonly to: number;
|
|
74
|
+
};
|
|
75
|
+
readonly expandSpace?: boolean;
|
|
76
|
+
readonly atomicTo?: number;
|
|
77
|
+
}
|
|
78
|
+
/** Replace the (hidden) span with a widget decoration. */
|
|
79
|
+
| {
|
|
80
|
+
readonly paint: "widget";
|
|
81
|
+
readonly deco: Decoration;
|
|
82
|
+
readonly atomicTo?: number;
|
|
83
|
+
}
|
|
84
|
+
/** Leave the node alone — visible raw source. */
|
|
85
|
+
| {
|
|
86
|
+
readonly paint: "none";
|
|
87
|
+
};
|
|
88
|
+
interface RuleMeta {
|
|
89
|
+
readonly intent: "render-raw" | "structural";
|
|
90
|
+
readonly why: string;
|
|
91
|
+
}
|
|
92
|
+
/** How one node name renders. `meta` tags the deliberate do-nothing rules so
|
|
93
|
+
* the coverage test can insist their reason is documented. */
|
|
94
|
+
type NodeRule = ((ctx: NodeContext) => Paint) & {
|
|
95
|
+
readonly meta?: RuleMeta;
|
|
96
|
+
};
|
|
97
|
+
type NodeRules = Readonly<Record<string, NodeRule>>;
|
|
98
|
+
/** Style the node's span with a class. */
|
|
99
|
+
declare function mark(className: string): NodeRule;
|
|
100
|
+
/** Stamp a line class on every line the node spans. */
|
|
101
|
+
declare function line(className: string): NodeRule;
|
|
102
|
+
/** Stamp a line class on the node's first line only (headings). */
|
|
103
|
+
declare function headingLine(className: string): NodeRule;
|
|
104
|
+
/** Hide the node (marker chrome), atomically. */
|
|
105
|
+
declare function hideAlways(): NodeRule;
|
|
106
|
+
/** Deliberately unstyled-for-now, visible raw — `why` documents the intent. */
|
|
107
|
+
declare function raw(why: string): NodeRule;
|
|
108
|
+
/** A parser grouping construct, never directly visible — `why` says which. */
|
|
109
|
+
declare function structural(why: string): NodeRule;
|
|
110
|
+
declare const none: Paint;
|
|
111
|
+
/**
|
|
112
|
+
* Rules contributed by extensions, merged over the base table (an extension
|
|
113
|
+
* may also deliberately override a base rule — last provider wins). The
|
|
114
|
+
* painter reads THIS, never the base table directly.
|
|
115
|
+
*/
|
|
116
|
+
declare const nodeRulesFacet: Facet<Readonly<Record<string, NodeRule>>, Readonly<Record<string, NodeRule>>>;
|
|
117
|
+
|
|
118
|
+
export { type NodeContext, type NodeLike, type NodeRule, type NodeRules, type Paint, type RuleMeta, headingLine, hideAlways, line, mark, nodeRulesFacet, none, raw, structural };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import "../../chunk-V6TY7KAL.js";
|
|
2
|
+
import { Facet } from "@codemirror/state";
|
|
3
|
+
const NONE = { paint: "none" };
|
|
4
|
+
function mark(className) {
|
|
5
|
+
const paint = { paint: "mark", className };
|
|
6
|
+
return () => paint;
|
|
7
|
+
}
|
|
8
|
+
function line(className) {
|
|
9
|
+
const paint = { paint: "lineClass", className, span: "all" };
|
|
10
|
+
return () => paint;
|
|
11
|
+
}
|
|
12
|
+
function headingLine(className) {
|
|
13
|
+
const paint = { paint: "lineClass", className, span: "first" };
|
|
14
|
+
return () => paint;
|
|
15
|
+
}
|
|
16
|
+
function hideAlways() {
|
|
17
|
+
const paint = { paint: "hide" };
|
|
18
|
+
return () => paint;
|
|
19
|
+
}
|
|
20
|
+
function raw(why) {
|
|
21
|
+
return Object.assign(() => NONE, { meta: { intent: "render-raw", why } });
|
|
22
|
+
}
|
|
23
|
+
function structural(why) {
|
|
24
|
+
return Object.assign(() => NONE, { meta: { intent: "structural", why } });
|
|
25
|
+
}
|
|
26
|
+
const none = NONE;
|
|
27
|
+
const nodeRulesFacet = Facet.define({
|
|
28
|
+
combine(values) {
|
|
29
|
+
return Object.assign({}, ...values);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
export {
|
|
33
|
+
headingLine,
|
|
34
|
+
hideAlways,
|
|
35
|
+
line,
|
|
36
|
+
mark,
|
|
37
|
+
nodeRulesFacet,
|
|
38
|
+
none,
|
|
39
|
+
raw,
|
|
40
|
+
structural
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=paint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/core/paint.ts"],"sourcesContent":["/**\n * The rendering contract: one polymorphic shape for \"how does a Lezer node\n * render\", replacing three parallel dispatch surfaces (a data-entry union, a\n * widget-name union + builders map, and a contextual-override switch).\n *\n * NodeRule = (ctx) => Paint — one function per node NAME\n * Paint = which CM6 mechanism — a CLOSED union\n *\n * The openness is split on the right axis: CONSTRUCTS grow (every new node\n * adds a rule — one entry, one place, usually one line via the combinators\n * below), while the ways to PAINT don't (line class / span mark / hide /\n * widget / nothing — CodeMirror's own vocabulary). The single switch over\n * `Paint` lives in the painter (plugin.ts) and never changes when a\n * construct is added.\n *\n * Context (the bare-URL lesson: a node name can mean different things in\n * different parents) is not a bolt-on — every rule IS a function of context;\n * simple rules just ignore it.\n *\n * Extensions contribute rules through {@link nodeRulesFacet}: a plugin that\n * introduces node names ships its rules alongside its grammar, touching no\n * core file.\n */\n\nimport { Facet, type EditorState } from \"@codemirror/state\";\nimport { type Decoration } from \"@codemirror/view\";\n\n// Structural stand-in for a Lezer node (`@lezer/common` is a transitive dep\n// this package deliberately doesn't import from).\nexport interface NodeLike {\n readonly name: string;\n readonly from: number;\n readonly to: number;\n readonly parent: NodeLike | null;\n readonly firstChild: NodeLike | null;\n readonly nextSibling: NodeLike | null;\n readonly prevSibling: NodeLike | null;\n getChild(type: string): NodeLike | null;\n}\n\n/** Everything a rule may consult. */\nexport interface NodeContext {\n readonly name: string;\n readonly from: number;\n readonly to: number;\n /** The parent node's name — the common contextual discriminator. */\n readonly parentName: string | undefined;\n /** Full structural node, for rules that need siblings/children. */\n readonly node: NodeLike;\n /** Rules are pure over state — no view dependency, so non-editor\n * renderers (table cells) can invoke the same rules. */\n readonly state: EditorState;\n}\n\n/** One painting instruction, in CodeMirror's own vocabulary. */\nexport type Paint =\n /** Stamp a line class — on the node's first line, or every spanned line. */\n | { readonly paint: \"lineClass\"; readonly className: string; readonly span: \"first\" | \"all\" }\n /** Style the node's span. */\n | { readonly paint: \"mark\"; readonly className: string }\n /**\n * Hide a range (default: the node, plus its one separator space when\n * line-leading) and make it atomic to caret motion. `atomicTo` widens the\n * atom past the hidden range (marker + space move as one unit).\n */\n | {\n readonly paint: \"hide\";\n readonly range?: { readonly from: number; readonly to: number };\n readonly expandSpace?: boolean;\n readonly atomicTo?: number;\n }\n /** Replace the (hidden) span with a widget decoration. */\n | { readonly paint: \"widget\"; readonly deco: Decoration; readonly atomicTo?: number }\n /** Leave the node alone — visible raw source. */\n | { readonly paint: \"none\" };\n\nexport interface RuleMeta {\n readonly intent: \"render-raw\" | \"structural\";\n readonly why: string;\n}\n\n/** How one node name renders. `meta` tags the deliberate do-nothing rules so\n * the coverage test can insist their reason is documented. */\nexport type NodeRule = ((ctx: NodeContext) => Paint) & { readonly meta?: RuleMeta };\n\nexport type NodeRules = Readonly<Record<string, NodeRule>>;\n\n/* ---------------- Combinators — the common rules as one-liners ------------ */\n\nconst NONE: Paint = { paint: \"none\" };\n\n/** Style the node's span with a class. */\nexport function mark(className: string): NodeRule {\n const paint: Paint = { paint: \"mark\", className };\n return () => paint;\n}\n\n/** Stamp a line class on every line the node spans. */\nexport function line(className: string): NodeRule {\n const paint: Paint = { paint: \"lineClass\", className, span: \"all\" };\n return () => paint;\n}\n\n/** Stamp a line class on the node's first line only (headings). */\nexport function headingLine(className: string): NodeRule {\n const paint: Paint = { paint: \"lineClass\", className, span: \"first\" };\n return () => paint;\n}\n\n/** Hide the node (marker chrome), atomically. */\nexport function hideAlways(): NodeRule {\n const paint: Paint = { paint: \"hide\" };\n return () => paint;\n}\n\n/** Deliberately unstyled-for-now, visible raw — `why` documents the intent. */\nexport function raw(why: string): NodeRule {\n return Object.assign(() => NONE, { meta: { intent: \"render-raw\", why } as RuleMeta });\n}\n\n/** A parser grouping construct, never directly visible — `why` says which. */\nexport function structural(why: string): NodeRule {\n return Object.assign(() => NONE, { meta: { intent: \"structural\", why } as RuleMeta });\n}\n\nexport const none: Paint = NONE;\n\n/* ---------------- Extension seam ----------------------------------------- */\n\n/**\n * Rules contributed by extensions, merged over the base table (an extension\n * may also deliberately override a base rule — last provider wins). The\n * painter reads THIS, never the base table directly.\n */\nexport const nodeRulesFacet = Facet.define<NodeRules, NodeRules>({\n combine(values) {\n return Object.assign({}, ...values);\n },\n});\n"],"mappings":";AAwBA,SAAS,aAA+B;AAiExC,MAAM,OAAc,EAAE,OAAO,OAAO;AAG7B,SAAS,KAAK,WAA6B;AAChD,QAAM,QAAe,EAAE,OAAO,QAAQ,UAAU;AAChD,SAAO,MAAM;AACf;AAGO,SAAS,KAAK,WAA6B;AAChD,QAAM,QAAe,EAAE,OAAO,aAAa,WAAW,MAAM,MAAM;AAClE,SAAO,MAAM;AACf;AAGO,SAAS,YAAY,WAA6B;AACvD,QAAM,QAAe,EAAE,OAAO,aAAa,WAAW,MAAM,QAAQ;AACpE,SAAO,MAAM;AACf;AAGO,SAAS,aAAuB;AACrC,QAAM,QAAe,EAAE,OAAO,OAAO;AACrC,SAAO,MAAM;AACf;AAGO,SAAS,IAAI,KAAuB;AACzC,SAAO,OAAO,OAAO,MAAM,MAAM,EAAE,MAAM,EAAE,QAAQ,cAAc,IAAI,EAAc,CAAC;AACtF;AAGO,SAAS,WAAW,KAAuB;AAChD,SAAO,OAAO,OAAO,MAAM,MAAM,EAAE,MAAM,EAAE,QAAQ,cAAc,IAAI,EAAc,CAAC;AACtF;AAEO,MAAM,OAAc;AASpB,MAAM,iBAAiB,MAAM,OAA6B;AAAA,EAC/D,QAAQ,QAAQ;AACd,WAAO,OAAO,OAAO,CAAC,GAAG,GAAG,MAAM;AAAA,EACpC;AACF,CAAC;","names":[]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Extension } from '@codemirror/state';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Drives the parse to the end of the document, establishing the invariant the
|
|
5
|
+
* rest of the editor is written against: **the installed syntax tree covers
|
|
6
|
+
* the whole document**, not just what the viewport happened to render.
|
|
7
|
+
*
|
|
8
|
+
* Without it, CodeMirror's own background work stops 100,000 characters past
|
|
9
|
+
* the viewport (measured: the tree plateaus at 100,739 for a 167k-character
|
|
10
|
+
* document and a 341k one alike, and never advances again). Everything
|
|
11
|
+
* downstream of the tree is then silently wrong for the rest of the document:
|
|
12
|
+
* table and mermaid widgets never materialize, code-language affordances never
|
|
13
|
+
* appear, and structural commands are left to re-parse at the caret
|
|
14
|
+
* ({@link treeAt} — still wanted, since a keystroke can land before this
|
|
15
|
+
* finishes).
|
|
16
|
+
*
|
|
17
|
+
* Scheduled with `setTimeout`, not `requestIdleCallback`: WebKit stops
|
|
18
|
+
* delivering idle callbacks to an unfocused window, and a note opened while
|
|
19
|
+
* the app is in the background must still be parsed when the user comes back
|
|
20
|
+
* to it.
|
|
21
|
+
*/
|
|
22
|
+
declare const parseToEnd: Extension;
|
|
23
|
+
|
|
24
|
+
export { parseToEnd };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "../../chunk-V6TY7KAL.js";
|
|
4
|
+
import { forceParsing, language, syntaxTree } from "@codemirror/language";
|
|
5
|
+
import { ViewPlugin } from "@codemirror/view";
|
|
6
|
+
const SLICE_MS = 10;
|
|
7
|
+
const GAP_MS = 25;
|
|
8
|
+
const parseToEnd = ViewPlugin.fromClass(
|
|
9
|
+
class {
|
|
10
|
+
constructor(view) {
|
|
11
|
+
__publicField(this, "view", view);
|
|
12
|
+
__publicField(this, "timer", null);
|
|
13
|
+
__publicField(this, "work", () => {
|
|
14
|
+
this.timer = null;
|
|
15
|
+
const { state } = this.view;
|
|
16
|
+
if (!state.facet(language)) return;
|
|
17
|
+
if (syntaxTree(state).length >= state.doc.length) return;
|
|
18
|
+
forceParsing(this.view, state.doc.length, SLICE_MS);
|
|
19
|
+
this.schedule();
|
|
20
|
+
});
|
|
21
|
+
this.schedule();
|
|
22
|
+
}
|
|
23
|
+
update(update) {
|
|
24
|
+
if (update.docChanged) this.schedule();
|
|
25
|
+
}
|
|
26
|
+
destroy() {
|
|
27
|
+
if (this.timer !== null) window.clearTimeout(this.timer);
|
|
28
|
+
}
|
|
29
|
+
schedule() {
|
|
30
|
+
if (this.timer !== null) return;
|
|
31
|
+
this.timer = window.setTimeout(this.work, GAP_MS);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
export {
|
|
36
|
+
parseToEnd
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=parseToEnd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/core/parseToEnd.ts"],"sourcesContent":["import { forceParsing, language, syntaxTree } from \"@codemirror/language\";\nimport type { Extension } from \"@codemirror/state\";\nimport { ViewPlugin, type EditorView, type ViewUpdate } from \"@codemirror/view\";\n\n/** Work per slice. Small enough to never register as jank between frames. */\nconst SLICE_MS = 10;\n\n/** Gap between slices, leaving the main thread mostly idle while the tail of a\n * large document parses. Markdown covers ~240k characters in ~43ms of work, so\n * even a very large note finishes within a few hundred ms of opening. */\nconst GAP_MS = 25;\n\n/**\n * Drives the parse to the end of the document, establishing the invariant the\n * rest of the editor is written against: **the installed syntax tree covers\n * the whole document**, not just what the viewport happened to render.\n *\n * Without it, CodeMirror's own background work stops 100,000 characters past\n * the viewport (measured: the tree plateaus at 100,739 for a 167k-character\n * document and a 341k one alike, and never advances again). Everything\n * downstream of the tree is then silently wrong for the rest of the document:\n * table and mermaid widgets never materialize, code-language affordances never\n * appear, and structural commands are left to re-parse at the caret\n * ({@link treeAt} — still wanted, since a keystroke can land before this\n * finishes).\n *\n * Scheduled with `setTimeout`, not `requestIdleCallback`: WebKit stops\n * delivering idle callbacks to an unfocused window, and a note opened while\n * the app is in the background must still be parsed when the user comes back\n * to it.\n */\nexport const parseToEnd: Extension = ViewPlugin.fromClass(\n class {\n private timer: number | null = null;\n\n constructor(private readonly view: EditorView) {\n this.schedule();\n }\n\n update(update: ViewUpdate) {\n if (update.docChanged) this.schedule();\n }\n\n destroy() {\n if (this.timer !== null) window.clearTimeout(this.timer);\n }\n\n private schedule() {\n if (this.timer !== null) return;\n this.timer = window.setTimeout(this.work, GAP_MS);\n }\n\n private readonly work = () => {\n this.timer = null;\n const { state } = this.view;\n // Without a language nothing will ever parse; rescheduling would poll\n // forever for a tree that never comes.\n if (!state.facet(language)) return;\n if (syntaxTree(state).length >= state.doc.length) return;\n forceParsing(this.view, state.doc.length, SLICE_MS);\n // Reschedule until covered, not until progress: a slice can spend its\n // whole budget without committing a longer tree (measured: the resume\n // from CodeMirror's own stop point commits nothing on the first slice,\n // then covers the rest of the document on the next).\n this.schedule();\n };\n },\n);\n"],"mappings":";;;AAAA,SAAS,cAAc,UAAU,kBAAkB;AAEnD,SAAS,kBAAoD;AAG7D,MAAM,WAAW;AAKjB,MAAM,SAAS;AAqBR,MAAM,aAAwB,WAAW;AAAA,EAC9C,MAAM;AAAA,IAGJ,YAA6B,MAAkB;AAAlB;AAF7B,0BAAQ,SAAuB;AAmB/B,0BAAiB,QAAO,MAAM;AAC5B,aAAK,QAAQ;AACb,cAAM,EAAE,MAAM,IAAI,KAAK;AAGvB,YAAI,CAAC,MAAM,MAAM,QAAQ,EAAG;AAC5B,YAAI,WAAW,KAAK,EAAE,UAAU,MAAM,IAAI,OAAQ;AAClD,qBAAa,KAAK,MAAM,MAAM,IAAI,QAAQ,QAAQ;AAKlD,aAAK,SAAS;AAAA,MAChB;AA7BE,WAAK,SAAS;AAAA,IAChB;AAAA,IAEA,OAAO,QAAoB;AACzB,UAAI,OAAO,WAAY,MAAK,SAAS;AAAA,IACvC;AAAA,IAEA,UAAU;AACR,UAAI,KAAK,UAAU,KAAM,QAAO,aAAa,KAAK,KAAK;AAAA,IACzD;AAAA,IAEQ,WAAW;AACjB,UAAI,KAAK,UAAU,KAAM;AACzB,WAAK,QAAQ,OAAO,WAAW,KAAK,MAAM,MAAM;AAAA,IAClD;AAAA,EAgBF;AACF;","names":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ViewPlugin, DecorationSet, ViewUpdate } from '@codemirror/view';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Markdown decoration plugin — the PAINTER. Walks the Lezer tree against the
|
|
5
|
+
* visible viewport, asks each node's {@link NodeRule} how to render, and
|
|
6
|
+
* applies the returned {@link Paint}.
|
|
7
|
+
*
|
|
8
|
+
* The painter contains *no* construct knowledge: rules live in the base
|
|
9
|
+
* table (`NODE_RULES`) merged with any extension-contributed rules
|
|
10
|
+
* (`nodeRulesFacet`). The one switch here is over `Paint` — CodeMirror's
|
|
11
|
+
* closed set of mechanisms — so adding a construct, widget, contextual
|
|
12
|
+
* override, or whole extension never edits this file.
|
|
13
|
+
*
|
|
14
|
+
* Perf shape (unchanged from the spike):
|
|
15
|
+
* * Walks `view.visibleRanges` against `syntaxTree(view.state)` —
|
|
16
|
+
* the work is proportional to the viewport, not the document.
|
|
17
|
+
* * Rebuilt on doc change or viewport change.
|
|
18
|
+
*
|
|
19
|
+
* Decoration ordering (CM6 requires `from`-then-`startSide` ascending):
|
|
20
|
+
* * Line decorations collected in one bucket, mark / replace in
|
|
21
|
+
* another. The final `Decoration.set` lets CM6 sort defensively,
|
|
22
|
+
* costing ~µs on the typical viewport — cheaper than risking the
|
|
23
|
+
* "decorations out of order" runtime error.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
declare const markdownDecorationsPlugin: ViewPlugin<{
|
|
27
|
+
decorations: DecorationSet;
|
|
28
|
+
atomic: DecorationSet;
|
|
29
|
+
update(update: ViewUpdate): void;
|
|
30
|
+
}, undefined>;
|
|
31
|
+
|
|
32
|
+
export { markdownDecorationsPlugin };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "../../chunk-V6TY7KAL.js";
|
|
4
|
+
import { ensureSyntaxTree, syntaxTree } from "@codemirror/language";
|
|
5
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
6
|
+
import {
|
|
7
|
+
Decoration,
|
|
8
|
+
EditorView,
|
|
9
|
+
ViewPlugin
|
|
10
|
+
} from "@codemirror/view";
|
|
11
|
+
import { nodeRulesFacet } from "./paint.js";
|
|
12
|
+
import { NODE_RULES } from "./registry.js";
|
|
13
|
+
const lineDecoCache = /* @__PURE__ */ new Map();
|
|
14
|
+
const markDecoCache = /* @__PURE__ */ new Map();
|
|
15
|
+
const HIDE_MARKER = Decoration.replace({});
|
|
16
|
+
function lineDeco(className) {
|
|
17
|
+
let d = lineDecoCache.get(className);
|
|
18
|
+
if (!d) {
|
|
19
|
+
d = Decoration.line({ class: className });
|
|
20
|
+
lineDecoCache.set(className, d);
|
|
21
|
+
}
|
|
22
|
+
return d;
|
|
23
|
+
}
|
|
24
|
+
function markDeco(className) {
|
|
25
|
+
let d = markDecoCache.get(className);
|
|
26
|
+
if (!d) {
|
|
27
|
+
d = Decoration.mark({ class: className });
|
|
28
|
+
markDecoCache.set(className, d);
|
|
29
|
+
}
|
|
30
|
+
return d;
|
|
31
|
+
}
|
|
32
|
+
const mergedRulesCache = /* @__PURE__ */ new WeakMap();
|
|
33
|
+
function effectiveRules(view) {
|
|
34
|
+
const extra = view.state.facet(nodeRulesFacet);
|
|
35
|
+
if (Object.keys(extra).length === 0) return NODE_RULES;
|
|
36
|
+
let merged = mergedRulesCache.get(extra);
|
|
37
|
+
if (!merged) {
|
|
38
|
+
merged = Object.assign({}, NODE_RULES, extra);
|
|
39
|
+
mergedRulesCache.set(extra, merged);
|
|
40
|
+
}
|
|
41
|
+
return merged;
|
|
42
|
+
}
|
|
43
|
+
function expandTrailingSpace(view, range) {
|
|
44
|
+
const line = view.state.doc.lineAt(range.from);
|
|
45
|
+
if (range.from !== line.from) return range.to;
|
|
46
|
+
const charAfter = view.state.doc.sliceString(range.to, range.to + 1);
|
|
47
|
+
return charAfter === " " ? range.to + 1 : range.to;
|
|
48
|
+
}
|
|
49
|
+
function buildDecorations(view) {
|
|
50
|
+
const rules = effectiveRules(view);
|
|
51
|
+
const lineDecs = [];
|
|
52
|
+
const markDecs = [];
|
|
53
|
+
const atomicBuilder = new RangeSetBuilder();
|
|
54
|
+
const tree = ensureSyntaxTree(view.state, view.viewport.to, 100) ?? syntaxTree(view.state);
|
|
55
|
+
const stampLineRange = (deco, from, to) => {
|
|
56
|
+
let pos = from;
|
|
57
|
+
while (pos <= to) {
|
|
58
|
+
const line = view.state.doc.lineAt(pos);
|
|
59
|
+
lineDecs.push(deco.range(line.from));
|
|
60
|
+
if (line.to >= to) break;
|
|
61
|
+
pos = line.to + 1;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
for (const { from, to } of view.visibleRanges) {
|
|
65
|
+
tree.iterate({
|
|
66
|
+
from,
|
|
67
|
+
to,
|
|
68
|
+
enter: (node) => {
|
|
69
|
+
const rule = rules[node.name];
|
|
70
|
+
if (!rule) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const paint = rule({
|
|
74
|
+
name: node.name,
|
|
75
|
+
from: node.from,
|
|
76
|
+
to: node.to,
|
|
77
|
+
get parentName() {
|
|
78
|
+
return node.node.parent?.name;
|
|
79
|
+
},
|
|
80
|
+
get node() {
|
|
81
|
+
return node.node;
|
|
82
|
+
},
|
|
83
|
+
state: view.state
|
|
84
|
+
});
|
|
85
|
+
switch (paint.paint) {
|
|
86
|
+
case "lineClass": {
|
|
87
|
+
if (paint.span === "first") {
|
|
88
|
+
const line = view.state.doc.lineAt(node.from);
|
|
89
|
+
lineDecs.push(lineDeco(paint.className).range(line.from));
|
|
90
|
+
} else {
|
|
91
|
+
stampLineRange(lineDeco(paint.className), node.from, node.to);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
case "mark": {
|
|
96
|
+
markDecs.push(markDeco(paint.className).range(node.from, node.to));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
case "hide": {
|
|
100
|
+
const range = paint.range ?? node;
|
|
101
|
+
const hideEnd = paint.expandSpace === false ? range.to : expandTrailingSpace(view, range);
|
|
102
|
+
markDecs.push(HIDE_MARKER.range(range.from, hideEnd));
|
|
103
|
+
atomicBuilder.add(
|
|
104
|
+
range.from,
|
|
105
|
+
Math.max(hideEnd, paint.atomicTo ?? hideEnd),
|
|
106
|
+
HIDE_MARKER
|
|
107
|
+
);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
case "widget": {
|
|
111
|
+
const hideEnd = expandTrailingSpace(view, node);
|
|
112
|
+
markDecs.push(paint.deco.range(node.from, hideEnd));
|
|
113
|
+
atomicBuilder.add(
|
|
114
|
+
node.from,
|
|
115
|
+
Math.max(hideEnd, paint.atomicTo ?? hideEnd),
|
|
116
|
+
paint.deco
|
|
117
|
+
);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
case "none":
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const all = lineDecs.concat(markDecs);
|
|
127
|
+
return {
|
|
128
|
+
decorations: Decoration.set(
|
|
129
|
+
all,
|
|
130
|
+
/* sort */
|
|
131
|
+
true
|
|
132
|
+
),
|
|
133
|
+
atomic: atomicBuilder.finish()
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const markdownDecorationsPlugin = ViewPlugin.fromClass(
|
|
137
|
+
class {
|
|
138
|
+
constructor(view) {
|
|
139
|
+
__publicField(this, "decorations");
|
|
140
|
+
__publicField(this, "atomic");
|
|
141
|
+
const built = buildDecorations(view);
|
|
142
|
+
this.decorations = built.decorations;
|
|
143
|
+
this.atomic = built.atomic;
|
|
144
|
+
}
|
|
145
|
+
update(update) {
|
|
146
|
+
if (update.docChanged || update.viewportChanged) {
|
|
147
|
+
const built = buildDecorations(update.view);
|
|
148
|
+
this.decorations = built.decorations;
|
|
149
|
+
this.atomic = built.atomic;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
decorations: (v) => v.decorations,
|
|
155
|
+
provide: (plugin) => EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomic ?? Decoration.none)
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
export {
|
|
159
|
+
markdownDecorationsPlugin
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/codemirror/core/plugin.ts"],"sourcesContent":["/**\n * Markdown decoration plugin — the PAINTER. Walks the Lezer tree against the\n * visible viewport, asks each node's {@link NodeRule} how to render, and\n * applies the returned {@link Paint}.\n *\n * The painter contains *no* construct knowledge: rules live in the base\n * table (`NODE_RULES`) merged with any extension-contributed rules\n * (`nodeRulesFacet`). The one switch here is over `Paint` — CodeMirror's\n * closed set of mechanisms — so adding a construct, widget, contextual\n * override, or whole extension never edits this file.\n *\n * Perf shape (unchanged from the spike):\n * * Walks `view.visibleRanges` against `syntaxTree(view.state)` —\n * the work is proportional to the viewport, not the document.\n * * Rebuilt on doc change or viewport change.\n *\n * Decoration ordering (CM6 requires `from`-then-`startSide` ascending):\n * * Line decorations collected in one bucket, mark / replace in\n * another. The final `Decoration.set` lets CM6 sort defensively,\n * costing ~µs on the typical viewport — cheaper than risking the\n * \"decorations out of order\" runtime error.\n */\n\nimport { ensureSyntaxTree, syntaxTree } from \"@codemirror/language\";\nimport { RangeSetBuilder, type Range } from \"@codemirror/state\";\nimport {\n Decoration,\n EditorView,\n type DecorationSet,\n ViewPlugin,\n type PluginValue,\n type ViewUpdate,\n} from \"@codemirror/view\";\n\nimport { nodeRulesFacet, type NodeLike, type NodeRules } from \"./paint\";\nimport { NODE_RULES } from \"./registry\";\n\n/* ---------------- Decoration instances ----------------- */\n//\n// Cached per `className` so we don't allocate a Decoration per node\n// per build. CM6 dedups internally, but skipping the call is cheaper.\n\nconst lineDecoCache = new Map<string, Decoration>();\nconst markDecoCache = new Map<string, Decoration>();\nconst HIDE_MARKER = Decoration.replace({});\n\nfunction lineDeco(className: string): Decoration {\n let d = lineDecoCache.get(className);\n if (!d) {\n d = Decoration.line({ class: className });\n lineDecoCache.set(className, d);\n }\n return d;\n}\n\nfunction markDeco(className: string): Decoration {\n let d = markDecoCache.get(className);\n if (!d) {\n d = Decoration.mark({ class: className });\n markDecoCache.set(className, d);\n }\n return d;\n}\n\n/* ---------------- Effective rules ---------------- */\n\n// Base + extension rules, merged once per distinct facet value (the facet\n// result is referentially stable until providers change).\nconst mergedRulesCache = new WeakMap<NodeRules, NodeRules>();\n\nfunction effectiveRules(view: EditorView): NodeRules {\n const extra = view.state.facet(nodeRulesFacet);\n if (Object.keys(extra).length === 0) return NODE_RULES;\n let merged = mergedRulesCache.get(extra);\n if (!merged) {\n merged = Object.assign({}, NODE_RULES, extra);\n mergedRulesCache.set(extra, merged);\n }\n return merged;\n}\n\n/* ---------------- The painter ---------------- */\n\ninterface BuildResult {\n decorations: DecorationSet;\n /**\n * Every hidden/replaced range, surfaced as `EditorView.atomicRanges` so\n * cursor motion (arrow keys, drag-select, double-click) treats hidden\n * markup as a single atom — the user moves \"around\" hidden `**` instead\n * of getting stranded between two invisible characters.\n */\n atomic: DecorationSet;\n}\n\n/**\n * Block-level markers (`# ` heading, `> ` quote, `- ` list item) are\n * followed by exactly one separator space; we hide that space along\n * with the marker so the rendered line starts at the first content\n * char. Inline markers (`*`, backticks) don't have this — only the\n * line-leading case applies.\n */\nfunction expandTrailingSpace(\n view: EditorView,\n range: { from: number; to: number },\n): number {\n const line = view.state.doc.lineAt(range.from);\n if (range.from !== line.from) return range.to;\n const charAfter = view.state.doc.sliceString(range.to, range.to + 1);\n return charAfter === \" \" ? range.to + 1 : range.to;\n}\n\nfunction buildDecorations(view: EditorView): BuildResult {\n const rules = effectiveRules(view);\n const lineDecs: Range<Decoration>[] = [];\n const markDecs: Range<Decoration>[] = [];\n const atomicBuilder = new RangeSetBuilder<Decoration>();\n // Force-parse through the viewport so a list/task marker stays rendered while\n // typing: the incremental tree can lag for the just-edited line on a large\n // doc, briefly dropping the widget back to raw source (#37). Bounded to the\n // viewport + a timeout, so a large note doesn't pay a full re-parse per key.\n const tree = ensureSyntaxTree(view.state, view.viewport.to, 100) ?? syntaxTree(view.state);\n\n // Stamp a Decoration.line on every line overlapping the given\n // range. CM6 requires `Decoration.line` to be anchored at a line\n // start; this helper does the line-iteration once for callers.\n const stampLineRange = (deco: Decoration, from: number, to: number) => {\n let pos = from;\n while (pos <= to) {\n const line = view.state.doc.lineAt(pos);\n lineDecs.push(deco.range(line.from));\n if (line.to >= to) break;\n pos = line.to + 1;\n }\n };\n\n for (const { from, to } of view.visibleRanges) {\n tree.iterate({\n from,\n to,\n enter: (node) => {\n const rule = rules[node.name];\n if (!rule) {\n // Unknown node — the coverage test prevents this for the base\n // grammar; an extension grammar's node without a contributed rule\n // lands here. Skip silently rather than throw: a missing rule\n // must not break editing.\n return;\n }\n // `node.node` materializes a SyntaxNode (lezer's documented-expensive\n // path); most rules are constant combinators that never read it, so\n // the context exposes it — and the parent walk — through lazy getters\n // that only pay when a contextual rule actually asks.\n const paint = rule({\n name: node.name,\n from: node.from,\n to: node.to,\n get parentName() {\n return node.node.parent?.name;\n },\n get node() {\n return node.node as unknown as NodeLike;\n },\n state: view.state,\n });\n\n switch (paint.paint) {\n case \"lineClass\": {\n if (paint.span === \"first\") {\n const line = view.state.doc.lineAt(node.from);\n lineDecs.push(lineDeco(paint.className).range(line.from));\n } else {\n stampLineRange(lineDeco(paint.className), node.from, node.to);\n }\n return;\n }\n case \"mark\": {\n markDecs.push(markDeco(paint.className).range(node.from, node.to));\n return;\n }\n case \"hide\": {\n const range = paint.range ?? node;\n const hideEnd =\n paint.expandSpace === false ? range.to : expandTrailingSpace(view, range);\n markDecs.push(HIDE_MARKER.range(range.from, hideEnd));\n atomicBuilder.add(\n range.from,\n Math.max(hideEnd, paint.atomicTo ?? hideEnd),\n HIDE_MARKER,\n );\n return;\n }\n case \"widget\": {\n const hideEnd = expandTrailingSpace(view, node);\n markDecs.push(paint.deco.range(node.from, hideEnd));\n atomicBuilder.add(\n node.from,\n Math.max(hideEnd, paint.atomicTo ?? hideEnd),\n paint.deco,\n );\n return;\n }\n case \"none\":\n return;\n }\n },\n });\n }\n\n // Line decorations before mark/replace at the same point — this is\n // the canonical CM6 ordering. Concat-then-sort is one O(n log n)\n // for the whole viewport, dwarfed by the parse cost.\n const all: Range<Decoration>[] = lineDecs.concat(markDecs);\n return {\n decorations: Decoration.set(all, /* sort */ true),\n atomic: atomicBuilder.finish(),\n };\n}\n\nexport const markdownDecorationsPlugin = ViewPlugin.fromClass(\n class implements PluginValue {\n decorations: DecorationSet;\n atomic: DecorationSet;\n constructor(view: EditorView) {\n const built = buildDecorations(view);\n this.decorations = built.decorations;\n this.atomic = built.atomic;\n }\n update(update: ViewUpdate) {\n // No decoration depends on the cursor (markers never reveal on\n // proximity), so caret-only transactions skip the whole build path.\n if (update.docChanged || update.viewportChanged) {\n const built = buildDecorations(update.view);\n this.decorations = built.decorations;\n this.atomic = built.atomic;\n }\n }\n },\n {\n decorations: (v) => v.decorations,\n provide: (plugin) =>\n EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomic ?? Decoration.none),\n },\n);\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NodeRules } from './paint.js';
|
|
2
|
+
import '@codemirror/state';
|
|
3
|
+
import '@codemirror/view';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Canonical table: every Lezer markdown node name → its {@link NodeRule} —
|
|
7
|
+
* ONE place answering "how does this construct render". The Lezer parser
|
|
8
|
+
* handles CommonMark + GFM spec compliance; this file is the visual contract.
|
|
9
|
+
*
|
|
10
|
+
* Why a table of rules (functions), not data:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Completeness is auditable.** `registry.test.ts` reads the live
|
|
13
|
+
* parser's node set and fails when any node Lezer emits has no entry
|
|
14
|
+
* here — a lezer-markdown bump that adds a node trips the gate before
|
|
15
|
+
* it ships unstyled. Only the KEYS matter for that, so entries are free
|
|
16
|
+
* to be behavior.
|
|
17
|
+
* 2. **Context is first-class.** A node name can mean different things in
|
|
18
|
+
* different parents (a URL inside `[text](url)` is chrome; a bare
|
|
19
|
+
* pasted URL is content — hiding it made an invisible dead zone).
|
|
20
|
+
* Every rule receives context; contextual entries are ordinary inline
|
|
21
|
+
* functions, readable at the point of definition.
|
|
22
|
+
* 3. **Adding a construct touches one place.** A styled span is a
|
|
23
|
+
* one-liner via the combinators; a widget construct exports its rule
|
|
24
|
+
* from its own module and is listed here; an EXTENSION with its own
|
|
25
|
+
* grammar ships rules via `nodeRulesFacet` and never touches this file.
|
|
26
|
+
* 4. **Deliberate non-styling stays documented.** `raw(why)` /
|
|
27
|
+
* `structural(why)` tag their rules; the coverage test insists the
|
|
28
|
+
* `why` is present.
|
|
29
|
+
*
|
|
30
|
+
* The rules speak {@link Paint} — CodeMirror's own mechanisms (line class,
|
|
31
|
+
* span mark, hide, widget, nothing). That union is CLOSED: constructs grow,
|
|
32
|
+
* ways to paint don't, so the single switch over Paint lives in the painter
|
|
33
|
+
* (plugin.ts) and no new construct ever edits it.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
declare const NODE_RULES: NodeRules;
|
|
37
|
+
|
|
38
|
+
export { NODE_RULES };
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import "../../chunk-V6TY7KAL.js";
|
|
2
|
+
import { horizontalRuleRule } from "./hrWidget.js";
|
|
3
|
+
import { htmlBlockRule, htmlInlineRule } from "../html/htmlWidget.js";
|
|
4
|
+
import { imageRule } from "../image/imageWidget.js";
|
|
5
|
+
import { linkHasVisibleLabel, linkResolves } from "./linkResolution.js";
|
|
6
|
+
import { listMarkRule } from "../list/bulletWidget.js";
|
|
7
|
+
import {
|
|
8
|
+
headingLine,
|
|
9
|
+
hideAlways,
|
|
10
|
+
line,
|
|
11
|
+
mark,
|
|
12
|
+
none,
|
|
13
|
+
raw,
|
|
14
|
+
structural
|
|
15
|
+
} from "./paint.js";
|
|
16
|
+
import { taskMarkerRule } from "../list/taskCheckboxWidget.js";
|
|
17
|
+
function parentLink(ctx) {
|
|
18
|
+
return ctx.parentName === "Link" ? ctx.node.parent : null;
|
|
19
|
+
}
|
|
20
|
+
const NODE_RULES = {
|
|
21
|
+
// ----- Structural wrappers (never directly styled) -----
|
|
22
|
+
Document: structural("top-level wrapper"),
|
|
23
|
+
Paragraph: structural("body font is the default"),
|
|
24
|
+
// ----- ATX headings (`# H1` … `###### H6`) -----
|
|
25
|
+
ATXHeading1: headingLine("cm-heading cm-heading--1"),
|
|
26
|
+
ATXHeading2: headingLine("cm-heading cm-heading--2"),
|
|
27
|
+
ATXHeading3: headingLine("cm-heading cm-heading--3"),
|
|
28
|
+
ATXHeading4: headingLine("cm-heading cm-heading--4"),
|
|
29
|
+
ATXHeading5: headingLine("cm-heading cm-heading--5"),
|
|
30
|
+
ATXHeading6: headingLine("cm-heading cm-heading--6"),
|
|
31
|
+
// ----- Setext headings (`=====` / `-----` under text) -----
|
|
32
|
+
SetextHeading1: raw("Phase 2: same line scaling as ATXHeading1"),
|
|
33
|
+
SetextHeading2: raw("Phase 2: same line scaling as ATXHeading2"),
|
|
34
|
+
// ----- Block-level constructs -----
|
|
35
|
+
Blockquote: line("cm-blockquote"),
|
|
36
|
+
BulletList: structural("ListItem children carry the styling"),
|
|
37
|
+
OrderedList: structural("ListItem children carry the styling"),
|
|
38
|
+
ListItem: line("cm-list-line"),
|
|
39
|
+
FencedCode: line("cm-fenced-code"),
|
|
40
|
+
CodeBlock: raw("Phase 2: indented code-block, same style as FencedCode"),
|
|
41
|
+
HorizontalRule: horizontalRuleRule,
|
|
42
|
+
// `---` → styled `<hr>` widget
|
|
43
|
+
HTMLBlock: htmlBlockRule,
|
|
44
|
+
LinkReference: raw("Phase 2: reference-style links resolve in click handler"),
|
|
45
|
+
// ----- Inline styling -----
|
|
46
|
+
Emphasis: mark("cm-emphasis"),
|
|
47
|
+
StrongEmphasis: mark("cm-strong"),
|
|
48
|
+
InlineCode: mark("cm-inline-code"),
|
|
49
|
+
// A `Link` node is not yet a link: Lezer emits one for every `[…]`, and the
|
|
50
|
+
// reference lookup CommonMark requires is left to us. Unresolved, it is the
|
|
51
|
+
// literal brackets the author typed — most `[…]` in prose, and every optional
|
|
52
|
+
// argument in a LaTeX block.
|
|
53
|
+
Link: (ctx) => linkResolves(ctx.node, ctx.state) ? { paint: "mark", className: "cm-link" } : none,
|
|
54
|
+
Image: imageRule,
|
|
55
|
+
// `` → inline `<img>` widget
|
|
56
|
+
// ----- Inline literal sub-nodes (rendered inside their parent) -----
|
|
57
|
+
// Inside a Link the URL is chrome ONLY when a visible label exists — for
|
|
58
|
+
// `[](url)` / `[ ](url)` the URL is the link's entire visible content, and
|
|
59
|
+
// hiding it (with the marks already hidden) left an invisible dead zone.
|
|
60
|
+
// Bare GFM autolinks and <angle> autolinks emit the SAME node name, and
|
|
61
|
+
// there the URL IS the content — same class of bug when hidden.
|
|
62
|
+
URL: (ctx) => {
|
|
63
|
+
const link = parentLink(ctx);
|
|
64
|
+
if (!link) return { paint: "mark", className: "cm-link" };
|
|
65
|
+
return linkHasVisibleLabel(link, ctx.state) ? { paint: "hide" } : { paint: "mark", className: "cm-link" };
|
|
66
|
+
},
|
|
67
|
+
LinkLabel: raw("visible inside Link; parent mark styles it"),
|
|
68
|
+
LinkTitle: hideAlways(),
|
|
69
|
+
// `[text](URL "title")` — title never visible
|
|
70
|
+
CodeText: raw("interior of FencedCode/InlineCode; parent decoration covers it"),
|
|
71
|
+
CodeInfo: mark("cm-code-info"),
|
|
72
|
+
// language tag on the opener row — visible so typing there is never invisible (§12.4)
|
|
73
|
+
HardBreak: structural("trailing two-spaces or backslash, no visible glyph"),
|
|
74
|
+
Comment: raw("Phase 2: dim inline HTML comments"),
|
|
75
|
+
CommentBlock: raw("Phase 2: dim block HTML comments"),
|
|
76
|
+
ProcessingInstruction: raw("Phase 2: dim like HTML comments"),
|
|
77
|
+
ProcessingInstructionBlock: raw("Phase 2: dim like HTML comments"),
|
|
78
|
+
Entity: raw("HTML entities like & render as-is, by design"),
|
|
79
|
+
// Backslash-escape: hide only the leading `\`, so `\'` renders as `'` per
|
|
80
|
+
// CommonMark rather than showing a literal backslash.
|
|
81
|
+
Escape: (ctx) => ({
|
|
82
|
+
paint: "hide",
|
|
83
|
+
range: { from: ctx.from, to: ctx.from + 1 },
|
|
84
|
+
expandSpace: false
|
|
85
|
+
}),
|
|
86
|
+
HTMLTag: htmlInlineRule,
|
|
87
|
+
// ----- Syntax markers (hidden always — non-technical UX, distinct from Obsidian's Live Preview) -----
|
|
88
|
+
// `#` marks on ATX headings hide; a SETEXT heading's underline is that
|
|
89
|
+
// heading's only marker on its own line — hiding it left an invisible,
|
|
90
|
+
// unclickable dead line. Visible until setext gets real styling.
|
|
91
|
+
HeaderMark: (ctx) => ctx.parentName?.startsWith("SetextHeading") ? { paint: "none" } : { paint: "hide" },
|
|
92
|
+
EmphasisMark: hideAlways(),
|
|
93
|
+
// `*` / `_`
|
|
94
|
+
CodeMark: hideAlways(),
|
|
95
|
+
// backticks for inline / fence pairs for blocks
|
|
96
|
+
// `[`/`]`/`(`/`)` — chrome only where they really are chrome. An unresolved
|
|
97
|
+
// link's brackets are content, and hiding them rewrote the document on screen.
|
|
98
|
+
LinkMark: (ctx) => {
|
|
99
|
+
const link = parentLink(ctx);
|
|
100
|
+
return link && !linkResolves(link, ctx.state) ? none : { paint: "hide" };
|
|
101
|
+
},
|
|
102
|
+
QuoteMark: hideAlways(),
|
|
103
|
+
// `>`
|
|
104
|
+
ListMark: listMarkRule,
|
|
105
|
+
// `-`/`1.` → bullet / number / nothing beside a checkbox
|
|
106
|
+
TaskMarker: taskMarkerRule,
|
|
107
|
+
// `[ ]` / `[x]` → real checkbox
|
|
108
|
+
// ----- GFM extensions (enabled via `markdownLanguage`) -----
|
|
109
|
+
Strikethrough: mark("cm-strikethrough"),
|
|
110
|
+
// `~~` joins the hidden-marker system like EmphasisMark — the flanking
|
|
111
|
+
// guard and delete normalizer already assume these semantics; leaving the
|
|
112
|
+
// marks visible made deletion eat single tildes (interaction-spec §8.1).
|
|
113
|
+
StrikethroughMark: hideAlways(),
|
|
114
|
+
Subscript: raw("Phase 2: vertical-align: sub"),
|
|
115
|
+
SubscriptMark: raw("Phase 2: hide `~` off-parent"),
|
|
116
|
+
Superscript: raw("Phase 2: vertical-align: super"),
|
|
117
|
+
SuperscriptMark: raw("Phase 2: hide `^` off-parent"),
|
|
118
|
+
Emoji: raw("Phase 2: replace `:smile:` with the emoji glyph"),
|
|
119
|
+
Autolink: raw("wrapper of a visible URL child; Phase 2 wires click-to-open"),
|
|
120
|
+
Task: raw("Phase 2: render task list items with a real checkbox"),
|
|
121
|
+
// GFM tables — handled by a dedicated StateField that emits the block
|
|
122
|
+
// widget on Table nodes (CM6 forbids multi-line replace from a ViewPlugin,
|
|
123
|
+
// so this rules-driven plugin can't do that shape; see tableField.ts).
|
|
124
|
+
Table: structural("tableField StateField owns Table rendering"),
|
|
125
|
+
TableHeader: structural("covered by Table widget"),
|
|
126
|
+
TableRow: structural("covered by Table widget"),
|
|
127
|
+
TableCell: structural("covered by Table widget"),
|
|
128
|
+
TableDelimiter: structural("covered by Table widget")
|
|
129
|
+
};
|
|
130
|
+
export {
|
|
131
|
+
NODE_RULES
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=registry.js.map
|