react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.1
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 +838 -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 +175 -11
- 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 +33 -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 +19 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +388 -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 +32 -5
- 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 +2 -0
- 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 +222 -8
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +21 -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 +262 -67
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +97 -68
- 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 +838 -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/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.m +22 -1
- 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 +46 -0
- package/ios/views/ENRMCodeBlockContainerView.m +566 -0
- package/ios/views/ENRMMathContainerView.h +12 -0
- package/ios/views/ENRMMathContainerView.m +71 -1
- package/ios/views/TableContainerView.h +18 -0
- package/ios/views/TableContainerView.m +259 -159
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +65 -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 +66 -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 +30 -4
- 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 +62 -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 +62 -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 +65 -1
- 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 +65 -0
- package/src/EnrichedMarkdownTextInput.tsx +159 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +66 -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 +40 -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 +65 -0
- 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
package/docs/COPY_OPTIONS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Copy Options
|
|
2
2
|
|
|
3
|
-
When text is selected, `react-native-enriched-markdown` provides enhanced copy functionality through the context menu on both platforms.
|
|
3
|
+
When text is selected, `react-native-enriched-markdown-scaffold` provides enhanced copy functionality through the context menu on both platforms.
|
|
4
4
|
|
|
5
5
|
## Smart Copy
|
|
6
6
|
|
|
@@ -44,6 +44,19 @@ Use `selectionMenuConfig` to hide built-in selection menu actions while keeping
|
|
|
44
44
|
/>
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
To turn the menu off entirely rather than item by item, use `contextMenuHidden`:
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
// No selection menu at all — text is still selectable
|
|
51
|
+
<EnrichedMarkdownText markdown={content} contextMenuHidden />
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The two are complementary: `selectionMenuConfig` prunes individual built-in
|
|
55
|
+
items and leaves the menu in place, while `contextMenuHidden` suppresses the
|
|
56
|
+
menu as a whole — including `contextMenuItems` and the copy menus on table,
|
|
57
|
+
code and math blocks. Note that `contextMenuHidden` applies to `EnrichedMarkdownText`
|
|
58
|
+
only; it does not affect `EnrichedMarkdownTextInput`.
|
|
59
|
+
|
|
47
60
|
`EnrichedMarkdownTextInput` supports the same `{ enabled, label }` shape. In addition to `copyAsMarkdown`, the input's `selectionMenuConfig` exposes the built-in **Format** submenu, and `formatMenuConfig` controls the items inside it:
|
|
48
61
|
|
|
49
62
|
```tsx
|
|
@@ -93,8 +106,13 @@ Notes:
|
|
|
93
106
|
plural category (`zero`, `one`, `two`, `few`, `many`, `other`). Only `other` is
|
|
94
107
|
required; any category left `undefined` falls back to it. The `{count}` token
|
|
95
108
|
is replaced by the number of selected images.
|
|
96
|
-
- The labels apply to the main text selection menu as well as the table
|
|
97
|
-
block copy menus.
|
|
109
|
+
- The labels apply to the main text selection menu as well as the table, math,
|
|
110
|
+
and code block copy menus. With `flavor="github"`, the code block header's copy
|
|
111
|
+
button also reuses the copy label for assistive technologies (the CommonMark
|
|
112
|
+
flavor renders code inline with no header button): it is the button's
|
|
113
|
+
contentDescription on Android, and on iOS it names the VoiceOver custom
|
|
114
|
+
action that triggers the copy. To be notified when code is copied from a code
|
|
115
|
+
block, use the [`onCopyPress`](./API_REFERENCE.md#oncopypress) callback.
|
|
98
116
|
- OS-provided actions (Look Up, Translate…) and the system **Cut / Paste /
|
|
99
117
|
Select All** items are localized by the platform and are not affected by this
|
|
100
118
|
config.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Element Structure
|
|
2
2
|
|
|
3
|
-
Markdown elements in `react-native-enriched-markdown` are organized into block and inline categories, each with distinct rendering behaviors.
|
|
3
|
+
Markdown elements in `react-native-enriched-markdown-scaffold` are organized into block and inline categories, each with distinct rendering behaviors.
|
|
4
4
|
|
|
5
5
|
## Supported Markdown Elements
|
|
6
6
|
|
|
7
|
-
`react-native-enriched-markdown` supports a comprehensive set of Markdown elements:
|
|
7
|
+
`react-native-enriched-markdown-scaffold` supports a comprehensive set of Markdown elements:
|
|
8
8
|
|
|
9
9
|
### Block Elements
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@ Markdown elements in `react-native-enriched-markdown` are organized into block a
|
|
|
13
13
|
| Headings | `# H1` to `###### H6` | `h1` - `h6` | Six levels of headings |
|
|
14
14
|
| Paragraphs | Plain text | `paragraph` | Default text container |
|
|
15
15
|
| Blockquotes | `> Quote` | `blockquote` | Quoted content with accent bar, unlimited nesting |
|
|
16
|
-
| Code Blocks | ` ``` code ``` ` | `codeBlock` | Multi-line code containers |
|
|
16
|
+
| Code Blocks | ` ``` code ``` ` | `codeBlock` | Multi-line code containers; with `flavor="github"` rendered as a block component with a language header and copy-code button |
|
|
17
17
|
| Unordered Lists | `- Item`, `* Item`, or `+ Item` | `list` | Bullet lists with unlimited nesting |
|
|
18
18
|
| Ordered Lists | `1. Item` | `list` | Numbered lists with unlimited nesting |
|
|
19
19
|
| Task Lists | `- [x] Done`, `- [ ] Todo` | `taskList` | Interactive checkboxes (requires `flavor="github"`) |
|
|
@@ -60,6 +60,22 @@ Markdown elements in `react-native-enriched-markdown` are organized into block a
|
|
|
60
60
|
2. Second item
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
### Lists with Block Content Example
|
|
64
|
+
|
|
65
|
+
List items can contain block elements — fenced code blocks, nested lists, and multiple paragraphs:
|
|
66
|
+
|
|
67
|
+
````markdown
|
|
68
|
+
1. Install via npm:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
npm install
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
2. Verify the connection.
|
|
75
|
+
````
|
|
76
|
+
|
|
77
|
+
Code blocks indent to the item's content column, and the marker is drawn next to the first line even when a code block or nested list is the item's first child.
|
|
78
|
+
|
|
63
79
|
### Nested Blockquotes Example
|
|
64
80
|
|
|
65
81
|
```markdown
|
|
@@ -94,6 +110,38 @@ Block elements are structural containers that define the layout and establish th
|
|
|
94
110
|
|
|
95
111
|
Inline elements modify text within blocks and apply additional styling on top of the block's typography.
|
|
96
112
|
|
|
113
|
+
## Line Breaks
|
|
114
|
+
|
|
115
|
+
Newlines follow standard CommonMark semantics by default:
|
|
116
|
+
|
|
117
|
+
- **Blank line**: Starts a new paragraph.
|
|
118
|
+
- **Single newline (soft break)**: Renders as a space — consecutive lines flow together into one wrapped paragraph, matching how GitHub and other CommonMark renderers display Markdown.
|
|
119
|
+
- **Hard break**: Ends a line with two spaces or a backslash to force a line break within the paragraph.
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
This line and
|
|
123
|
+
this line render as one continuous sentence.
|
|
124
|
+
|
|
125
|
+
A blank line starts a new paragraph.
|
|
126
|
+
|
|
127
|
+
Two trailing spaces
|
|
128
|
+
or a trailing backslash\
|
|
129
|
+
force a line break within the paragraph.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Preserving single newlines
|
|
133
|
+
|
|
134
|
+
When displaying content authored in `EnrichedMarkdownTextInput`, pressing Enter produces a single newline in the serialized markdown. By default, `EnrichedMarkdownText` collapses these to spaces (per CommonMark). To preserve them as visible line breaks, enable the `hardSoftBreaks` flag:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<EnrichedMarkdownText
|
|
138
|
+
markdown={markdownFromInput}
|
|
139
|
+
md4cFlags={{ hardSoftBreaks: true }}
|
|
140
|
+
/>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
This forces the parser to treat every soft break as a hard break, so single newlines render as line breaks on all platforms.
|
|
144
|
+
|
|
97
145
|
## Images: Block vs Inline
|
|
98
146
|
|
|
99
147
|
Images are automatically detected as block or inline based on context:
|
|
@@ -101,7 +149,7 @@ Images are automatically detected as block or inline based on context:
|
|
|
101
149
|
- **Block images**: When an image is the only content in a paragraph (standalone), it's treated as a block image and uses block-level spacing
|
|
102
150
|
- **Inline images**: When an image appears alongside other text content, it's treated as inline and aligns with the text baseline
|
|
103
151
|
|
|
104
|
-
You don't need to specify which type—the renderer automatically determines this based on the image's position in the content.
|
|
152
|
+
You don't need to specify which type—the renderer automatically determines this based on the image's position in the content. Note that a single newline doesn't split a paragraph, so an image on its own source line directly below text is still inline; separate it with a blank line to make it a block image.
|
|
105
153
|
|
|
106
154
|
## Nested Elements
|
|
107
155
|
|
package/docs/IMAGE_CACHING.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
Images in Markdown content are loaded, cached, and reused automatically — no configuration required.
|
|
4
4
|
|
|
5
|
+
## Supported Image Sources
|
|
6
|
+
|
|
7
|
+
Markdown image URLs are strings, so bundled assets must be resolved to a URI before being interpolated into the markdown:
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Image } from 'react-native';
|
|
11
|
+
|
|
12
|
+
const logoUri = Image.resolveAssetSource(require('./assets/logo.png')).uri;
|
|
13
|
+
const markdown = ``;
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This works in every environment: in dev the URI is a Metro dev-server URL, while in a release build it resolves to a drawable resource name on Android and a bundle `file://` URL on iOS — all of which are supported. URIs from `expo-asset` (`asset.uri` / `asset.localUri`) work the same way.
|
|
17
|
+
|
|
18
|
+
| Source | Android | iOS / macOS |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `http://`, `https://` | Yes | Yes |
|
|
21
|
+
| `file://` (including percent-encoded paths) | Yes | Yes |
|
|
22
|
+
| Bare asset name (release builds, expo-asset `localUri`) | Yes (drawable/raw resource) | Yes (bundle resource) |
|
|
23
|
+
| `file:///android_res/…`, `file:///android_asset/…` | Yes | No |
|
|
24
|
+
| `asset://`, `res://`, `content://` | Yes | No |
|
|
25
|
+
| `data:` (base64) | Yes | Yes |
|
|
26
|
+
|
|
27
|
+
Local sources skip the HTTP layers below (disk cache, request headers, deduplication) but still use both memory cache tiers.
|
|
28
|
+
|
|
5
29
|
## Cache Layers
|
|
6
30
|
|
|
7
31
|
The library uses a three-tier caching strategy on both platforms:
|
|
@@ -16,6 +40,12 @@ The library uses a three-tier caching strategy on both platforms:
|
|
|
16
40
|
- **Processed cache** stores scaled and clipped variants keyed by URL + dimensions + border radius, so repeated layouts with the same geometry skip all image processing.
|
|
17
41
|
- **Disk cache** persists raw HTTP responses across app launches, respecting standard HTTP cache headers.
|
|
18
42
|
|
|
43
|
+
## Request Headers
|
|
44
|
+
|
|
45
|
+
When `imageRequestHeaders` is set, the headers become part of the cache identity for both memory tiers and for request deduplication: the same URL requested with different headers is fetched and cached separately, and changing the prop re-fetches the images.
|
|
46
|
+
|
|
47
|
+
One caveat: the disk cache is managed by the HTTP stack (OkHttp / `NSURLCache`) and keys responses by URL alone. A response fetched with one set of headers can be served from disk for a request with different headers, subject to standard HTTP caching semantics (`Cache-Control`, `Vary`).
|
|
48
|
+
|
|
19
49
|
## Request Deduplication
|
|
20
50
|
|
|
21
51
|
When multiple components request the same image URL simultaneously (e.g. during a re-render), only one network request is made. All pending callbacks are coalesced and dispatched together once the download completes.
|
package/docs/INPUT.md
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
EnrichedMarkdownTextInput,
|
|
14
14
|
type EnrichedMarkdownTextInputInstance,
|
|
15
15
|
type StyleState,
|
|
16
|
-
} from 'react-native-enriched-markdown';
|
|
16
|
+
} from 'react-native-enriched-markdown-scaffold';
|
|
17
17
|
|
|
18
18
|
export default function App() {
|
|
19
19
|
const ref = useRef<EnrichedMarkdownTextInputInstance>(null);
|
|
@@ -66,6 +66,48 @@ Each call toggles the style within the current text selection. They are being to
|
|
|
66
66
|
|
|
67
67
|
Styles are also available through the built-in native format bar that appears on text selection, and through the system context menu.
|
|
68
68
|
|
|
69
|
+
## Headings
|
|
70
|
+
|
|
71
|
+
Supported heading levels: H1–H6.
|
|
72
|
+
|
|
73
|
+
Headings are block-level: a heading applies to the whole paragraph the cursor (or selection) touches, unlike [inline styles](#inline-styles) which apply to a character range. Toggle a heading by calling `toggleHeading(level)` on the component ref with a level from `1` to `6`:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
<Button title="H1" onPress={() => ref.current?.toggleHeading(1)} />
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Calling `toggleHeading` with the level already applied to the cursor's paragraph turns the heading back into a regular paragraph. The cursor's current heading level is reported through the [`onChangeState`](API_REFERENCE.md#onchangestate) payload as `heading: { isActive, level }` (`level` is `0` when the paragraph is not a heading), so you can highlight the active level in your toolbar.
|
|
80
|
+
|
|
81
|
+
Behavior notes:
|
|
82
|
+
|
|
83
|
+
- An emptied heading line stays a heading until you toggle it off, so characters you type next continue at the heading size.
|
|
84
|
+
- Pressing Enter at the end of a heading starts a regular paragraph on the next line (headings do not continue like list items).
|
|
85
|
+
|
|
86
|
+
Heading font sizes, weights, and colors are configurable per level — see [Customizing Styles](#customizing-enrichedmarkdowntextinput--styles).
|
|
87
|
+
|
|
88
|
+
## Lists
|
|
89
|
+
|
|
90
|
+
`EnrichedMarkdownTextInput` supports nested unordered (bullet) and ordered (numbered) lists, serialized to Markdown as `- ` / `1. ` with three spaces of indentation per nesting level. Ordered items are numbered by their position among adjacent same-depth siblings, so numbering stays correct as items are added, removed, or reordered. Like headings, list items are block-level — they apply to whole paragraphs. Manage them through the component ref:
|
|
91
|
+
|
|
92
|
+
- [`toggleUnorderedList()`](API_REFERENCE.md#toggleunorderedlist) — turns the cursor's paragraph(s) into bullet items, or back into regular paragraphs if they already are.
|
|
93
|
+
- [`toggleOrderedList()`](API_REFERENCE.md#toggleorderedlist) — same for numbered items; toggling one list type on the other replaces it.
|
|
94
|
+
- [`indentList()`](API_REFERENCE.md#indentlist) — nests the current item one level deeper. On a non-list paragraph it starts a bullet list.
|
|
95
|
+
- [`outdentList()`](API_REFERENCE.md#outdentlist) — lifts the current item out one level. Outdenting a top-level (depth 0) item removes the bullet.
|
|
96
|
+
|
|
97
|
+
On a hardware keyboard, **Tab** and **Shift+Tab** indent and outdent the current item.
|
|
98
|
+
|
|
99
|
+
Behavior notes:
|
|
100
|
+
|
|
101
|
+
- **Return continues the list** — pressing Return inside an item starts a new bullet at the same depth on the next line. Pressing Return on an empty item exits the list (the line becomes a regular paragraph).
|
|
102
|
+
- **Backspace at the start of an item** outdents it; at depth 0 it removes the bullet.
|
|
103
|
+
- An emptied list line stays a list item (its bullet keeps showing) until you toggle it off or Backspace out of it, so text you type next continues in the list.
|
|
104
|
+
- The bullet marker exists only in the serialized Markdown and the rendered glyph — it is never part of the editor's text, so it won't collide with `-`-prefixed text such as mentions.
|
|
105
|
+
- **List items are single-line.** Each item is exactly one paragraph. Importing or pasting Markdown with *loose* list items (an item containing multiple paragraphs) keeps only the item's first line as a list item — continuation paragraphs become regular paragraphs, not list-styled blocks.
|
|
106
|
+
|
|
107
|
+
Whether the cursor's paragraph is a list item, and its nesting depth, are reported through the [`onChangeState`](API_REFERENCE.md#onchangestate) payload as `unorderedList` / `orderedList` (`{ isActive, depth }`), so you can highlight the list buttons in your toolbar.
|
|
108
|
+
|
|
109
|
+
Use [`markdownStyle.list.itemSpacing`](API_REFERENCE.md#markdownstyle) to add vertical spacing between list items (bullet and numbered alike) so they read as separate rows.
|
|
110
|
+
|
|
69
111
|
## Links
|
|
70
112
|
|
|
71
113
|
Links are a piece of text with a URL attributed to it. They can be managed by calling methods on the input ref:
|
|
@@ -126,10 +168,11 @@ When a manual link is applied (via `setLink` or `insertLink`) over an auto-detec
|
|
|
126
168
|
|
|
127
169
|
By default the input interprets block-level Markdown: a line starting with `1) `, `- `,
|
|
128
170
|
`# ` or `> ` is consumed as list, heading or quote *structure*, and the marker itself is
|
|
129
|
-
not part of the text.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
171
|
+
not part of the text. Headings and lists are written back on save, but in the editor's
|
|
172
|
+
own form rather than the source's: `1) ` comes back as `1. ` and `* ` as `- `. Other block
|
|
173
|
+
syntax — blockquotes, code blocks, tables, thematic breaks, setext headings — is not
|
|
174
|
+
modeled by the editor and is not guaranteed to survive: depending on the platform its
|
|
175
|
+
marker is either dropped or left in the text.
|
|
133
176
|
|
|
134
177
|
Set `blockSyntax={false}` when the text must survive the round trip unchanged:
|
|
135
178
|
|
|
@@ -148,8 +191,9 @@ style as usual.
|
|
|
148
191
|
|
|
149
192
|
What changes:
|
|
150
193
|
|
|
151
|
-
- **
|
|
152
|
-
|
|
194
|
+
- **Loaded or pasted markers stay text**: `3) ` or `# ` coming in through `defaultValue`,
|
|
195
|
+
`setValue` or a paste is not turned into a list or heading. Blocks applied explicitly
|
|
196
|
+
through the toolbar commands still work, and are written back with their markers.
|
|
153
197
|
- The text is displayed with its markers showing, so an editor with `blockSyntax={false}`
|
|
154
198
|
and a `EnrichedMarkdownText` rendering the same source look different, even though the
|
|
155
199
|
stored string is identical.
|
|
@@ -205,6 +249,45 @@ The input's content can be copied to the system clipboard from a ref, without re
|
|
|
205
249
|
|
|
206
250
|
On iOS and macOS the clipboard receives both plain text and a private Markdown pasteboard type, so pasting back into an `EnrichedMarkdownTextInput` restores the formatting; external apps receive plain text only. On Android the clipboard receives plain text only — inline styles are not preserved for any paste target.
|
|
207
251
|
|
|
252
|
+
## Intercepting paste
|
|
253
|
+
|
|
254
|
+
By default a paste goes straight into the buffer. Set [`interceptPaste`](API_REFERENCE.md#interceptpaste) together with [`onPaste`](API_REFERENCE.md#onpaste) to decide what a paste means before any text lands — turning a long paste into an attachment chip, stripping it, or inserting it unchanged.
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
const inputRef = useRef<EnrichedMarkdownTextInputInstance>(null);
|
|
258
|
+
|
|
259
|
+
<EnrichedMarkdownTextInput
|
|
260
|
+
ref={inputRef}
|
|
261
|
+
interceptPaste
|
|
262
|
+
onPaste={({ text, markdown }) => {
|
|
263
|
+
if (text.length > 2000) {
|
|
264
|
+
attachAsFile(text);
|
|
265
|
+
inputRef.current?.resolvePaste('', ''); // drops it, and replaces the selection
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
inputRef.current?.resolvePaste(text, markdown);
|
|
269
|
+
}}
|
|
270
|
+
/>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Native reads the clipboard and **does not touch the buffer**. That makes the handler the only thing that can complete the paste, so the contract is strict:
|
|
274
|
+
|
|
275
|
+
- Call [`resolvePaste`](API_REFERENCE.md#resolvepastetext-string-markdown-string) **exactly once per event, on every path including failures**. A handler that throws before resolving leaves the paste dropped — the user sees nothing happen.
|
|
276
|
+
- Pass `markdown` back through when inserting. It is the copied formatting; dropping it turns a copy-then-paste inside your app into flat text.
|
|
277
|
+
- `interceptPaste` is ignored unless `onPaste` is set, so switching the prop on alone cannot make the input swallow pastes.
|
|
278
|
+
|
|
279
|
+
Because nothing is written until you resolve, an async decision is safe: the selection is still there, and the user sees an unchanged input rather than text that vanished.
|
|
280
|
+
|
|
281
|
+
### Platform behavior
|
|
282
|
+
|
|
283
|
+
| | Behavior |
|
|
284
|
+
| --- | --- |
|
|
285
|
+
| **iOS** | Context menu and hardware ⌘V. `markdown` is set when the copy source was an `EnrichedMarkdownTextInput`. |
|
|
286
|
+
| **Android** | Context menu, hardware Ctrl+V and `KEYCODE_PASTE`. `markdown` is always `''`, and `resolvePaste` inserts `text` verbatim — so an intercepted copy-then-paste inside the app lands as plain text, even though the un-intercepted paste restores the formatting. |
|
|
287
|
+
| **macOS** | `interceptPaste` is ignored, `onPaste` never fires, and pastes insert inline as usual. |
|
|
288
|
+
|
|
289
|
+
Only clipboard content is intercepted. Drag-and-drop, autofill and IME content insertion bypass `onPaste` on both platforms and insert normally — on Android they are filtered out explicitly, so an autofill never arrives looking like a paste.
|
|
290
|
+
|
|
208
291
|
## Style Detection
|
|
209
292
|
|
|
210
293
|
All of the above styles can be detected with the use of [onChangeState](API_REFERENCE.md#onchangestate) callback payload.
|
|
@@ -220,6 +303,17 @@ You can find some examples in the [usage section](#usage) or in the example app.
|
|
|
220
303
|
- [onChangeText](API_REFERENCE.md#onchangetext) - returns the input's plain text (without Markdown syntax) anytime it changes.
|
|
221
304
|
- [onChangeMarkdown](API_REFERENCE.md#onchangemarkdown) - returns the Markdown string parsed from current input text and styles anytime it would change. As parsing the Markdown on each input change can be expensive, not assigning the event's callback will skip the serialization for better performance.
|
|
222
305
|
- [onChangeSelection](API_REFERENCE.md#onchangeselection) - returns `{ start, end }` of the current selection, useful for working with [links](#links).
|
|
306
|
+
- [onKeyPress](API_REFERENCE.md#onkeypress) - returns `{ nativeEvent: { key } }` for every keystroke before it is applied to the content, mirroring React Native TextInput's `onKeyPress`.
|
|
307
|
+
|
|
308
|
+
## Keyboard Dismissal
|
|
309
|
+
|
|
310
|
+
`EnrichedMarkdownTextInput` registers with React Native's text-input focus tracking (`TextInput.State`), so scroll containers treat it exactly like the built-in `TextInput`. No props on the input are involved — the behavior is controlled by the surrounding `ScrollView` / `FlatList`:
|
|
311
|
+
|
|
312
|
+
- With the soft keyboard open, tapping outside the focused input blurs it and dismisses the keyboard, following the scroll container's [`keyboardShouldPersistTaps`](https://reactnative.dev/docs/scrollview#keyboardshouldpersisttaps) setting. In the default `'never'` mode the dismissing tap is consumed (the classic first-tap-dismisses, second-tap-presses behavior); `'handled'` dismisses only on taps no child handles; `'always'` never auto-dismisses.
|
|
313
|
+
- Scrolling does not dismiss the keyboard unless the container sets [`keyboardDismissMode`](https://reactnative.dev/docs/scrollview#keyboarddismissmode).
|
|
314
|
+
- [`Keyboard.dismiss()`](https://reactnative.dev/docs/keyboard#dismiss) blurs the input when it is the focused field.
|
|
315
|
+
|
|
316
|
+
Matching `TextInput`, none of this applies while a hardware keyboard is in use (for example the iOS Simulator with **Connect Hardware Keyboard** enabled): with no soft keyboard on screen there is nothing to dismiss, so outside taps intentionally leave the input focused.
|
|
223
317
|
|
|
224
318
|
## RTL Support
|
|
225
319
|
|
|
@@ -249,7 +343,7 @@ No setup is required. Both platforms autodetect direction per paragraph out of t
|
|
|
249
343
|
|
|
250
344
|
- **Placeholder** follows the host view's layout direction, not the prop. If you need an RTL placeholder, wrap the input in `<View style={{ direction: 'rtl' }}>` or set `I18nManager.forceRTL(true)`.
|
|
251
345
|
- **Mixed paragraphs while typing** — newly inserted characters in an empty paragraph briefly inherit the previous paragraph's direction; the first-strong pass corrects this on the next input event.
|
|
252
|
-
- **Code blocks, tables, blockquotes
|
|
346
|
+
- **Code blocks, tables, blockquotes** are not supported in the input. Headings and bullet lists are; other block elements require [`EnrichedMarkdownText`](TEXT.md).
|
|
253
347
|
|
|
254
348
|
See [RTL Support](RTL.md) for the full per-element behavior on the rendered output side.
|
|
255
349
|
|
|
@@ -263,6 +357,7 @@ See [RTL Support](RTL.md) for the full per-element behavior on the rendered outp
|
|
|
263
357
|
strong: { color: '#1D4ED8' },
|
|
264
358
|
em: { color: '#7C3AED' },
|
|
265
359
|
link: { color: '#2563EB', underline: true },
|
|
360
|
+
h1: { fontSize: 28, fontWeight: 'bold', color: '#111827' },
|
|
266
361
|
}}
|
|
267
362
|
/>
|
|
268
363
|
```
|
|
@@ -275,7 +370,9 @@ Available style properties:
|
|
|
275
370
|
- `link.underline` — whether links are underlined (defaults to `true`).
|
|
276
371
|
- `spoiler.color` — text color for spoiler text.
|
|
277
372
|
- `spoiler.backgroundColor` — background color for spoiler text.
|
|
278
|
-
- `
|
|
373
|
+
- `h1`–`h6` — per-level heading styling, each accepting `fontSize`, `fontWeight`, and `color`. Defaults match the read-only `EnrichedMarkdownText` renderer (sizes `30/24/20/18/16/14`, bold) so headings look the same in the editor and a rendered preview. Omitted levels (or fields) fall back to those defaults.
|
|
374
|
+
- `inlineMath` / `math` — chip styling for inline (`$...$`) and block (`$$...$$`) LaTeX. Same key names and shared field names as the read-only renderer's `markdownStyle`, so one palette drives both. See [LaTeX Math](LATEX_MATH.md#styling-math-in-the-editor).
|
|
375
|
+
- `inlineMath.fontWeight` — `'bold'` | `'normal'` (default `'normal'`); typesets inline formula chips
|
|
279
376
|
(`$...$`) at bold weight. See [LATEX_MATH.md](./LATEX_MATH.md#bold-formulas).
|
|
280
|
-
- `
|
|
281
|
-
`
|
|
377
|
+
- `math.fontWeight` — same for block formula chips (`$$...$$`); inherits from
|
|
378
|
+
`inlineMath.fontWeight` when unset.
|
package/docs/LATEX_MATH.md
CHANGED
|
@@ -47,6 +47,39 @@ what pushes those lines apart. It affects only lines that actually contain inlin
|
|
|
47
47
|
the line height they had. Set it to `0` to get the old flush behaviour back. Block math (`$$...$$`) has its own
|
|
48
48
|
`math.padding` instead.
|
|
49
49
|
|
|
50
|
+
### Styling math in the editor
|
|
51
|
+
|
|
52
|
+
`EnrichedMarkdownTextInput` renders each formula as a chip and takes its style
|
|
53
|
+
under the **same two keys**, with the same meaning: `markdownStyle.inlineMath`
|
|
54
|
+
for `$...$` and `markdownStyle.math` for `$$...$$`.
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<EnrichedMarkdownTextInput
|
|
58
|
+
markdownStyle={{
|
|
59
|
+
inlineMath: { color: '#0F172A', backgroundColor: '#EEF2FF' },
|
|
60
|
+
math: { fontSize: 22, padding: 12, textAlign: 'center' },
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Fields shared with the renderer (`color`, `fontSize`, `backgroundColor`,
|
|
66
|
+
`padding`, `marginTop`, `marginBottom`, `textAlign`) mean the same thing on both
|
|
67
|
+
surfaces, so one palette can drive an editor and its preview. The chip adds
|
|
68
|
+
`borderColor`, `borderWidth`, `borderRadius`, `selectedBackgroundColor` and
|
|
69
|
+
`selectedBorderColor`, which the read-only renderer has no counterpart for, and
|
|
70
|
+
it splits `padding` into `paddingHorizontal` / `paddingVertical` — either of
|
|
71
|
+
which overrides the `padding` shorthand for its axis.
|
|
72
|
+
|
|
73
|
+
`math` inherits the chip look (colors, border, selection) from `inlineMath`, so
|
|
74
|
+
setting `inlineMath` alone styles both; `math` then overrides what differs.
|
|
75
|
+
|
|
76
|
+
A formula is **atomic** in the editor: it occupies one character (`U+FFFC`) in the
|
|
77
|
+
buffer, and the LaTeX lives on the chip rather than in the text. That is what makes
|
|
78
|
+
the caret, selection and IME step over a formula in one move — and it is why
|
|
79
|
+
`onChangeText` reports a `U+FFFC` where the formula is, while `onChangeMarkdown`
|
|
80
|
+
reports the `$...$` source. Offsets in `onChangeSelection`, `onCaretRectChange` and
|
|
81
|
+
`updateMath` / `removeMath` count a formula as that one character.
|
|
82
|
+
|
|
50
83
|
### Bold formulas
|
|
51
84
|
|
|
52
85
|
`math.fontWeight` / `inlineMath.fontWeight` (`'normal'` | `'bold'`, default `'normal'`) typeset a
|
|
@@ -74,15 +107,16 @@ bold face, so the browser synthesizes one there too. Treat web as synthetic as w
|
|
|
74
107
|
reference for how heavy bold "should" look.
|
|
75
108
|
|
|
76
109
|
`EnrichedMarkdownTextInput` honours the same prop for the formula chips typed into the editor, under
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
110
|
+
the same two keys as the rest of [Styling math in the editor](#styling-math-in-the-editor) —
|
|
111
|
+
`inlineMath.fontWeight` for inline chips (`$...$`) and `math.fontWeight` for block chips
|
|
112
|
+
(`$$...$$`). `math` inherits the weight from `inlineMath` when it does not set one of its own, the
|
|
113
|
+
way it already inherits `color` and the border props:
|
|
80
114
|
|
|
81
115
|
```tsx
|
|
82
116
|
<EnrichedMarkdownTextInput
|
|
83
117
|
markdownStyle={{
|
|
84
|
-
|
|
85
|
-
|
|
118
|
+
inlineMath: { fontWeight: 'bold' }, // inline chips bold…
|
|
119
|
+
math: { fontWeight: 'normal' }, // …block chips opt back out
|
|
86
120
|
}}
|
|
87
121
|
/>
|
|
88
122
|
```
|
|
@@ -142,57 +176,65 @@ Set `latexMath: false` in `md4cFlags` so the parser treats `$` as plain text:
|
|
|
142
176
|
|
|
143
177
|
This alone prevents math rendering without any native changes. The steps below go further by removing the native math libraries from your binary entirely.
|
|
144
178
|
|
|
145
|
-
### 2. Remove the native
|
|
179
|
+
### 2. Remove the native dependency
|
|
146
180
|
|
|
147
|
-
|
|
181
|
+
Set `enableMath` to `false` in the `enriched-markdown` block of your app's `package.json`:
|
|
148
182
|
|
|
149
|
-
```
|
|
150
|
-
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"enriched-markdown": {
|
|
186
|
+
"enableMath": false
|
|
187
|
+
}
|
|
188
|
+
}
|
|
151
189
|
```
|
|
152
190
|
|
|
153
|
-
This
|
|
191
|
+
This is the single source of truth for both platforms: `postinstall` skips the install-time RaTeX
|
|
192
|
+
download, and the native build reads the same block directly to exclude **RaTeX** from the binary — no
|
|
193
|
+
Podfile or `gradle.properties` edit needed. Re-run `pod install` (iOS) / rebuild (Android) after
|
|
194
|
+
changing it. See [Skipping the download](./NATIVE_ASSETS.md#skipping-the-download-opt-out).
|
|
154
195
|
|
|
155
196
|
> [!NOTE]
|
|
156
|
-
>
|
|
157
|
-
>
|
|
158
|
-
>
|
|
159
|
-
> ```
|
|
160
|
-
> This is required for CocoaPods to resolve the RaTeX Swift Package dependency.
|
|
197
|
+
> **Deprecated:** the `ENV['ENRICHED_MARKDOWN_ENABLE_MATH']` Podfile variable and the
|
|
198
|
+
> `enrichedMarkdown.enableMath` gradle property still work as a fallback but are deprecated and print a
|
|
199
|
+
> warning; they are ignored when the `package.json` block sets `enableMath`.
|
|
161
200
|
|
|
162
201
|
> [!NOTE]
|
|
163
|
-
>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
```properties
|
|
170
|
-
enrichedMarkdown.enableMath=false
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
This excludes **RaTeX** from the Android build. Rebuild the app after changing this property.
|
|
202
|
+
> When math is **enabled** (the default), no special Podfile configuration is required.
|
|
203
|
+
> RaTeX ships as a prebuilt static XCFramework vendored into the pod, so it links under
|
|
204
|
+
> CocoaPods default static linkage — you do **not** need `use_frameworks!`. (Earlier
|
|
205
|
+
> versions required `use_frameworks! :linkage => :dynamic` to resolve RaTeX as a Swift
|
|
206
|
+
> Package; that is no longer the case.)
|
|
174
207
|
|
|
175
|
-
|
|
208
|
+
> [!NOTE]
|
|
209
|
+
> The RaTeX XCFramework is **not** bundled in the npm tarball — it is downloaded at install time by
|
|
210
|
+
> a `postinstall` script (see [Native assets](./NATIVE_ASSETS.md)). If `ios/vendor/RaTeX.xcframework`
|
|
211
|
+
> is missing (offline install, `--ignore-scripts`, pnpm, or a `package.json` opt-out) and math is only
|
|
212
|
+
> on by default, `pod install` auto-disables math and prints a warning instead of failing. If you
|
|
213
|
+
> **explicitly** set `"enableMath": true`, a missing framework is a hard error instead. Either way, run
|
|
214
|
+
> `node node_modules/react-native-enriched-markdown-scaffold/postinstall.mjs` and re-run `pod install` to restore it.
|
|
176
215
|
|
|
177
|
-
|
|
216
|
+
> [!IMPORTANT]
|
|
217
|
+
> **Upgrading from a version that used `use_frameworks! :linkage => :dynamic` for math?**
|
|
218
|
+
> The pod changed from a dynamic framework to a static library. After `pod install`,
|
|
219
|
+
> do a one-time clean build (Xcode: Product > Clean Build Folder, or delete the app's
|
|
220
|
+
> DerivedData) — a stale build folder otherwise fails with
|
|
221
|
+
> `ReactNativeEnrichedMarkdown.framework/Modules/module.modulemap not found`. Fresh
|
|
222
|
+
> installs are unaffected.
|
|
178
223
|
|
|
179
|
-
|
|
224
|
+
> [!NOTE]
|
|
225
|
+
> **macOS**: LaTeX math is not yet enabled on macOS and remains off in the macOS example
|
|
226
|
+
> app. The previous blocker (`use_frameworks!` was required for the RaTeX Swift Package)
|
|
227
|
+
> no longer applies now that RaTeX is a vendored XCFramework with a macOS slice, so macOS
|
|
228
|
+
> support is a possible future follow-up.
|
|
180
229
|
|
|
181
|
-
|
|
182
|
-
{
|
|
183
|
-
"expo": {
|
|
184
|
-
"plugins": [
|
|
185
|
-
[
|
|
186
|
-
"react-native-enriched-markdown",
|
|
187
|
-
{
|
|
188
|
-
"enableMath": false
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
]
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
```
|
|
230
|
+
### 3. Expo
|
|
195
231
|
|
|
196
|
-
|
|
232
|
+
The `package.json` block above works with Expo too — `node_modules` (and the resolved config) survive
|
|
233
|
+
`npx expo prebuild`, so no config plugin is needed. Set `"enriched-markdown": { "enableMath": false }` in
|
|
234
|
+
your app's `package.json` and rebuild.
|
|
197
235
|
|
|
198
|
-
|
|
236
|
+
> [!NOTE]
|
|
237
|
+
> Because `enableMath` is a compile/link-time decision, it only applies in builds you compile yourself
|
|
238
|
+
> (a custom dev client or `expo prebuild`). It **cannot** be changed in **Expo Go**, which ships a fixed
|
|
239
|
+
> prebuilt binary. A dedicated config plugin was removed in favor of the `package.json` block — see
|
|
240
|
+
> [Breaking changes](./BREAKING_CHANGES.md).
|
package/docs/MACOS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# macOS Support
|
|
2
2
|
|
|
3
|
-
`react-native-enriched-markdown` supports macOS via [react-native-macos](https://github.com/microsoft/react-native-macos). The native layer shares code with iOS through a platform abstraction header (`ENRMUIKit.h`), with macOS-specific implementations for context menus, text selection, and clipboard handling.
|
|
3
|
+
`react-native-enriched-markdown-scaffold` supports macOS via [react-native-macos](https://github.com/microsoft/react-native-macos). The native layer shares code with iOS through a platform abstraction header (`ENRMUIKit.h`), with macOS-specific implementations for context menus, text selection, and clipboard handling.
|
|
4
4
|
|
|
5
5
|
The macOS implementation supports the same rendering elements as iOS — CommonMark, GitHub Flavored Markdown (tables, task lists, strikethrough), images, code blocks, blockquotes, and all other supported elements. `EnrichedMarkdownTextInput` is also available on macOS with full support for inline styles, links, and the native context menu.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Markdown Streaming
|
|
2
2
|
|
|
3
|
-
If you need to render markdown that streams token-by-token from an LLM, check out [react-native-streamdown](https://github.com/software-mansion-labs/react-native-streamdown) — a streaming-ready markdown component built on top of `react-native-enriched-markdown`.
|
|
3
|
+
If you need to render markdown that streams token-by-token from an LLM, check out [react-native-streamdown](https://github.com/software-mansion-labs/react-native-streamdown) — a streaming-ready markdown component built on top of `react-native-enriched-markdown-scaffold`.
|
|
4
4
|
|
|
5
5
|
It combines [remend](https://www.npmjs.com/package/remend) for fixing incomplete markdown on the fly with [react-native-worklets](https://docs.swmansion.com/react-native-worklets/) **Bundle Mode** to run all processing off the JS thread, keeping your UI responsive while tokens arrive.
|
|
6
6
|
|
|
@@ -34,3 +34,29 @@ The `streamingConfig` prop controls this behavior:
|
|
|
34
34
|
| `'progressive'` (default) | Renders the table row-by-row as content arrives. New rows fade in when `streamingAnimation` is enabled. Incomplete trailing rows are automatically trimmed. |
|
|
35
35
|
| `'hidden'` | The table is completely hidden until it is followed by a blank line, indicating the table is complete. Prevents visual jank from partially formed tables. |
|
|
36
36
|
|
|
37
|
+
## Code Block Streaming (GFM)
|
|
38
|
+
|
|
39
|
+
Fenced code blocks are also block-level elements. While a block's closing fence
|
|
40
|
+
(```` ``` ````) has not arrived, its content is still changing, which would
|
|
41
|
+
otherwise make syntax highlighting flicker on every token.
|
|
42
|
+
|
|
43
|
+
The `codeBlockMode` field of `streamingConfig` controls this:
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
<EnrichedMarkdownText
|
|
47
|
+
markdown={streamingMarkdown}
|
|
48
|
+
flavor="github"
|
|
49
|
+
streamingAnimation
|
|
50
|
+
streamingConfig={{ codeBlockMode: 'progressive' }}
|
|
51
|
+
/>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Code Block Modes
|
|
55
|
+
|
|
56
|
+
| Mode | Behavior |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `'progressive'` (default) | The code streams in line-by-line with its header (language label + copy button) visible but non-interactive — copying is disabled until the block completes. Syntax highlighting is deferred so it applies once when the closing fence arrives instead of flickering per token. |
|
|
59
|
+
| `'hidden'` | The entire code block is hidden until its closing fence arrives, then it appears complete (the same all-or-nothing behavior block math uses). |
|
|
60
|
+
|
|
61
|
+
Both modes only take effect when `streamingAnimation` is `true`.
|
|
62
|
+
|