react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.2
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/README.md +54 -8
- package/ReactNativeEnrichedMarkdown.podspec +82 -73
- package/android/build.gradle +186 -1
- package/android/consumer-rules.pro +1 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +35 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -23
- package/android/src/main/baseline-prof.txt +1 -1
- package/android/src/main/cpp/jni-adapter.cpp +74 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +189 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
- package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
- package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +36 -9
- package/android/src/main/jni/CMakeLists.txt +53 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +6 -4
- package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
- package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
- package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
- package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
- package/cpp/highlight/HighlightGrammars.hpp +28 -0
- package/cpp/highlight/code_highlight_podspec.rb +211 -0
- package/cpp/highlight/gen-registry.mjs +155 -0
- package/cpp/highlight/grammar-versions.json +159 -0
- package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
- package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
- package/cpp/parser/MD4CParser.cpp +173 -61
- package/cpp/parser/MD4CParser.hpp +1 -0
- package/cpp/parser/MarkdownASTNode.hpp +2 -1
- package/cpp/wasm/ASTSerializer.cpp +2 -0
- package/cpp/wasm/build.sh +1 -0
- package/cpp/wasm/md4c_wasm.cpp +3 -1
- package/docs/ACCESSIBILITY.md +14 -2
- package/docs/API_REFERENCE.md +234 -12
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +47 -3
- package/docs/ELEMENTS_STRUCTURE.md +52 -4
- package/docs/IMAGE_CACHING.md +30 -0
- package/docs/INPUT.md +108 -11
- package/docs/LATEX_MATH.md +87 -45
- package/docs/MACOS.md +1 -1
- package/docs/MARKDOWN_STREAMING.md +27 -1
- package/docs/NATIVE_ASSETS.md +127 -0
- package/docs/RTL.md +1 -1
- package/docs/STYLES.md +46 -6
- package/docs/TESTING.md +112 -0
- package/docs/TEXT.md +16 -6
- package/docs/WEB.md +3 -1
- package/ios/EnrichedMarkdown.h +7 -0
- package/ios/EnrichedMarkdown.mm +284 -75
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +101 -73
- package/ios/attachments/ENRMImageAttachment.h +9 -0
- package/ios/attachments/ENRMImageAttachment.m +143 -40
- package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
- package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +35 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -23
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
- package/ios/input/ENRMAutoLinkDetector.h +2 -1
- package/ios/input/ENRMAutoLinkDetector.mm +79 -41
- package/ios/input/ENRMBlockEditCoordinator.h +71 -0
- package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
- package/ios/input/ENRMBlockRange.h +28 -0
- package/ios/input/ENRMBlockRange.mm +30 -0
- package/ios/input/ENRMBlockStore.h +56 -0
- package/ios/input/ENRMBlockStore.mm +275 -0
- package/ios/input/ENRMClipboardCoordinator.h +45 -0
- package/ios/input/ENRMClipboardCoordinator.mm +120 -0
- package/ios/input/ENRMDetectorPipeline.h +2 -1
- package/ios/input/ENRMEditPipeline.h +76 -0
- package/ios/input/ENRMEditPipeline.mm +228 -0
- package/ios/input/ENRMEditSession.h +36 -0
- package/ios/input/ENRMEditSession.mm +63 -0
- package/ios/input/ENRMFormattingStore.h +17 -0
- package/ios/input/ENRMFormattingStore.mm +95 -105
- package/ios/input/ENRMInputBlockType.h +91 -0
- package/ios/input/ENRMInputBlockType.mm +5 -0
- package/ios/input/ENRMInputDecorationDrawer.h +18 -0
- package/ios/input/ENRMInputEventEmitter.h +56 -0
- package/ios/input/ENRMInputEventEmitter.mm +308 -0
- package/ios/input/ENRMInputFormatter.h +29 -69
- package/ios/input/ENRMInputFormatter.mm +216 -124
- package/ios/input/ENRMInputFormatterStyle.h +99 -0
- package/ios/input/ENRMInputFormatterStyle.mm +188 -0
- package/ios/input/ENRMInputLayoutManager.h +9 -0
- package/ios/input/ENRMInputLayoutManager.mm +30 -0
- package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
- package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
- package/ios/input/ENRMInputParser.h +5 -6
- package/ios/input/ENRMInputParser.mm +461 -178
- package/ios/input/ENRMInputRemend.mm +2 -2
- package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
- package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
- package/ios/input/ENRMInputTextView.mm +103 -8
- package/ios/input/ENRMInputTypingAttributesController.h +42 -0
- package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
- package/ios/input/ENRMLinkCoordinator.h +41 -0
- package/ios/input/ENRMLinkCoordinator.mm +89 -0
- package/ios/input/ENRMMarkdownSerializer.h +29 -5
- package/ios/input/ENRMMarkdownSerializer.mm +170 -48
- package/ios/input/ENRMMathAtom.h +26 -0
- package/ios/input/ENRMMathAtom.mm +12 -0
- package/ios/input/ENRMMentionCoordinator.h +45 -0
- package/ios/input/ENRMMentionCoordinator.mm +167 -0
- package/ios/input/ENRMRangeEditAdjustment.h +38 -0
- package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
- package/ios/input/ENRMRangeStoreUtils.h +39 -0
- package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
- package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
- package/ios/input/EnrichedMarkdownTextInput.h +7 -1
- package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
- package/ios/input/InputStylePropsUtils.h +109 -68
- package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
- package/ios/input/styles/ENRMBlockHandler.h +46 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
- package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
- package/ios/internals/MeasurementCache.h +33 -7
- package/ios/internals/ShadowMeasurementUtils.h +63 -58
- package/ios/math/ENRMMathChipController.h +74 -0
- package/ios/math/ENRMMathChipController.mm +476 -0
- package/ios/math/ENRMRaTeXBridge.swift +4 -1
- package/ios/parser/ENRMMarkdownParser.h +1 -8
- package/ios/parser/ENRMMarkdownParser.mm +2 -11
- package/ios/parser/MarkdownASTNode.h +2 -1
- package/ios/parser/MarkdownParserBridge.mm +4 -0
- package/ios/renderer/AttributedRenderer.m +20 -2
- package/ios/renderer/BaseRenderer.h +17 -2
- package/ios/renderer/BaseRenderer.m +30 -0
- package/ios/renderer/BlockquoteRenderer.h +1 -1
- package/ios/renderer/BlockquoteRenderer.m +144 -35
- package/ios/renderer/CodeBlockRenderer.h +1 -1
- package/ios/renderer/CodeBlockRenderer.m +27 -23
- package/ios/renderer/CodeRenderer.h +1 -1
- package/ios/renderer/CodeRenderer.m +3 -1
- package/ios/renderer/ENRMImageRenderer.h +1 -1
- package/ios/renderer/ENRMImageRenderer.m +5 -1
- package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
- package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
- package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
- package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
- package/ios/renderer/EmphasisRenderer.h +1 -1
- package/ios/renderer/EmphasisRenderer.m +3 -1
- package/ios/renderer/HeadingRenderer.h +1 -1
- package/ios/renderer/HeadingRenderer.m +13 -6
- package/ios/renderer/HighlightRenderer.h +1 -1
- package/ios/renderer/HighlightRenderer.m +3 -1
- package/ios/renderer/LinkRenderer.h +1 -1
- package/ios/renderer/LinkRenderer.m +3 -1
- package/ios/renderer/ListItemRenderer.h +13 -1
- package/ios/renderer/ListItemRenderer.m +102 -44
- package/ios/renderer/ListRenderer.h +2 -2
- package/ios/renderer/ListRenderer.m +63 -25
- package/ios/renderer/ParagraphRenderer.h +1 -1
- package/ios/renderer/ParagraphRenderer.m +16 -8
- package/ios/renderer/RenderContext.h +10 -0
- package/ios/renderer/RenderContext.m +44 -0
- package/ios/renderer/RendererFactory.m +14 -0
- package/ios/renderer/StrikethroughRenderer.h +1 -1
- package/ios/renderer/StrikethroughRenderer.m +3 -1
- package/ios/renderer/StrongRenderer.h +1 -1
- package/ios/renderer/StrongRenderer.m +3 -1
- package/ios/renderer/SubscriptRenderer.h +1 -1
- package/ios/renderer/SubscriptRenderer.m +3 -1
- package/ios/renderer/SuperscriptRenderer.h +1 -1
- package/ios/renderer/SuperscriptRenderer.m +3 -1
- package/ios/renderer/TextRenderer.h +2 -2
- package/ios/renderer/TextRenderer.m +3 -1
- package/ios/renderer/ThematicBreakRenderer.h +1 -1
- package/ios/renderer/ThematicBreakRenderer.m +3 -1
- package/ios/renderer/UnderlineRenderer.h +1 -1
- package/ios/renderer/UnderlineRenderer.m +3 -1
- package/ios/styles/StyleConfig.h +22 -0
- package/ios/styles/StyleConfig.mm +132 -0
- package/ios/utils/BlockquoteBorder.h +6 -0
- package/ios/utils/BlockquoteBorder.m +249 -52
- package/ios/utils/CodeBlockBackground.m +16 -2
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMBlockMenu.h +57 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +79 -0
- package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
- package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
- package/ios/utils/ENRMFeatureFlags.h +7 -0
- package/ios/utils/ENRMImageDownloader.h +11 -1
- package/ios/utils/ENRMImageDownloader.m +60 -16
- package/ios/utils/ENRMLocalImageLoader.h +31 -0
- package/ios/utils/ENRMLocalImageLoader.m +68 -0
- package/ios/utils/ENRMMathFallback.h +26 -0
- package/ios/utils/ENRMMathFallback.m +18 -0
- package/ios/utils/ENRMTextViewSetup.h +35 -17
- package/ios/utils/EditMenuUtils.h +22 -5
- package/ios/utils/EditMenuUtils.m +53 -9
- package/ios/utils/ImageRequestHeaderUtils.h +35 -0
- package/ios/utils/LastElementUtils.h +1 -0
- package/ios/utils/ListMarkerDrawer.m +29 -42
- package/ios/utils/MarkdownASTSerializer.m +4 -0
- package/ios/utils/ParagraphStyleUtils.h +5 -0
- package/ios/utils/ParagraphStyleUtils.m +77 -17
- package/ios/utils/RenderedMarkdownSegment.h +13 -1
- package/ios/utils/RenderedMarkdownSegment.m +20 -0
- package/ios/utils/SegmentRenderer.m +17 -4
- package/ios/utils/StreamingMarkdownFilter.h +11 -1
- package/ios/utils/StreamingMarkdownFilter.m +98 -2
- package/ios/utils/StylePropsUtils.h +63 -0
- package/ios/utils/TaskListTapUtils.m +24 -0
- package/ios/views/ENRMCodeBlockContainerView.h +53 -0
- package/ios/views/ENRMCodeBlockContainerView.m +559 -0
- package/ios/views/ENRMMathContainerView.h +16 -0
- package/ios/views/ENRMMathContainerView.m +74 -19
- package/ios/views/TableContainerView.h +22 -0
- package/ios/views/TableContainerView.m +261 -175
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
- package/lib/module/EnrichedMarkdownTextInput.js +84 -5
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -0
- package/lib/module/headingDefaults.js +34 -0
- package/lib/module/headingDefaults.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/jest/index.js +191 -0
- package/lib/module/jest/index.js.map +1 -0
- package/lib/module/native/EnrichedMarkdownText.js +37 -5
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +81 -19
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +56 -18
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/normalizeMenuItem.js +1 -1
- package/lib/module/utils/textInputState.js +26 -0
- package/lib/module/utils/textInputState.js.map +1 -0
- package/lib/module/web/EnrichedMarkdownText.js +9 -5
- package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/web/parseMarkdown.js +4 -3
- package/lib/module/web/parseMarkdown.js.map +1 -1
- package/lib/module/web/renderers/InlineRenderers.js +6 -0
- package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
- package/lib/module/web/renderers/ListRenderers.js +7 -2
- package/lib/module/web/renderers/ListRenderers.js.map +1 -1
- package/lib/module/web/renderers/index.js +7 -4
- package/lib/module/web/renderers/index.js.map +1 -1
- package/lib/module/web/styles.js +83 -6
- package/lib/module/web/styles.js.map +1 -1
- package/lib/module/web/utils.js +1 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/module/web/wasm/md4c.js +0 -0
- package/lib/module/web/wasm/md4c.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +66 -0
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/headingDefaults.d.ts +9 -0
- package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +1 -1
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/jest/index.d.ts +6 -0
- package/lib/typescript/src/jest/index.d.ts.map +1 -0
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +104 -9
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +19 -0
- package/lib/typescript/src/types/events.d.ts.map +1 -1
- package/lib/typescript/src/utils/textInputState.d.ts +24 -0
- package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/index.d.ts +2 -1
- package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
- package/lib/typescript/src/web/styles.d.ts +2 -1
- package/lib/typescript/src/web/styles.d.ts.map +1 -1
- package/lib/typescript/src/web/types.d.ts +6 -2
- package/lib/typescript/src/web/types.d.ts.map +1 -1
- package/lib/typescript/src/web/utils.d.ts.map +1 -1
- package/package.json +36 -9
- package/postinstall.mjs +131 -0
- package/ratex-version.json +21 -0
- package/src/EnrichedMarkdownNativeComponent.ts +73 -0
- package/src/EnrichedMarkdownTextInput.tsx +159 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +74 -0
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +9 -0
- package/src/index.web.tsx +1 -0
- package/src/jest/index.tsx +215 -0
- package/src/native/EnrichedMarkdownText.tsx +53 -2
- package/src/normalizeMarkdownStyle.ts +102 -16
- package/src/normalizeMarkdownStyle.web.ts +63 -15
- package/src/normalizeMarkdownTextInputStyle.ts +110 -35
- package/src/normalizeMenuItem.ts +1 -1
- package/src/types/MarkdownStyle.ts +74 -0
- package/src/types/MarkdownStyleInternal.ts +39 -0
- package/src/types/MarkdownTextProps.ts +101 -9
- package/src/types/MarkdownTextProps.web.ts +19 -0
- package/src/types/events.ts +21 -0
- package/src/utils/textInputState.ts +35 -0
- package/src/web/EnrichedMarkdownText.tsx +16 -2
- package/src/web/parseMarkdown.ts +6 -2
- package/src/web/renderers/InlineRenderers.tsx +5 -0
- package/src/web/renderers/ListRenderers.tsx +14 -2
- package/src/web/renderers/index.tsx +6 -2
- package/src/web/styles.ts +89 -5
- package/src/web/types.ts +6 -1
- package/src/web/utils.ts +1 -0
- package/src/web/wasm/md4c.js +0 -0
- package/vendor-grammars.mjs +511 -0
- package/vendor-ratex.mjs +173 -0
- package/app.plugin.js +0 -2
- package/plugin/build/withAndroidMath.js +0 -19
- package/plugin/build/withIosMath.js +0 -28
- package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
- package/plugin/src/withAndroidMath.ts +0 -24
- package/plugin/src/withIosMath.ts +0 -35
- package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
- package/plugin/tsconfig.build.json +0 -16
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
LinkPressEvent,
|
|
6
6
|
LinkLongPressEvent,
|
|
7
7
|
TaskListItemPressEvent,
|
|
8
|
+
CopyPressEvent,
|
|
8
9
|
} from './events';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -56,22 +57,31 @@ export interface SelectionMenuPluralLabels {
|
|
|
56
57
|
* Controls the built-in items added to the native text selection menu and
|
|
57
58
|
* lets you localize their labels.
|
|
58
59
|
*
|
|
59
|
-
* Each item accepts an object: `{ enabled }` toggles visibility
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
60
|
+
* Each item accepts an object: `{ enabled }` toggles visibility and `label`
|
|
61
|
+
* overrides the English default. Wire `label` to your i18n library to match
|
|
62
|
+
* the rest of your app's UI. Items and labels apply to the main text selection
|
|
63
|
+
* menu as well as the table, math and code block copy menus.
|
|
64
|
+
*
|
|
65
|
+
* `copy.enabled`, `copy.format` and `systemItems` are ignored on macOS.
|
|
64
66
|
*
|
|
65
67
|
* @platform ios, android, macos
|
|
66
68
|
*/
|
|
67
69
|
export interface SelectionMenuConfig {
|
|
68
70
|
/**
|
|
69
|
-
* The
|
|
70
|
-
*
|
|
71
|
+
* The "Copy" item.
|
|
72
|
+
* - `enabled`: `false` removes it from the text selection menu, the table /
|
|
73
|
+
* math / code block menus and the code block VoiceOver copy action.
|
|
74
|
+
* - `format`: `'rich'` copies rich text (plain + HTML, plus RTF on iOS) from
|
|
75
|
+
* text selections and the raw content from blocks; `'markdown'` copies
|
|
76
|
+
* Markdown as plain text everywhere the item appears (inline math becomes
|
|
77
|
+
* `$…$`, math blocks `$$…$$`, code blocks are fenced). The code block header
|
|
78
|
+
* button and VoiceOver action always copy the raw code.
|
|
79
|
+
* @default { enabled: true, label: "Copy", format: "rich" }
|
|
71
80
|
*/
|
|
72
|
-
copy?: { label?: string };
|
|
81
|
+
copy?: { enabled?: boolean; label?: string; format?: 'rich' | 'markdown' };
|
|
73
82
|
/**
|
|
74
|
-
* The built-in "Copy as Markdown" action
|
|
83
|
+
* The built-in "Copy as Markdown" action, in the text selection menu and in
|
|
84
|
+
* the table / math / code block menus.
|
|
75
85
|
* @default { enabled: true, label: "Copy as Markdown" }
|
|
76
86
|
*/
|
|
77
87
|
copyAsMarkdown?: { enabled?: boolean; label?: string };
|
|
@@ -86,6 +96,23 @@ export interface SelectionMenuConfig {
|
|
|
86
96
|
label?: string;
|
|
87
97
|
pluralLabels?: SelectionMenuPluralLabels;
|
|
88
98
|
};
|
|
99
|
+
/**
|
|
100
|
+
* Which system items the text selection menu keeps.
|
|
101
|
+
* - `'default'`: keep everything the OS adds (Select All, Look Up, Share,
|
|
102
|
+
* Translate, app text actions…), with Copy replaced by the built-in one.
|
|
103
|
+
* - `'none'`: drop every system item; the menu only holds the built-in items
|
|
104
|
+
* above and `contextMenuItems`.
|
|
105
|
+
* @default 'default'
|
|
106
|
+
* @platform ios, android
|
|
107
|
+
*/
|
|
108
|
+
systemItems?: 'default' | 'none';
|
|
109
|
+
/**
|
|
110
|
+
* The copy button in the code block header. `false` hides the button; the
|
|
111
|
+
* header and language label stay.
|
|
112
|
+
* @default { enabled: true }
|
|
113
|
+
* @platform ios, android, macos
|
|
114
|
+
*/
|
|
115
|
+
codeBlockCopyButton?: { enabled?: boolean };
|
|
89
116
|
}
|
|
90
117
|
|
|
91
118
|
export interface StreamingConfig {
|
|
@@ -98,6 +125,18 @@ export interface StreamingConfig {
|
|
|
98
125
|
* @platform ios, android
|
|
99
126
|
*/
|
|
100
127
|
tableMode?: 'hidden' | 'progressive';
|
|
128
|
+
/**
|
|
129
|
+
* Controls how a fenced code block whose closing fence has not arrived yet
|
|
130
|
+
* is handled during streaming.
|
|
131
|
+
* - `'hidden'`: hide the entire code block until its closing fence arrives.
|
|
132
|
+
* - `'progressive'` (default): show the code as it streams in with its header
|
|
133
|
+
* visible but non-interactive (copying is disabled); syntax highlighting is
|
|
134
|
+
* deferred until the closing fence arrives, so it appears once atomically.
|
|
135
|
+
* Only effective when `streamingAnimation` is `true`.
|
|
136
|
+
* @default 'progressive'
|
|
137
|
+
* @platform ios, android
|
|
138
|
+
*/
|
|
139
|
+
codeBlockMode?: 'hidden' | 'progressive';
|
|
101
140
|
}
|
|
102
141
|
|
|
103
142
|
export interface EnrichedMarkdownTextProps extends Omit<ViewProps, 'style'> {
|
|
@@ -149,6 +188,31 @@ export interface EnrichedMarkdownTextProps extends Omit<ViewProps, 'style'> {
|
|
|
149
188
|
* @platform ios, android, web
|
|
150
189
|
*/
|
|
151
190
|
onTaskListItemPress?: (event: TaskListItemPressEvent) => void;
|
|
191
|
+
/**
|
|
192
|
+
* Controls whether tapping a task list checkbox toggles its checked state.
|
|
193
|
+
*
|
|
194
|
+
* When `true` (default), tapping the checkbox toggles it and fires
|
|
195
|
+
* `onTaskListItemPress`. When `false`, the checkbox renders its markdown
|
|
196
|
+
* state read-only: the tap is fully inert — no visual toggle and no
|
|
197
|
+
* `onTaskListItemPress` emission. Text selection and links in the same row
|
|
198
|
+
* are unaffected.
|
|
199
|
+
*
|
|
200
|
+
* @default true
|
|
201
|
+
* @platform ios, android, web
|
|
202
|
+
*/
|
|
203
|
+
enableTaskListItemToggle?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Callback fired when code is copied from a fenced code block, via the header
|
|
206
|
+
* copy button, the long-press context-menu "Copy" action, or the VoiceOver
|
|
207
|
+
* copy action. Receives the copied code and its language. Does not fire for
|
|
208
|
+
* "Copy as Markdown", nor for the context-menu "Copy" when
|
|
209
|
+
* `selectionMenuConfig.copy.format` is `'markdown'`.
|
|
210
|
+
*
|
|
211
|
+
* Only fires when `flavor="github"` (the copy button is part of the GitHub
|
|
212
|
+
* flavor's container-based code block renderer).
|
|
213
|
+
* @platform ios, android, macos
|
|
214
|
+
*/
|
|
215
|
+
onCopyPress?: (event: CopyPressEvent) => void;
|
|
152
216
|
/**
|
|
153
217
|
* Controls whether the system link preview is shown on long press (iOS only).
|
|
154
218
|
*
|
|
@@ -254,6 +318,34 @@ export interface EnrichedMarkdownTextProps extends Omit<ViewProps, 'style'> {
|
|
|
254
318
|
* @platform ios, android
|
|
255
319
|
*/
|
|
256
320
|
contextMenuItems?: ContextMenuItem[];
|
|
321
|
+
/**
|
|
322
|
+
* HTTP headers to attach to remote image requests, e.g. a `Referer`
|
|
323
|
+
* required by CDN hotlink protection or an `Authorization` token.
|
|
324
|
+
*
|
|
325
|
+
* Headers participate in image cache identity, so the same URL requested
|
|
326
|
+
* with different headers is fetched and cached separately.
|
|
327
|
+
*
|
|
328
|
+
* Not supported on web — browsers don't allow custom headers on `<img>`
|
|
329
|
+
* requests.
|
|
330
|
+
* @platform ios, android
|
|
331
|
+
*/
|
|
332
|
+
imageRequestHeaders?: Record<string, string>;
|
|
333
|
+
/**
|
|
334
|
+
* Hides the text selection context menu. Text stays selectable (and stays
|
|
335
|
+
* reachable by TalkBack / VoiceOver) — only the menu is suppressed. Use
|
|
336
|
+
* `selectable={false}` instead if you want to disable selection itself.
|
|
337
|
+
*
|
|
338
|
+
* This hides the whole menu, including the custom items from
|
|
339
|
+
* `contextMenuItems` and the built-in items from `selectionMenuConfig`,
|
|
340
|
+
* since they all share one menu. It also covers the copy menus on table,
|
|
341
|
+
* math and code blocks.
|
|
342
|
+
*
|
|
343
|
+
* It does not suppress the system "Save to Camera Roll / Copy" sheet that
|
|
344
|
+
* UIKit shows when long-pressing an image.
|
|
345
|
+
* @default false
|
|
346
|
+
* @platform ios, android, macos
|
|
347
|
+
*/
|
|
348
|
+
contextMenuHidden?: boolean;
|
|
257
349
|
/**
|
|
258
350
|
* Controls the built-in items added to the native text selection menu and
|
|
259
351
|
* lets you localize their labels. Custom app-provided actions are controlled
|
|
@@ -58,6 +58,25 @@ export interface EnrichedMarkdownTextProps extends Omit<
|
|
|
58
58
|
* @platform ios, android, web
|
|
59
59
|
*/
|
|
60
60
|
onTaskListItemPress?: (event: TaskListItemPressEvent) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Controls whether tapping a task list checkbox toggles its checked state.
|
|
63
|
+
*
|
|
64
|
+
* When `true` (default), tapping the checkbox toggles it and fires
|
|
65
|
+
* `onTaskListItemPress`. When `false`, the checkbox renders its markdown
|
|
66
|
+
* state read-only: the tap is fully inert — no visual toggle and no
|
|
67
|
+
* `onTaskListItemPress` emission. Text selection and links in the same row
|
|
68
|
+
* are unaffected.
|
|
69
|
+
*
|
|
70
|
+
* On web the checkbox keeps its normal appearance and is marked
|
|
71
|
+
* `readOnly` / `aria-disabled` rather than `disabled`, so it stays visually
|
|
72
|
+
* consistent with iOS and Android. It is also made pointer-inert
|
|
73
|
+
* (`pointer-events: none`) so the browser cannot paint hover or active
|
|
74
|
+
* states on a checkbox that cannot be toggled.
|
|
75
|
+
*
|
|
76
|
+
* @default true
|
|
77
|
+
* @platform ios, android, web
|
|
78
|
+
*/
|
|
79
|
+
enableTaskListItemToggle?: boolean;
|
|
61
80
|
/**
|
|
62
81
|
* Controls text selection.
|
|
63
82
|
* - iOS: Controls text selection and link previews on long press.
|
package/src/types/events.ts
CHANGED
|
@@ -12,6 +12,11 @@ export interface TaskListItemPressEvent {
|
|
|
12
12
|
text: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export interface CopyPressEvent {
|
|
16
|
+
code: string;
|
|
17
|
+
language: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
/**
|
|
16
21
|
* Native-level context menu item config sent to the native component.
|
|
17
22
|
* Does not include the `onPress` callback — callbacks are managed on the JS side.
|
|
@@ -30,3 +35,19 @@ export interface OnContextMenuItemPressEvent {
|
|
|
30
35
|
selectionStart: number;
|
|
31
36
|
selectionEnd: number;
|
|
32
37
|
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Event payload fired by the native component when the user pastes while
|
|
41
|
+
* `interceptPaste` is on. Native does not touch the buffer — it only reports
|
|
42
|
+
* what the clipboard held. The handler must call `resolvePaste` exactly once,
|
|
43
|
+
* or the paste is dropped.
|
|
44
|
+
*/
|
|
45
|
+
export interface OnPasteEvent {
|
|
46
|
+
/** Plain text from the clipboard, verbatim, before the text view sees it. */
|
|
47
|
+
text: string;
|
|
48
|
+
/**
|
|
49
|
+
* Markdown flavor, set only when the copy source was an input of this
|
|
50
|
+
* component. iOS-only; Android always reports `''`.
|
|
51
|
+
*/
|
|
52
|
+
markdown: string;
|
|
53
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridges EnrichedMarkdownTextInput into React Native's TextInputState focus
|
|
3
|
+
* registry so it participates in RN's keyboard-dismiss behavior (issue #577).
|
|
4
|
+
*
|
|
5
|
+
* Registering a non-TextInput host component is safe: TextInputState's
|
|
6
|
+
* blurTextInput dispatches the built-in TextInput's "blur" command at the
|
|
7
|
+
* registered instance, and Fabric command dispatch is name-based — it works
|
|
8
|
+
* as long as the component ships a command with that name, which ours does.
|
|
9
|
+
*
|
|
10
|
+
* A deep import is required because the public TextInput.State API lacks the
|
|
11
|
+
* registerInput/focusInput/blurInput bookkeeping functions.
|
|
12
|
+
*/
|
|
13
|
+
import type { HostInstance } from 'react-native';
|
|
14
|
+
|
|
15
|
+
interface TextInputStateModule {
|
|
16
|
+
registerInput(input: HostInstance): void;
|
|
17
|
+
unregisterInput(input: HostInstance): void;
|
|
18
|
+
focusInput(input: HostInstance | null): void;
|
|
19
|
+
blurInput(input: HostInstance | null): void;
|
|
20
|
+
blurTextInput(input: HostInstance | null): void;
|
|
21
|
+
currentlyFocusedInput(): HostInstance | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The internal module's export shape has changed across RN versions: newer
|
|
26
|
+
* versions use `export default` (surfacing as `.default` after Metro's CJS
|
|
27
|
+
* transform) while older ones assigned `module.exports` directly. A raw
|
|
28
|
+
* require bypasses Babel's import interop, so both shapes are handled here.
|
|
29
|
+
*/
|
|
30
|
+
const TextInputStateModuleImpl =
|
|
31
|
+
// eslint-disable-next-line @react-native/no-deep-imports
|
|
32
|
+
require('react-native/Libraries/Components/TextInput/TextInputState');
|
|
33
|
+
|
|
34
|
+
export const TextInputState = (TextInputStateModuleImpl.default ??
|
|
35
|
+
TextInputStateModuleImpl) as TextInputStateModule;
|
|
@@ -21,6 +21,7 @@ export const EnrichedMarkdownText = ({
|
|
|
21
21
|
onLinkPress,
|
|
22
22
|
onLinkLongPress,
|
|
23
23
|
onTaskListItemPress,
|
|
24
|
+
enableTaskListItemToggle = true,
|
|
24
25
|
allowTrailingMargin = false,
|
|
25
26
|
containerStyle,
|
|
26
27
|
selectable = true,
|
|
@@ -43,6 +44,7 @@ export const EnrichedMarkdownText = ({
|
|
|
43
44
|
superscript = false,
|
|
44
45
|
subscript = false,
|
|
45
46
|
highlight = false,
|
|
47
|
+
hardSoftBreaks = false,
|
|
46
48
|
} = md4cFlags;
|
|
47
49
|
|
|
48
50
|
useEffect(() => {
|
|
@@ -57,6 +59,7 @@ export const EnrichedMarkdownText = ({
|
|
|
57
59
|
superscript,
|
|
58
60
|
subscript,
|
|
59
61
|
highlight,
|
|
62
|
+
hardSoftBreaks,
|
|
60
63
|
}),
|
|
61
64
|
katexPromise,
|
|
62
65
|
])
|
|
@@ -85,14 +88,25 @@ export const EnrichedMarkdownText = ({
|
|
|
85
88
|
return () => {
|
|
86
89
|
cancelled = true;
|
|
87
90
|
};
|
|
88
|
-
}, [
|
|
91
|
+
}, [
|
|
92
|
+
markdown,
|
|
93
|
+
underline,
|
|
94
|
+
latexMath,
|
|
95
|
+
superscript,
|
|
96
|
+
subscript,
|
|
97
|
+
highlight,
|
|
98
|
+
hardSoftBreaks,
|
|
99
|
+
]);
|
|
89
100
|
|
|
90
101
|
const callbacks = useMemo<RendererCallbacks>(
|
|
91
102
|
() => ({ onLinkPress, onLinkLongPress, onTaskListItemPress }),
|
|
92
103
|
[onLinkPress, onLinkLongPress, onTaskListItemPress]
|
|
93
104
|
);
|
|
94
105
|
|
|
95
|
-
const capabilities = useMemo<RenderCapabilities>(
|
|
106
|
+
const capabilities = useMemo<RenderCapabilities>(
|
|
107
|
+
() => ({ katex, enableTaskListItemToggle }),
|
|
108
|
+
[katex, enableTaskListItemToggle]
|
|
109
|
+
);
|
|
96
110
|
|
|
97
111
|
const lastChildStyle = useMemo(
|
|
98
112
|
() =>
|
package/src/web/parseMarkdown.ts
CHANGED
|
@@ -7,7 +7,8 @@ type ParseFn = (
|
|
|
7
7
|
latexMath: number,
|
|
8
8
|
superscript: number,
|
|
9
9
|
subscript: number,
|
|
10
|
-
highlight: number
|
|
10
|
+
highlight: number,
|
|
11
|
+
hardSoftBreaks: number
|
|
11
12
|
) => string;
|
|
12
13
|
|
|
13
14
|
// Caching the Promise (not the resolved value) means concurrent callers share
|
|
@@ -28,6 +29,7 @@ function initializeParser(): Promise<ParseFn> {
|
|
|
28
29
|
'number',
|
|
29
30
|
'number',
|
|
30
31
|
'number',
|
|
32
|
+
'number',
|
|
31
33
|
])
|
|
32
34
|
)
|
|
33
35
|
.catch((error) => {
|
|
@@ -55,6 +57,7 @@ export async function parseMarkdown(
|
|
|
55
57
|
superscript = false,
|
|
56
58
|
subscript = false,
|
|
57
59
|
highlight = false,
|
|
60
|
+
hardSoftBreaks = false,
|
|
58
61
|
}: Md4cFlags = {}
|
|
59
62
|
): Promise<ASTNode> {
|
|
60
63
|
const parse = await initializeParser();
|
|
@@ -66,7 +69,8 @@ export async function parseMarkdown(
|
|
|
66
69
|
latexMath ? 1 : 0,
|
|
67
70
|
superscript ? 1 : 0,
|
|
68
71
|
subscript ? 1 : 0,
|
|
69
|
-
highlight ? 1 : 0
|
|
72
|
+
highlight ? 1 : 0,
|
|
73
|
+
hardSoftBreaks ? 1 : 0
|
|
70
74
|
)
|
|
71
75
|
);
|
|
72
76
|
|
|
@@ -12,6 +12,10 @@ function LineBreakRenderer(_props: RendererProps) {
|
|
|
12
12
|
return <br />;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function SoftBreakRenderer(_props: RendererProps) {
|
|
16
|
+
return <> </>;
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
function StrongRenderer({ node, styles, renderChildren }: RendererProps) {
|
|
16
20
|
return <strong style={styles.strong}>{renderChildren(node)}</strong>;
|
|
17
21
|
}
|
|
@@ -108,6 +112,7 @@ function LatexMathInlineRenderer({
|
|
|
108
112
|
export const inlineRenderers: RendererMap = {
|
|
109
113
|
Text: TextRenderer,
|
|
110
114
|
LineBreak: LineBreakRenderer,
|
|
115
|
+
SoftBreak: SoftBreakRenderer,
|
|
111
116
|
Strong: StrongRenderer,
|
|
112
117
|
Emphasis: EmphasisRenderer,
|
|
113
118
|
Strikethrough: StrikethroughRenderer,
|
|
@@ -44,7 +44,9 @@ function ListItemRenderer({
|
|
|
44
44
|
node,
|
|
45
45
|
style,
|
|
46
46
|
styles,
|
|
47
|
+
index,
|
|
47
48
|
callbacks,
|
|
49
|
+
capabilities,
|
|
48
50
|
renderChildren,
|
|
49
51
|
}: RendererProps) {
|
|
50
52
|
const isTask = node.attributes?.isTask === 'true';
|
|
@@ -57,6 +59,8 @@ function ListItemRenderer({
|
|
|
57
59
|
}, [initialChecked]);
|
|
58
60
|
|
|
59
61
|
const handleChange = () => {
|
|
62
|
+
if (!capabilities.enableTaskListItemToggle) return;
|
|
63
|
+
|
|
60
64
|
const taskIndex = node.attributes?.taskIndex;
|
|
61
65
|
if (taskIndex === undefined) return;
|
|
62
66
|
|
|
@@ -85,14 +89,22 @@ function ListItemRenderer({
|
|
|
85
89
|
: null;
|
|
86
90
|
|
|
87
91
|
return (
|
|
88
|
-
<li style={listItemStyle(isTask)}>
|
|
92
|
+
<li style={listItemStyle(style, isTask, (index ?? 0) === 0)}>
|
|
89
93
|
<span style={checkedStyle}>
|
|
90
94
|
{isTask && (
|
|
91
95
|
<input
|
|
92
96
|
type="checkbox"
|
|
93
97
|
checked={isChecked}
|
|
94
98
|
onChange={handleChange}
|
|
95
|
-
|
|
99
|
+
readOnly={!capabilities.enableTaskListItemToggle}
|
|
100
|
+
aria-disabled={
|
|
101
|
+
capabilities.enableTaskListItemToggle ? undefined : true
|
|
102
|
+
}
|
|
103
|
+
style={
|
|
104
|
+
capabilities.enableTaskListItemToggle
|
|
105
|
+
? styles.taskCheckbox
|
|
106
|
+
: styles.taskCheckboxDisabled
|
|
107
|
+
}
|
|
96
108
|
aria-label={`Task: ${taskText}`}
|
|
97
109
|
/>
|
|
98
110
|
)}
|
|
@@ -35,6 +35,7 @@ export interface RenderNodeProps {
|
|
|
35
35
|
callbacks: RendererCallbacks;
|
|
36
36
|
capabilities: RenderCapabilities;
|
|
37
37
|
parentType?: NodeType;
|
|
38
|
+
index?: number;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
export function RenderNode({
|
|
@@ -44,20 +45,22 @@ export function RenderNode({
|
|
|
44
45
|
callbacks,
|
|
45
46
|
capabilities,
|
|
46
47
|
parentType,
|
|
48
|
+
index,
|
|
47
49
|
}: RenderNodeProps): ReactNode {
|
|
48
50
|
const Renderer = RENDERERS[node.type];
|
|
49
51
|
if (!Renderer) return null;
|
|
50
52
|
|
|
51
53
|
const renderChildren = (childNode: ASTNode): ReactNode =>
|
|
52
|
-
childNode.children?.map((child,
|
|
54
|
+
childNode.children?.map((child, childIndex) => (
|
|
53
55
|
<RenderNode
|
|
54
|
-
key={nodeKey(child,
|
|
56
|
+
key={nodeKey(child, childIndex)}
|
|
55
57
|
node={child}
|
|
56
58
|
style={style}
|
|
57
59
|
styles={styles}
|
|
58
60
|
callbacks={callbacks}
|
|
59
61
|
capabilities={capabilities}
|
|
60
62
|
parentType={childNode.type}
|
|
63
|
+
index={childIndex}
|
|
61
64
|
/>
|
|
62
65
|
)) ?? null;
|
|
63
66
|
|
|
@@ -67,6 +70,7 @@ export function RenderNode({
|
|
|
67
70
|
style={style}
|
|
68
71
|
styles={styles}
|
|
69
72
|
parentType={parentType}
|
|
73
|
+
index={index}
|
|
70
74
|
callbacks={callbacks}
|
|
71
75
|
capabilities={capabilities}
|
|
72
76
|
renderChildren={renderChildren}
|
package/src/web/styles.ts
CHANGED
|
@@ -126,7 +126,11 @@ function blockquoteStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
|
126
126
|
marginInlineStart: 0, // reset UA default (40px in LTR, auto in RTL)
|
|
127
127
|
marginInlineEnd: 0,
|
|
128
128
|
paddingInlineStart: blockquote.gapWidth,
|
|
129
|
+
paddingInlineEnd: blockquote.padding,
|
|
130
|
+
paddingTop: blockquote.padding,
|
|
131
|
+
paddingBottom: blockquote.padding,
|
|
129
132
|
borderInlineStart: `${blockquote.borderWidth}px solid ${blockquote.borderColor}`,
|
|
133
|
+
borderRadius: blockquote.borderRadius,
|
|
130
134
|
backgroundColor: blockquote.backgroundColor,
|
|
131
135
|
};
|
|
132
136
|
}
|
|
@@ -180,16 +184,55 @@ function thematicBreakStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
|
180
184
|
};
|
|
181
185
|
}
|
|
182
186
|
|
|
187
|
+
const RESIZE_MODE_TO_OBJECT_FIT: Record<
|
|
188
|
+
Exclude<MarkdownStyleInternal['image']['resizeMode'], ''>,
|
|
189
|
+
NonNullable<CSSProperties['objectFit']>
|
|
190
|
+
> = {
|
|
191
|
+
contain: 'contain',
|
|
192
|
+
cover: 'cover',
|
|
193
|
+
stretch: 'fill',
|
|
194
|
+
center: 'scale-down',
|
|
195
|
+
none: 'none',
|
|
196
|
+
};
|
|
197
|
+
|
|
183
198
|
function imageStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
184
199
|
const image = style.image;
|
|
185
|
-
|
|
186
|
-
height: image.height,
|
|
200
|
+
const base: CSSProperties = {
|
|
187
201
|
borderRadius: image.borderRadius,
|
|
188
202
|
marginTop: image.marginTop,
|
|
189
203
|
marginBottom: image.marginBottom,
|
|
190
204
|
maxWidth: '100%',
|
|
191
205
|
display: 'block',
|
|
192
206
|
};
|
|
207
|
+
|
|
208
|
+
// Sizing precedence: aspectRatio > maxHeight > height. resizeMode '' means
|
|
209
|
+
// legacy sizing — emit today's exact CSS for backward compatibility.
|
|
210
|
+
if (image.resizeMode === '') {
|
|
211
|
+
return { ...base, height: image.height };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const objectFit = RESIZE_MODE_TO_OBJECT_FIT[image.resizeMode] ?? 'cover';
|
|
215
|
+
|
|
216
|
+
if (image.aspectRatio > 0) {
|
|
217
|
+
return {
|
|
218
|
+
...base,
|
|
219
|
+
width: '100%',
|
|
220
|
+
aspectRatio: image.aspectRatio,
|
|
221
|
+
objectFit,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (image.maxHeight > 0) {
|
|
226
|
+
return {
|
|
227
|
+
...base,
|
|
228
|
+
width: '100%',
|
|
229
|
+
height: 'auto',
|
|
230
|
+
maxHeight: image.maxHeight,
|
|
231
|
+
objectFit,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return { ...base, width: '100%', height: image.height, objectFit };
|
|
193
236
|
}
|
|
194
237
|
|
|
195
238
|
function inlineImageStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
@@ -368,8 +411,17 @@ function tableStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
|
368
411
|
};
|
|
369
412
|
}
|
|
370
413
|
|
|
371
|
-
export function listItemStyle(
|
|
372
|
-
|
|
414
|
+
export function listItemStyle(
|
|
415
|
+
style: MarkdownStyleInternal,
|
|
416
|
+
isTask: boolean,
|
|
417
|
+
isFirstChild: boolean
|
|
418
|
+
): CSSProperties | undefined {
|
|
419
|
+
const { itemSpacing } = style.list;
|
|
420
|
+
const marginTop = !isFirstChild && itemSpacing > 0 ? itemSpacing : undefined;
|
|
421
|
+
if (isTask) {
|
|
422
|
+
return { listStyle: 'none', marginTop };
|
|
423
|
+
}
|
|
424
|
+
return marginTop !== undefined ? { marginTop } : undefined;
|
|
373
425
|
}
|
|
374
426
|
|
|
375
427
|
export function checkedTaskTextStyle(
|
|
@@ -384,6 +436,21 @@ export function checkedTaskTextStyle(
|
|
|
384
436
|
};
|
|
385
437
|
}
|
|
386
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Checkbox style used when `enableTaskListItemToggle` is `false`. Pointer-inert
|
|
441
|
+
* so the browser paints no hover/active state on a checkbox that cannot be
|
|
442
|
+
* toggled; appearance is otherwise identical to the enabled checkbox.
|
|
443
|
+
*/
|
|
444
|
+
function taskCheckboxDisabledStyle(
|
|
445
|
+
style: MarkdownStyleInternal
|
|
446
|
+
): CSSProperties {
|
|
447
|
+
return {
|
|
448
|
+
...taskCheckboxStyle(style),
|
|
449
|
+
pointerEvents: 'none',
|
|
450
|
+
cursor: 'default',
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
387
454
|
function taskCheckboxStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
388
455
|
const taskList = style.taskList;
|
|
389
456
|
return {
|
|
@@ -411,11 +478,20 @@ export function tableBodyRowStyle(
|
|
|
411
478
|
|
|
412
479
|
function tableWrapperStyle(style: MarkdownStyleInternal): CSSProperties {
|
|
413
480
|
const table = style.table;
|
|
481
|
+
const alignment: CSSProperties = table.align
|
|
482
|
+
? {
|
|
483
|
+
width: 'fit-content',
|
|
484
|
+
maxWidth: '100%',
|
|
485
|
+
marginLeft: table.align === 'left' ? 0 : 'auto',
|
|
486
|
+
marginRight: table.align === 'right' ? 0 : 'auto',
|
|
487
|
+
}
|
|
488
|
+
: {};
|
|
414
489
|
return {
|
|
415
490
|
overflowX: 'auto',
|
|
416
491
|
overflowY: 'hidden',
|
|
417
492
|
marginTop: table.marginTop,
|
|
418
493
|
marginBottom: table.marginBottom,
|
|
494
|
+
...alignment,
|
|
419
495
|
// borderRadius must live on the wrapper, not the <table> — border-collapse:
|
|
420
496
|
// collapse causes browsers to ignore border-radius on the table element itself.
|
|
421
497
|
borderRadius: table.borderRadius,
|
|
@@ -491,6 +567,7 @@ export interface Styles {
|
|
|
491
567
|
tableHeaderCell: Record<ColumnAlign, CSSProperties>;
|
|
492
568
|
tableCell: Record<ColumnAlign, CSSProperties>;
|
|
493
569
|
taskCheckbox: CSSProperties;
|
|
570
|
+
taskCheckboxDisabled: CSSProperties;
|
|
494
571
|
}
|
|
495
572
|
|
|
496
573
|
type ColumnAlign = 'left' | 'center' | 'right' | 'default';
|
|
@@ -513,7 +590,13 @@ export function buildStyles(style: MarkdownStyleInternal): Styles {
|
|
|
513
590
|
h6: headingStyle(style, '6'),
|
|
514
591
|
blockquote: blockquoteStyle(style),
|
|
515
592
|
list: listStyle(style),
|
|
516
|
-
listNested: {
|
|
593
|
+
listNested: {
|
|
594
|
+
...listStyle(style),
|
|
595
|
+
// A nested list sits directly under its parent item's text; itemSpacing
|
|
596
|
+
// (not the list's outer margins) controls that gap, like on native.
|
|
597
|
+
marginTop: Math.max(0, style.list.itemSpacing),
|
|
598
|
+
marginBottom: 0,
|
|
599
|
+
},
|
|
517
600
|
listTask: listStyle(style, true),
|
|
518
601
|
codeBlock,
|
|
519
602
|
codeBlockFont: { fontFamily: codeBlock.fontFamily },
|
|
@@ -546,6 +629,7 @@ export function buildStyles(style: MarkdownStyleInternal): Styles {
|
|
|
546
629
|
default: tableCellStyle(style, 'default'),
|
|
547
630
|
},
|
|
548
631
|
taskCheckbox: taskCheckboxStyle(style),
|
|
632
|
+
taskCheckboxDisabled: taskCheckboxDisabledStyle(style),
|
|
549
633
|
};
|
|
550
634
|
|
|
551
635
|
stylesStore.set(style, result);
|
package/src/web/types.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type NodeType =
|
|
|
15
15
|
| 'Link'
|
|
16
16
|
| 'Heading'
|
|
17
17
|
| 'LineBreak'
|
|
18
|
+
| 'SoftBreak'
|
|
18
19
|
| 'Strong'
|
|
19
20
|
| 'Emphasis'
|
|
20
21
|
| 'Strikethrough'
|
|
@@ -63,7 +64,7 @@ export interface ASTNode {
|
|
|
63
64
|
content?: string;
|
|
64
65
|
/** Present on nodes that carry structural metadata (Heading, Link, etc.). */
|
|
65
66
|
attributes?: NodeAttributes;
|
|
66
|
-
/** Child nodes; absent on leaf nodes (Text, LineBreak, ThematicBreak). */
|
|
67
|
+
/** Child nodes; absent on leaf nodes (Text, LineBreak, SoftBreak, ThematicBreak). */
|
|
67
68
|
children?: ASTNode[];
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -75,6 +76,8 @@ export interface RendererCallbacks {
|
|
|
75
76
|
|
|
76
77
|
export interface RenderCapabilities {
|
|
77
78
|
katex: KaTeXInstance | null;
|
|
79
|
+
/** When false, task list checkboxes render read-only and ignore clicks. */
|
|
80
|
+
enableTaskListItemToggle: boolean;
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
export interface RendererProps {
|
|
@@ -82,6 +85,8 @@ export interface RendererProps {
|
|
|
82
85
|
style: MarkdownStyleInternal;
|
|
83
86
|
styles: Styles;
|
|
84
87
|
parentType?: NodeType;
|
|
88
|
+
/** Position among the parent node's children. */
|
|
89
|
+
index?: number;
|
|
85
90
|
callbacks: RendererCallbacks;
|
|
86
91
|
capabilities: RenderCapabilities;
|
|
87
92
|
renderChildren: (node: ASTNode) => ReactNode;
|
package/src/web/utils.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ASTNode } from './types';
|
|
|
2
2
|
|
|
3
3
|
/** Recursively collects plain text content from an AST node's subtree. */
|
|
4
4
|
export function extractNodeText(node: ASTNode): string {
|
|
5
|
+
if (node.type === 'SoftBreak' || node.type === 'LineBreak') return ' ';
|
|
5
6
|
if (node.content !== undefined) return node.content;
|
|
6
7
|
return node.children?.map(extractNodeText).join('') ?? '';
|
|
7
8
|
}
|
package/src/web/wasm/md4c.js
CHANGED
|
Binary file
|