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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "ListItemRenderer.h"
|
|
2
|
+
#import "BlockquoteBorder.h"
|
|
2
3
|
#import "ENRMUIKit.h"
|
|
3
4
|
#import "LastElementUtils.h"
|
|
4
5
|
#import "MarkdownASTNode.h"
|
|
@@ -10,10 +11,14 @@
|
|
|
10
11
|
NSString *const ListDepthAttribute = @"ListDepth";
|
|
11
12
|
NSString *const ListTypeAttribute = @"ListType";
|
|
12
13
|
NSString *const ListItemNumberAttribute = @"ListItemNumber";
|
|
14
|
+
NSString *const ListItemMarkerStartAttribute = @"ListItemMarkerStart";
|
|
13
15
|
NSString *const TaskItemAttribute = @"TaskItem";
|
|
14
16
|
NSString *const TaskCheckedAttribute = @"TaskChecked";
|
|
15
17
|
NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
16
18
|
|
|
19
|
+
@implementation ENRMListMarkerDescriptor
|
|
20
|
+
@end
|
|
21
|
+
|
|
17
22
|
@interface ListItemRenderer ()
|
|
18
23
|
- (void)applyCheckedDecorationsTo:(NSMutableAttributedString *)output
|
|
19
24
|
range:(NSRange)range
|
|
@@ -22,7 +27,9 @@ NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
|
22
27
|
|
|
23
28
|
@implementation ListItemRenderer
|
|
24
29
|
|
|
25
|
-
- (void)
|
|
30
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
31
|
+
into:(NSMutableAttributedString *)output
|
|
32
|
+
context:(RenderContext *)context
|
|
26
33
|
{
|
|
27
34
|
if (!context)
|
|
28
35
|
return;
|
|
@@ -39,10 +46,28 @@ NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
|
39
46
|
context.taskItemCount++;
|
|
40
47
|
}
|
|
41
48
|
|
|
49
|
+
// currentDepth - 1 handles the horizontal offset for nested lists
|
|
50
|
+
const NSInteger nestingLevel = currentDepth - 1;
|
|
51
|
+
const CGFloat baseMarkerWidth = isTask ? [_config effectiveListMarginLeftForTask]
|
|
52
|
+
: (context.listType == ListTypeOrdered) ? [_config effectiveListMarginLeftForNumber]
|
|
53
|
+
: [_config effectiveListMarginLeftForBullet];
|
|
54
|
+
|
|
55
|
+
const CGFloat blockquoteIndent =
|
|
56
|
+
blockquoteIndentForDepth(context.blockquoteDepth, [_config blockquoteBorderWidth] + [_config blockquoteGapWidth]);
|
|
57
|
+
|
|
58
|
+
const CGFloat totalIndent = blockquoteIndent + baseMarkerWidth + [_config effectiveListGapWidth] +
|
|
59
|
+
(nestingLevel * [_config listStyleMarginLeft]);
|
|
60
|
+
|
|
42
61
|
const NSUInteger startLocation = output.length;
|
|
43
62
|
|
|
44
|
-
//
|
|
45
|
-
|
|
63
|
+
// Manual save/restore — a scope snapshot would also roll back the listItemNumber increment
|
|
64
|
+
const CGFloat prevIndent = context.accumulatedIndent;
|
|
65
|
+
context.accumulatedIndent = totalIndent;
|
|
66
|
+
@try {
|
|
67
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
68
|
+
} @finally {
|
|
69
|
+
context.accumulatedIndent = prevIndent;
|
|
70
|
+
}
|
|
46
71
|
|
|
47
72
|
// Ensure every list item ends with a newline to prevent paragraph merging
|
|
48
73
|
if (output.length > startLocation && ![output.string hasSuffix:@"\n"]) {
|
|
@@ -59,15 +84,6 @@ NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
|
59
84
|
depth:currentDepth
|
|
60
85
|
isOrdered:(context.listType == ListTypeOrdered)];
|
|
61
86
|
|
|
62
|
-
// currentDepth - 1 handles the horizontal offset for nested lists
|
|
63
|
-
const NSInteger nestingLevel = currentDepth - 1;
|
|
64
|
-
const CGFloat baseMarkerWidth = isTask ? [_config effectiveListMarginLeftForTask]
|
|
65
|
-
: (context.listType == ListTypeOrdered) ? [_config effectiveListMarginLeftForNumber]
|
|
66
|
-
: [_config effectiveListMarginLeftForBullet];
|
|
67
|
-
|
|
68
|
-
const CGFloat totalIndent =
|
|
69
|
-
baseMarkerWidth + [_config effectiveListGapWidth] + (nestingLevel * [_config listStyleMarginLeft]);
|
|
70
|
-
|
|
71
87
|
const CGFloat lineHeightConfig = [_config listStyleLineHeight];
|
|
72
88
|
|
|
73
89
|
// Boxing metadata for attributed string storage
|
|
@@ -83,45 +99,87 @@ NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
|
83
99
|
metadata[TaskIndexAttribute] = @(taskIndex);
|
|
84
100
|
}
|
|
85
101
|
|
|
86
|
-
//
|
|
87
|
-
//
|
|
102
|
+
// Preserve styles of nested sub-lists and code blocks by applying the list
|
|
103
|
+
// paragraph style only to the surviving gaps between them.
|
|
104
|
+
NSMutableArray<NSValue *> *skipRanges = [NSMutableArray array];
|
|
105
|
+
[output enumerateAttribute:CodeBlockAttributeName
|
|
106
|
+
inRange:itemRange
|
|
107
|
+
options:0
|
|
108
|
+
usingBlock:^(id value, NSRange range, BOOL *stop) {
|
|
109
|
+
if ([value boolValue]) {
|
|
110
|
+
[skipRanges addObject:[NSValue valueWithRange:range]];
|
|
111
|
+
}
|
|
112
|
+
}];
|
|
88
113
|
[output enumerateAttribute:ListDepthAttribute
|
|
89
114
|
inRange:itemRange
|
|
90
115
|
options:0
|
|
91
116
|
usingBlock:^(id depthAttr, NSRange range, BOOL *stop) {
|
|
92
|
-
// If a segment already has a Depth attribute higher than our current level,
|
|
93
|
-
// it belongs to a nested list and we should skip it to preserve its styling.
|
|
94
117
|
if (depthAttr && [depthAttr integerValue] > nestingLevel) {
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Skip code block ranges — CodeBlockRenderer already applied its own
|
|
99
|
-
// paragraph style (padding, LTR indent). Overwriting would add list
|
|
100
|
-
// markers ("2.") inside the code block.
|
|
101
|
-
NSNumber *isCodeBlock = [output attribute:CodeBlockAttributeName
|
|
102
|
-
atIndex:range.location
|
|
103
|
-
effectiveRange:nil];
|
|
104
|
-
if ([isCodeBlock boolValue]) {
|
|
105
|
-
return;
|
|
118
|
+
[skipRanges addObject:[NSValue valueWithRange:range]];
|
|
106
119
|
}
|
|
120
|
+
}];
|
|
121
|
+
[skipRanges sortUsingComparator:^NSComparisonResult(NSValue *a, NSValue *b) {
|
|
122
|
+
NSUInteger la = [a rangeValue].location;
|
|
123
|
+
NSUInteger lb = [b rangeValue].location;
|
|
124
|
+
return la < lb ? NSOrderedAscending : (la > lb ? NSOrderedDescending : NSOrderedSame);
|
|
125
|
+
}];
|
|
126
|
+
|
|
127
|
+
void (^applyStyleToRange)(NSRange) = ^(NSRange range) {
|
|
128
|
+
if (range.length == 0)
|
|
129
|
+
return;
|
|
130
|
+
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
|
|
131
|
+
style.firstLineHeadIndent = totalIndent;
|
|
132
|
+
style.headIndent = totalIndent;
|
|
133
|
+
NSMutableDictionary *attributesToApply = [metadata mutableCopy];
|
|
134
|
+
attributesToApply[NSParagraphStyleAttributeName] = style;
|
|
135
|
+
[output addAttributes:attributesToApply range:range];
|
|
136
|
+
// Line height goes through the shared helper so list items get the same carve-out as
|
|
137
|
+
// paragraphs — inline math AND block images. Clamping maximumLineHeight here directly
|
|
138
|
+
// would push the line fragment below the height an inline math attachment draws at, and
|
|
139
|
+
// the overflow paints over the neighbouring lines. applyLineHeight reads the paragraph
|
|
140
|
+
// style back via getOrCreateParagraphStyle, so it must run AFTER addAttributes: for the
|
|
141
|
+
// indents above to survive; it early-returns on a non-positive line height.
|
|
142
|
+
applyLineHeight(output, range, lineHeightConfig);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
NSUInteger pos = itemRange.location;
|
|
146
|
+
const NSUInteger itemEnd = NSMaxRange(itemRange);
|
|
147
|
+
for (NSValue *val in skipRanges) {
|
|
148
|
+
NSRange skip = [val rangeValue];
|
|
149
|
+
if (pos < skip.location) {
|
|
150
|
+
applyStyleToRange(NSMakeRange(pos, skip.location - pos));
|
|
151
|
+
}
|
|
152
|
+
pos = MAX(pos, NSMaxRange(skip));
|
|
153
|
+
}
|
|
154
|
+
if (pos < itemEnd) {
|
|
155
|
+
applyStyleToRange(NSMakeRange(pos, itemEnd - pos));
|
|
156
|
+
}
|
|
107
157
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
158
|
+
ENRMListMarkerDescriptor *marker = [[ENRMListMarkerDescriptor alloc] init];
|
|
159
|
+
marker.isTask = isTask;
|
|
160
|
+
marker.isChecked = isChecked;
|
|
161
|
+
marker.taskIndex = taskIndex;
|
|
162
|
+
marker.listType = context.listType;
|
|
163
|
+
marker.number = currentPosition;
|
|
164
|
+
marker.depth = nestingLevel;
|
|
165
|
+
marker.indent = totalIndent;
|
|
166
|
+
|
|
167
|
+
// Anchor on the first content character so items that open with a code block
|
|
168
|
+
// or nested sublist still get their marker; fall back to startLocation for
|
|
169
|
+
// whitespace-only items.
|
|
170
|
+
NSUInteger anchorLocation = startLocation;
|
|
171
|
+
NSString *string = output.string;
|
|
172
|
+
for (NSUInteger i = startLocation; i < itemEnd; i++) {
|
|
173
|
+
if ([string characterAtIndex:i] != '\n') {
|
|
174
|
+
anchorLocation = i;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
116
178
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// paragraph style we just applied, so the indents above survive, and it
|
|
122
|
-
// early-returns on a non-positive line height like the old guard did.
|
|
123
|
-
applyLineHeight(output, range, lineHeightConfig);
|
|
124
|
-
}];
|
|
179
|
+
NSArray *existingMarkers = [output attribute:ListItemMarkerStartAttribute atIndex:anchorLocation effectiveRange:NULL];
|
|
180
|
+
NSArray *markers =
|
|
181
|
+
[existingMarkers isKindOfClass:[NSArray class]] ? [existingMarkers arrayByAddingObject:marker] : @[ marker ];
|
|
182
|
+
[output addAttribute:ListItemMarkerStartAttribute value:markers range:NSMakeRange(anchorLocation, 1)];
|
|
125
183
|
|
|
126
184
|
if (isTask && isChecked) {
|
|
127
185
|
[self applyCheckedDecorationsTo:output range:itemRange nestingLevel:nestingLevel];
|
|
@@ -175,4 +233,4 @@ NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
|
175
233
|
}];
|
|
176
234
|
}
|
|
177
235
|
|
|
178
|
-
@end
|
|
236
|
+
@end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#import "
|
|
1
|
+
#import "BaseRenderer.h"
|
|
2
2
|
|
|
3
3
|
@class RendererFactory;
|
|
4
4
|
@class StyleConfig;
|
|
5
5
|
@class RenderContext;
|
|
6
6
|
|
|
7
|
-
@interface ListRenderer :
|
|
7
|
+
@interface ListRenderer : BaseRenderer
|
|
8
8
|
|
|
9
9
|
- (instancetype)initWithRendererFactory:(RendererFactory *)rendererFactory
|
|
10
10
|
config:(StyleConfig *)config
|
|
@@ -6,37 +6,75 @@
|
|
|
6
6
|
#import "RendererFactory.h"
|
|
7
7
|
#import "StyleConfig.h"
|
|
8
8
|
|
|
9
|
+
// Inserts the configured vertical gap between consecutive list items (including
|
|
10
|
+
// nested ones) by raising paragraphSpacing on the paragraph preceding each item
|
|
11
|
+
// start. The first item of the root list gets no spacing above it.
|
|
12
|
+
static void applyListItemSpacing(NSMutableAttributedString *output, RenderContext *context, NSUInteger listStart,
|
|
13
|
+
CGFloat itemSpacing)
|
|
14
|
+
{
|
|
15
|
+
if (itemSpacing <= 0)
|
|
16
|
+
return;
|
|
17
|
+
|
|
18
|
+
NSMutableIndexSet *itemStarts = [NSMutableIndexSet indexSet];
|
|
19
|
+
for (NSValue *value in context.listItemRanges) {
|
|
20
|
+
NSUInteger location = [value rangeValue].location;
|
|
21
|
+
if (location >= listStart && location < output.length) {
|
|
22
|
+
[itemStarts addIndex:location];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (itemStarts.count < 2)
|
|
26
|
+
return;
|
|
27
|
+
|
|
28
|
+
NSString *string = output.string;
|
|
29
|
+
const NSUInteger firstStart = itemStarts.firstIndex;
|
|
30
|
+
[itemStarts enumerateIndexesUsingBlock:^(NSUInteger itemStart, BOOL *stop) {
|
|
31
|
+
if (itemStart == firstStart)
|
|
32
|
+
return;
|
|
33
|
+
NSRange prevParagraph = [string paragraphRangeForRange:NSMakeRange(itemStart - 1, 0)];
|
|
34
|
+
[output enumerateAttribute:NSParagraphStyleAttributeName
|
|
35
|
+
inRange:prevParagraph
|
|
36
|
+
options:0
|
|
37
|
+
usingBlock:^(NSParagraphStyle *style, NSRange range, BOOL *innerStop) {
|
|
38
|
+
if (style.paragraphSpacing >= itemSpacing)
|
|
39
|
+
return;
|
|
40
|
+
NSMutableParagraphStyle *updated =
|
|
41
|
+
style ? [style mutableCopy] : [[NSMutableParagraphStyle alloc] init];
|
|
42
|
+
updated.paragraphSpacing = itemSpacing;
|
|
43
|
+
[output addAttribute:NSParagraphStyleAttributeName value:updated range:range];
|
|
44
|
+
}];
|
|
45
|
+
}];
|
|
46
|
+
}
|
|
47
|
+
|
|
9
48
|
@implementation ListRenderer {
|
|
10
|
-
__weak RendererFactory *_rendererFactory;
|
|
11
|
-
StyleConfig *_config;
|
|
12
49
|
BOOL _isOrdered;
|
|
13
50
|
}
|
|
14
51
|
|
|
15
52
|
- (instancetype)initWithRendererFactory:(RendererFactory *)factory config:(StyleConfig *)config isOrdered:(BOOL)ordered
|
|
16
53
|
{
|
|
17
|
-
if (self = [super
|
|
18
|
-
_rendererFactory = factory;
|
|
19
|
-
_config = config;
|
|
54
|
+
if (self = [super initWithRendererFactory:factory config:config]) {
|
|
20
55
|
_isOrdered = ordered;
|
|
21
56
|
}
|
|
22
57
|
return self;
|
|
23
58
|
}
|
|
24
59
|
|
|
25
|
-
- (
|
|
60
|
+
- (id)takeContextSnapshot:(RenderContext *)context
|
|
61
|
+
{
|
|
62
|
+
return [context snapshotScope];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
66
|
+
into:(NSMutableAttributedString *)output
|
|
67
|
+
context:(RenderContext *)context
|
|
26
68
|
{
|
|
27
69
|
if (!context)
|
|
28
70
|
return;
|
|
29
71
|
|
|
30
72
|
const NSInteger prevDepth = context.listDepth;
|
|
31
|
-
const ListType prevType = context.listType;
|
|
32
|
-
const NSInteger prevNum = context.listItemNumber;
|
|
33
|
-
|
|
34
73
|
const NSUInteger startLocation = output.length;
|
|
35
|
-
NSUInteger contentStart = startLocation;
|
|
36
74
|
|
|
37
75
|
if (prevDepth == 0) {
|
|
38
76
|
// Apply top margin for root-level list
|
|
39
|
-
|
|
77
|
+
applyBlockSpacingBefore(output, startLocation, _config.listStyleMarginTop);
|
|
40
78
|
} else if (output.length > 0 && ![output.string hasSuffix:@"\n"]) {
|
|
41
79
|
// Ensure nested lists start on a new line
|
|
42
80
|
[output appendAttributedString:kNewlineAttributedString];
|
|
@@ -44,27 +82,27 @@
|
|
|
44
82
|
|
|
45
83
|
context.listDepth = prevDepth + 1;
|
|
46
84
|
context.listType = _isOrdered ? ListTypeOrdered : ListTypeUnordered;
|
|
47
|
-
|
|
85
|
+
NSInteger startNumber = 1;
|
|
86
|
+
NSString *startAttr = node.attributes[@"start"];
|
|
87
|
+
if (_isOrdered && startAttr != nil) {
|
|
88
|
+
startNumber = MAX((NSInteger)0, (NSInteger)startAttr.integerValue);
|
|
89
|
+
}
|
|
90
|
+
// ListItemRenderer pre-increments, so the counter starts one below the
|
|
91
|
+
// first rendered number.
|
|
92
|
+
context.listItemNumber = startNumber - 1;
|
|
48
93
|
|
|
49
94
|
[context setBlockStyle:_isOrdered ? BlockTypeOrderedList : BlockTypeUnorderedList
|
|
50
95
|
font:_config.listStyleFont
|
|
51
96
|
color:_config.listStyleColor
|
|
52
97
|
headingLevel:0];
|
|
53
98
|
|
|
54
|
-
|
|
55
|
-
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
56
|
-
} @finally {
|
|
57
|
-
context.listDepth = prevDepth;
|
|
58
|
-
context.listType = prevType;
|
|
59
|
-
context.listItemNumber = prevNum;
|
|
60
|
-
|
|
61
|
-
if (prevDepth == 0) {
|
|
62
|
-
[context clearBlockStyle];
|
|
99
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
63
100
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
101
|
+
if (prevDepth == 0) {
|
|
102
|
+
applyListItemSpacing(output, context, startLocation, [_config listStyleItemSpacing]);
|
|
103
|
+
// Apply bottom margin for root-level list
|
|
104
|
+
applyBlockSpacingAfter(output, _config.listStyleMarginBottom);
|
|
67
105
|
}
|
|
68
106
|
}
|
|
69
107
|
|
|
70
|
-
@end
|
|
108
|
+
@end
|
|
@@ -7,8 +7,22 @@
|
|
|
7
7
|
|
|
8
8
|
@implementation ParagraphRenderer
|
|
9
9
|
|
|
10
|
-
- (
|
|
10
|
+
- (id)takeContextSnapshot:(RenderContext *)context
|
|
11
11
|
{
|
|
12
|
+
return [context snapshotScope];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
16
|
+
into:(NSMutableAttributedString *)output
|
|
17
|
+
context:(RenderContext *)context
|
|
18
|
+
{
|
|
19
|
+
// Synthetic wrapper around tight list item inlines (see wrapListItemInlineRuns
|
|
20
|
+
// in MD4CParser) — render transparently, the list owns spacing and layout.
|
|
21
|
+
if ([node.attributes[@"tight"] boolValue]) {
|
|
22
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
// Only set block style if a parent element (e.g. List, Blockquote) hasn't already established one
|
|
13
27
|
BOOL isTopLevel = (context.currentBlockType == BlockTypeNone);
|
|
14
28
|
|
|
@@ -33,13 +47,7 @@
|
|
|
33
47
|
start += offset;
|
|
34
48
|
}
|
|
35
49
|
|
|
36
|
-
|
|
37
|
-
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
38
|
-
} @finally {
|
|
39
|
-
if (isTopLevel) {
|
|
40
|
-
[context clearBlockStyle];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
50
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
43
51
|
|
|
44
52
|
if (output.length <= start)
|
|
45
53
|
return;
|
|
@@ -41,6 +41,7 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered };
|
|
|
41
41
|
@property (nonatomic, assign) NSInteger listDepth;
|
|
42
42
|
@property (nonatomic, assign) ListType listType;
|
|
43
43
|
@property (nonatomic, assign) NSInteger listItemNumber;
|
|
44
|
+
@property (nonatomic, assign) CGFloat accumulatedIndent;
|
|
44
45
|
@property (nonatomic, assign) BOOL allowFontScaling;
|
|
45
46
|
@property (nonatomic, assign) CGFloat maxFontSizeMultiplier;
|
|
46
47
|
@property (nonatomic, assign) NSInteger taskItemCount;
|
|
@@ -79,6 +80,15 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered };
|
|
|
79
80
|
- (NSDictionary *)getTextAttributes;
|
|
80
81
|
- (void)clearBlockStyle;
|
|
81
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Captures/restores the scoped context state: block style, block type, heading level,
|
|
85
|
+
* blockquote/list depths, list type, list item counter and accumulated indent.
|
|
86
|
+
* Accumulators (range registries, taskItemCount) are excluded on purpose — they
|
|
87
|
+
* must survive restores.
|
|
88
|
+
*/
|
|
89
|
+
- (id)snapshotScope;
|
|
90
|
+
- (void)restoreScope:(id)snapshot;
|
|
91
|
+
|
|
82
92
|
/**
|
|
83
93
|
* Checks if colors should be preserved based on existing attributes.
|
|
84
94
|
* Returns YES if the text is inside a link or inline code, which means
|
|
@@ -6,6 +6,30 @@
|
|
|
6
6
|
@implementation BlockStyle
|
|
7
7
|
@end
|
|
8
8
|
|
|
9
|
+
static NSArray<NSString *> *ENRMScopedKeyPaths(void)
|
|
10
|
+
{
|
|
11
|
+
static NSArray<NSString *> *keyPaths;
|
|
12
|
+
static dispatch_once_t onceToken;
|
|
13
|
+
dispatch_once(&onceToken, ^{
|
|
14
|
+
keyPaths = @[
|
|
15
|
+
@"currentBlockType",
|
|
16
|
+
@"currentHeadingLevel",
|
|
17
|
+
@"currentBlockStyle.fontSize",
|
|
18
|
+
@"currentBlockStyle.fontFamily",
|
|
19
|
+
@"currentBlockStyle.fontWeight",
|
|
20
|
+
@"currentBlockStyle.color",
|
|
21
|
+
@"currentBlockStyle.cachedFont",
|
|
22
|
+
@"currentBlockStyle.cachedTextAttributes",
|
|
23
|
+
@"blockquoteDepth",
|
|
24
|
+
@"listDepth",
|
|
25
|
+
@"listType",
|
|
26
|
+
@"listItemNumber",
|
|
27
|
+
@"accumulatedIndent",
|
|
28
|
+
];
|
|
29
|
+
});
|
|
30
|
+
return keyPaths;
|
|
31
|
+
}
|
|
32
|
+
|
|
9
33
|
@implementation RenderContext {
|
|
10
34
|
NSMutableDictionary<NSString *, UIFont *> *_fontCache;
|
|
11
35
|
NSParagraphStyle *_baseSpacerTemplate;
|
|
@@ -235,6 +259,25 @@
|
|
|
235
259
|
_currentBlockStyle.cachedTextAttributes = nil;
|
|
236
260
|
}
|
|
237
261
|
|
|
262
|
+
- (id)snapshotScope
|
|
263
|
+
{
|
|
264
|
+
NSArray<NSString *> *keyPaths = ENRMScopedKeyPaths();
|
|
265
|
+
NSMutableDictionary *snapshot = [NSMutableDictionary dictionaryWithCapacity:keyPaths.count];
|
|
266
|
+
for (NSString *keyPath in keyPaths) {
|
|
267
|
+
snapshot[keyPath] = [self valueForKeyPath:keyPath] ?: [NSNull null];
|
|
268
|
+
}
|
|
269
|
+
return snapshot;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
- (void)restoreScope:(id)snapshot
|
|
273
|
+
{
|
|
274
|
+
NSDictionary *frame = snapshot;
|
|
275
|
+
for (NSString *keyPath in ENRMScopedKeyPaths()) {
|
|
276
|
+
id value = frame[keyPath];
|
|
277
|
+
[self setValue:(value == [NSNull null] ? nil : value) forKeyPath:keyPath];
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
238
281
|
#pragma mark - Reset
|
|
239
282
|
|
|
240
283
|
- (void)reset
|
|
@@ -256,6 +299,7 @@
|
|
|
256
299
|
_listDepth = 0;
|
|
257
300
|
_listType = ListTypeUnordered;
|
|
258
301
|
_listItemNumber = 0;
|
|
302
|
+
_accumulatedIndent = 0;
|
|
259
303
|
_taskItemCount = 0;
|
|
260
304
|
|
|
261
305
|
// Revert shared style object to baseline defaults
|
|
@@ -112,6 +112,14 @@
|
|
|
112
112
|
#if ENRICHED_MARKDOWN_MATH
|
|
113
113
|
case MarkdownNodeTypeLatexMathInline:
|
|
114
114
|
return [[ENRMMathInlineRenderer alloc] initWithRendererFactory:self config:_config];
|
|
115
|
+
case MarkdownNodeTypeLatexMathDisplay:
|
|
116
|
+
// Display math INSIDE a paragraph (mid-paragraph / softbreak-adjacent
|
|
117
|
+
// `$$…$$`) previously fell through to the nil-renderer child dump —
|
|
118
|
+
// the body leaked as plain text with its delimiters silently dropped.
|
|
119
|
+
// Typeset it as an inline attachment instead; block-level display math
|
|
120
|
+
// is unaffected (SegmentRenderer intercepts root-level display nodes
|
|
121
|
+
// before this factory is consulted).
|
|
122
|
+
return [[ENRMMathInlineRenderer alloc] initWithRendererFactory:self config:_config];
|
|
115
123
|
#endif
|
|
116
124
|
case MarkdownNodeTypeSpoiler:
|
|
117
125
|
return [[ENRMSpoilerRenderer alloc] initWithRendererFactory:self config:_config];
|
|
@@ -135,6 +143,12 @@
|
|
|
135
143
|
[output appendAttributedString:lineBreak];
|
|
136
144
|
continue;
|
|
137
145
|
}
|
|
146
|
+
if (child.type == MarkdownNodeTypeSoftBreak) {
|
|
147
|
+
NSAttributedString *softBreak = [[NSAttributedString alloc] initWithString:@" "
|
|
148
|
+
attributes:[context getTextAttributes]];
|
|
149
|
+
[output appendAttributedString:softBreak];
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
138
152
|
id<NodeRenderer> renderer = [self rendererForNodeType:child.type];
|
|
139
153
|
if (renderer) {
|
|
140
154
|
[renderer renderNode:child into:output context:context];
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
#pragma mark - Rendering
|
|
10
10
|
|
|
11
|
-
- (void)
|
|
11
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
12
|
+
into:(NSMutableAttributedString *)output
|
|
13
|
+
context:(RenderContext *)context
|
|
12
14
|
{
|
|
13
15
|
NSUInteger start = output.length;
|
|
14
16
|
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
#pragma mark - Rendering
|
|
12
12
|
|
|
13
|
-
- (void)
|
|
13
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
14
|
+
into:(NSMutableAttributedString *)output
|
|
15
|
+
context:(RenderContext *)context
|
|
14
16
|
{
|
|
15
17
|
NSUInteger start = output.length;
|
|
16
18
|
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
@implementation SubscriptRenderer
|
|
9
9
|
|
|
10
|
-
- (void)
|
|
10
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
11
|
+
into:(NSMutableAttributedString *)output
|
|
12
|
+
context:(RenderContext *)context
|
|
11
13
|
{
|
|
12
14
|
NSUInteger start = output.length;
|
|
13
15
|
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
@implementation SuperscriptRenderer
|
|
9
9
|
|
|
10
|
-
- (void)
|
|
10
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
11
|
+
into:(NSMutableAttributedString *)output
|
|
12
|
+
context:(RenderContext *)context
|
|
11
13
|
{
|
|
12
14
|
NSUInteger start = output.length;
|
|
13
15
|
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
@implementation TextRenderer
|
|
5
5
|
|
|
6
|
-
- (void)
|
|
6
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
7
|
+
into:(NSMutableAttributedString *)output
|
|
8
|
+
context:(RenderContext *)context
|
|
7
9
|
{
|
|
8
10
|
if (!node.content)
|
|
9
11
|
return;
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
@implementation ThematicBreakRenderer
|
|
9
9
|
|
|
10
|
-
- (void)
|
|
10
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
11
|
+
into:(NSMutableAttributedString *)output
|
|
12
|
+
context:(RenderContext *)context
|
|
11
13
|
{
|
|
12
14
|
[self ensureStartingNewline:output];
|
|
13
15
|
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
#pragma mark - Rendering
|
|
10
10
|
|
|
11
|
-
- (void)
|
|
11
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
12
|
+
into:(NSMutableAttributedString *)output
|
|
13
|
+
context:(RenderContext *)context
|
|
12
14
|
{
|
|
13
15
|
NSUInteger start = output.length;
|
|
14
16
|
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|