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
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import "ENRMBlockRange.h"
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
/// Stores the block-level (paragraph-scoped) ranges for the editor, mirroring
|
|
8
|
+
/// ENRMFormattingStore. Unlike inline ranges, block ranges never overlap: at
|
|
9
|
+
/// most one block covers any given paragraph, and ranges are kept normalized to
|
|
10
|
+
/// whole-line boundaries.
|
|
11
|
+
@interface ENRMBlockStore : NSObject
|
|
12
|
+
|
|
13
|
+
@property (nonatomic, readonly) NSArray<ENRMBlockRange *> *allRanges;
|
|
14
|
+
|
|
15
|
+
/// Returns the block whose paragraph starts exactly at `location`, or nil.
|
|
16
|
+
/// Ranges are kept sorted by start, so this is an O(log n) binary search — the
|
|
17
|
+
/// single lookup callers use instead of linearly scanning `allRanges`. Relies on
|
|
18
|
+
/// the one-block-per-paragraph invariant (paragraph starts are unique).
|
|
19
|
+
- (nullable ENRMBlockRange *)blockStartingAtLocation:(NSUInteger)location;
|
|
20
|
+
|
|
21
|
+
- (void)setRanges:(NSArray<ENRMBlockRange *> *)ranges;
|
|
22
|
+
- (void)clearAll;
|
|
23
|
+
|
|
24
|
+
/// Sets/replaces the block on every paragraph the given range touches, expanding
|
|
25
|
+
/// to whole-line boundaries within `text`. Removes any block previously covering
|
|
26
|
+
/// those paragraphs.
|
|
27
|
+
- (void)setBlockType:(ENRMInputBlockType)type
|
|
28
|
+
level:(NSInteger)level
|
|
29
|
+
forParagraphRange:(NSRange)range
|
|
30
|
+
inText:(NSString *)text;
|
|
31
|
+
|
|
32
|
+
/// Clears any block on the paragraphs the given range touches (reverting them to
|
|
33
|
+
/// the implicit paragraph default).
|
|
34
|
+
- (void)removeBlockInParagraphRange:(NSRange)range inText:(NSString *)text;
|
|
35
|
+
|
|
36
|
+
/// Shifts/clips block ranges to follow a text edit (shared
|
|
37
|
+
/// ENRMRangeEditAdjustment classification), with heading persistence: a heading
|
|
38
|
+
/// deleted exactly to its end collapses to a zero-length anchor at the edit
|
|
39
|
+
/// location (its line survives), and existing anchors shift/keep/drop with
|
|
40
|
+
/// their line.
|
|
41
|
+
- (void)adjustForEditAtLocation:(NSUInteger)location
|
|
42
|
+
deletedLength:(NSUInteger)deletedLength
|
|
43
|
+
insertedLength:(NSUInteger)insertedLength;
|
|
44
|
+
|
|
45
|
+
/// Snaps every stored range to the line bounds of its start position.
|
|
46
|
+
/// Absorbs edge-typed chars, clips split ranges to first line, drops
|
|
47
|
+
/// duplicates. On an empty line a heading persists as a zero-length anchor;
|
|
48
|
+
/// any other collapsed range is dropped. List depths are clamped so an item
|
|
49
|
+
/// nests at most one level under the previous adjacent item (CommonMark cannot
|
|
50
|
+
/// represent orphan nesting). Call after adjustForEditAtLocation: once text is
|
|
51
|
+
/// final. Idempotent.
|
|
52
|
+
- (void)normalizeToLineBoundsInText:(NSString *)text;
|
|
53
|
+
|
|
54
|
+
@end
|
|
55
|
+
|
|
56
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#import "ENRMBlockStore.h"
|
|
2
|
+
#import "ENRMRangeEditAdjustment.h"
|
|
3
|
+
#import "ENRMRangeStoreUtils.h"
|
|
4
|
+
|
|
5
|
+
/// Expands a selection to cover whole paragraphs (line-scoped block boundaries).
|
|
6
|
+
/// Clamps unconditionally so out-of-bounds input can't reach
|
|
7
|
+
/// paragraphRangeForRange: (which raises on an invalid range).
|
|
8
|
+
static NSRange paragraphBoundsForRange(NSRange range, NSString *text)
|
|
9
|
+
{
|
|
10
|
+
if (text.length == 0) {
|
|
11
|
+
return NSMakeRange(0, 0);
|
|
12
|
+
}
|
|
13
|
+
NSUInteger location = MIN(range.location, text.length);
|
|
14
|
+
NSUInteger length = MIN(range.length, text.length - location);
|
|
15
|
+
return [text paragraphRangeForRange:NSMakeRange(location, length)];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@implementation ENRMBlockStore {
|
|
19
|
+
NSMutableArray<ENRMBlockRange *> *_ranges;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (instancetype)init
|
|
23
|
+
{
|
|
24
|
+
if (self = [super init]) {
|
|
25
|
+
_ranges = [NSMutableArray array];
|
|
26
|
+
}
|
|
27
|
+
return self;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
- (NSArray<ENRMBlockRange *> *)allRanges
|
|
31
|
+
{
|
|
32
|
+
return [_ranges copy];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (nullable ENRMBlockRange *)blockStartingAtLocation:(NSUInteger)location
|
|
36
|
+
{
|
|
37
|
+
NSInteger lo = 0;
|
|
38
|
+
NSInteger hi = (NSInteger)_ranges.count - 1;
|
|
39
|
+
while (lo <= hi) {
|
|
40
|
+
NSInteger mid = (lo + hi) / 2;
|
|
41
|
+
NSUInteger start = _ranges[(NSUInteger)mid].range.location;
|
|
42
|
+
if (start < location) {
|
|
43
|
+
lo = mid + 1;
|
|
44
|
+
} else if (start > location) {
|
|
45
|
+
hi = mid - 1;
|
|
46
|
+
} else {
|
|
47
|
+
return _ranges[(NSUInteger)mid];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return nil;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Incoming ranges are trusted to be non-overlapping and line-scoped — the
|
|
54
|
+
// parser owns that invariant (md4c block structure never overlaps at the same
|
|
55
|
+
// nesting level, and nested containers are not yet mapped). Revisit enforcement
|
|
56
|
+
// here if a container block type (list, blockquote) is added.
|
|
57
|
+
- (void)setRanges:(NSArray<ENRMBlockRange *> *)ranges
|
|
58
|
+
{
|
|
59
|
+
_ranges = [[ranges sortedArrayUsingComparator:^NSComparisonResult(ENRMBlockRange *first, ENRMBlockRange *second) {
|
|
60
|
+
if (first.range.location < second.range.location)
|
|
61
|
+
return NSOrderedAscending;
|
|
62
|
+
if (first.range.location > second.range.location)
|
|
63
|
+
return NSOrderedDescending;
|
|
64
|
+
return NSOrderedSame;
|
|
65
|
+
}] mutableCopy];
|
|
66
|
+
[self recomputeListMetadata];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
- (void)clearAll
|
|
70
|
+
{
|
|
71
|
+
[_ranges removeAllObjects];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// Drops any stored block overlapping `paragraphRange` so a replacement can be
|
|
75
|
+
/// inserted cleanly. Blocks are line-scoped and never partially overlap, so a
|
|
76
|
+
/// touched block is removed wholesale.
|
|
77
|
+
- (void)removeBlocksOverlappingRange:(NSRange)paragraphRange
|
|
78
|
+
{
|
|
79
|
+
NSUInteger removeStart = paragraphRange.location;
|
|
80
|
+
NSUInteger removeEnd = NSMaxRange(paragraphRange);
|
|
81
|
+
NSMutableIndexSet *indexesToRemove = [NSMutableIndexSet indexSet];
|
|
82
|
+
|
|
83
|
+
for (NSUInteger idx = 0; idx < _ranges.count; idx++) {
|
|
84
|
+
ENRMBlockRange *existing = _ranges[idx];
|
|
85
|
+
NSUInteger existingStart = existing.range.location;
|
|
86
|
+
NSUInteger existingEnd = NSMaxRange(existing.range);
|
|
87
|
+
|
|
88
|
+
// A zero-length anchor occupies a point, so the half-open overlap test
|
|
89
|
+
// never matches it; drop one whose anchor lies within the removal bounds.
|
|
90
|
+
if (existing.range.length == 0) {
|
|
91
|
+
if (existingStart >= removeStart && existingStart <= removeEnd) {
|
|
92
|
+
[indexesToRemove addIndex:idx];
|
|
93
|
+
}
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (existingEnd <= removeStart || existingStart >= removeEnd) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
[indexesToRemove addIndex:idx];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
ENRMRemoveIndexesInReverse(_ranges, indexesToRemove);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
- (void)setBlockType:(ENRMInputBlockType)type
|
|
107
|
+
level:(NSInteger)level
|
|
108
|
+
forParagraphRange:(NSRange)range
|
|
109
|
+
inText:(NSString *)text
|
|
110
|
+
{
|
|
111
|
+
NSRange paragraphRange = paragraphBoundsForRange(range, text);
|
|
112
|
+
[self removeBlocksOverlappingRange:paragraphRange];
|
|
113
|
+
|
|
114
|
+
paragraphRange = ENRMTrimLineTerminators(paragraphRange, text);
|
|
115
|
+
|
|
116
|
+
if (paragraphRange.length == 0 && !ENRMBlockTypePersistsWhenEmpty(type)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
ENRMBlockRange *blockRange = [ENRMBlockRange rangeWithType:type range:paragraphRange level:level];
|
|
121
|
+
NSUInteger insertAt = ENRMSortedInsertionIndex(
|
|
122
|
+
_ranges, blockRange.range.location, ^NSUInteger(id range) { return ((ENRMBlockRange *)range).range.location; });
|
|
123
|
+
[_ranges insertObject:blockRange atIndex:insertAt];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
- (void)removeBlockInParagraphRange:(NSRange)range inText:(NSString *)text
|
|
127
|
+
{
|
|
128
|
+
NSRange paragraphRange = paragraphBoundsForRange(range, text);
|
|
129
|
+
[self removeBlocksOverlappingRange:paragraphRange];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
- (void)adjustForEditAtLocation:(NSUInteger)editLocation
|
|
133
|
+
deletedLength:(NSUInteger)deletedLength
|
|
134
|
+
insertedLength:(NSUInteger)insertedLength
|
|
135
|
+
{
|
|
136
|
+
if (deletedLength == 0 && insertedLength == 0)
|
|
137
|
+
return;
|
|
138
|
+
|
|
139
|
+
NSUInteger deleteEnd = editLocation + deletedLength;
|
|
140
|
+
NSMutableIndexSet *indexesToRemove = [NSMutableIndexSet indexSet];
|
|
141
|
+
|
|
142
|
+
for (NSUInteger idx = 0; idx < _ranges.count; idx++) {
|
|
143
|
+
ENRMBlockRange *blockRange = _ranges[idx];
|
|
144
|
+
BOOL persists = ENRMBlockTypePersistsWhenEmpty(blockRange.type);
|
|
145
|
+
|
|
146
|
+
// Zero-length anchors don't follow the shared adjustment: one at the edit
|
|
147
|
+
// location stays put (normalize grows it over the typed text), one past
|
|
148
|
+
// the edit shifts with it, one inside the deletion is dropped.
|
|
149
|
+
if (blockRange.range.length == 0) {
|
|
150
|
+
if (!persists) {
|
|
151
|
+
[indexesToRemove addIndex:idx];
|
|
152
|
+
} else if (blockRange.range.location >= deleteEnd && blockRange.range.location > editLocation) {
|
|
153
|
+
blockRange.range = NSMakeRange(blockRange.range.location - deletedLength + insertedLength, 0);
|
|
154
|
+
} else if (blockRange.range.location > editLocation) {
|
|
155
|
+
[indexesToRemove addIndex:idx]; // anchor sat inside the deleted region
|
|
156
|
+
}
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
ENRMAdjustedRange adjusted = ENRMAdjustRangeForEdit(blockRange.range, editLocation, deletedLength, insertedLength,
|
|
161
|
+
/* inheritsReplacementAtStart */ YES,
|
|
162
|
+
/* growsAtStartOnInsert */ YES);
|
|
163
|
+
if (adjusted.shouldRemove) {
|
|
164
|
+
// A persisting block deleted exactly to its end collapses to a zero-length
|
|
165
|
+
// anchor (the line's newline survived, so the line stays the block); a
|
|
166
|
+
// deletion running past its end removed the line, so drop the block with it.
|
|
167
|
+
if (persists && NSMaxRange(blockRange.range) == deleteEnd && blockRange.range.location >= editLocation) {
|
|
168
|
+
blockRange.range = NSMakeRange(editLocation, 0);
|
|
169
|
+
} else {
|
|
170
|
+
[indexesToRemove addIndex:idx];
|
|
171
|
+
}
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
blockRange.range = adjusted.range;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
ENRMRemoveIndexesInReverse(_ranges, indexesToRemove);
|
|
178
|
+
|
|
179
|
+
// Prune zero-length ranges, but keep zero-length persisting blocks: they anchor
|
|
180
|
+
// an emptied-but-still-present heading/bullet line (see the collapse rule above).
|
|
181
|
+
NSMutableIndexSet *emptyIndexes = [NSMutableIndexSet indexSet];
|
|
182
|
+
for (NSUInteger idx = 0; idx < _ranges.count; idx++) {
|
|
183
|
+
ENRMBlockRange *range = _ranges[idx];
|
|
184
|
+
if (range.range.length == 0 && !ENRMBlockTypePersistsWhenEmpty(range.type)) {
|
|
185
|
+
[emptyIndexes addIndex:idx];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (emptyIndexes.count > 0) {
|
|
189
|
+
ENRMRemoveIndexesInReverse(_ranges, emptyIndexes);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
- (void)normalizeToLineBoundsInText:(NSString *)text
|
|
194
|
+
{
|
|
195
|
+
if (_ranges.count == 0) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
NSMutableIndexSet *indexesToRemove = [NSMutableIndexSet indexSet];
|
|
200
|
+
NSInteger previousEnd = -1;
|
|
201
|
+
|
|
202
|
+
for (NSUInteger idx = 0; idx < _ranges.count; idx++) {
|
|
203
|
+
ENRMBlockRange *blockRange = _ranges[idx];
|
|
204
|
+
NSRange lineRange = paragraphBoundsForRange(NSMakeRange(blockRange.range.location, 0), text);
|
|
205
|
+
|
|
206
|
+
lineRange = ENRMTrimLineTerminators(lineRange, text);
|
|
207
|
+
|
|
208
|
+
BOOL emptyLine = lineRange.length == 0;
|
|
209
|
+
if ((emptyLine && !ENRMBlockTypePersistsWhenEmpty(blockRange.type)) ||
|
|
210
|
+
(NSInteger)lineRange.location <= previousEnd) {
|
|
211
|
+
// Dedup: drop a range that resolves to an already-claimed paragraph. This is a
|
|
212
|
+
// legitimate self-heal path (a heading anchor and the block it merges into can
|
|
213
|
+
// briefly share a start after a line-join), so it is deliberately silent — it
|
|
214
|
+
// cannot distinguish that benign case from genuine corruption, so it does not
|
|
215
|
+
// assert here.
|
|
216
|
+
[indexesToRemove addIndex:idx];
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
blockRange.range = lineRange;
|
|
221
|
+
previousEnd = (NSInteger)NSMaxRange(lineRange);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
ENRMRemoveIndexesInReverse(_ranges, indexesToRemove);
|
|
225
|
+
[self recomputeListMetadata];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/// Clamps list depths to valid ancestry (an item nests at most one level under
|
|
229
|
+
/// the previous adjacent list item — CommonMark cannot represent orphan nesting)
|
|
230
|
+
/// and renumbers ordered items among their adjacent same-depth, same-type run.
|
|
231
|
+
- (void)recomputeListMetadata
|
|
232
|
+
{
|
|
233
|
+
NSInteger prevEnd = -2;
|
|
234
|
+
NSInteger prevDepth = -1;
|
|
235
|
+
NSInteger counters[kENRMMaxListDepth + 2];
|
|
236
|
+
ENRMInputBlockType counterTypes[kENRMMaxListDepth + 2];
|
|
237
|
+
memset(counters, 0, sizeof(counters));
|
|
238
|
+
memset(counterTypes, 0, sizeof(counterTypes));
|
|
239
|
+
|
|
240
|
+
for (ENRMBlockRange *blockRange in _ranges) {
|
|
241
|
+
if (!ENRMBlockTypeIsListItem(blockRange.type)) {
|
|
242
|
+
prevDepth = -1;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
BOOL adjacent = prevDepth >= 0 && (NSInteger)blockRange.range.location == prevEnd + 1;
|
|
246
|
+
if (!adjacent) {
|
|
247
|
+
memset(counters, 0, sizeof(counters));
|
|
248
|
+
memset(counterTypes, 0, sizeof(counterTypes));
|
|
249
|
+
}
|
|
250
|
+
// Coerce into [0, kENRMMaxListDepth] before ancestry-clamping: parser and
|
|
251
|
+
// indent commands cap their depths, but this pass indexes the counter
|
|
252
|
+
// arrays by depth, so an out-of-bounds level must never survive it.
|
|
253
|
+
NSInteger maxDepth = MIN(adjacent ? prevDepth + 1 : 0, kENRMMaxListDepth);
|
|
254
|
+
if (blockRange.level > maxDepth) {
|
|
255
|
+
blockRange.level = maxDepth;
|
|
256
|
+
} else if (blockRange.level < 0) {
|
|
257
|
+
blockRange.level = 0;
|
|
258
|
+
}
|
|
259
|
+
NSInteger depth = blockRange.level;
|
|
260
|
+
for (NSInteger i = depth + 1; i <= kENRMMaxListDepth + 1; i++) {
|
|
261
|
+
counters[i] = 0;
|
|
262
|
+
counterTypes[i] = (ENRMInputBlockType)0;
|
|
263
|
+
}
|
|
264
|
+
if (counterTypes[depth] != blockRange.type) {
|
|
265
|
+
counters[depth] = 0;
|
|
266
|
+
counterTypes[depth] = blockRange.type;
|
|
267
|
+
}
|
|
268
|
+
counters[depth]++;
|
|
269
|
+
blockRange.ordinal = counters[depth];
|
|
270
|
+
prevEnd = (NSInteger)NSMaxRange(blockRange.range);
|
|
271
|
+
prevDepth = blockRange.level;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
@end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import "ENRMBlockRange.h"
|
|
4
|
+
#import "ENRMFormattingRange.h"
|
|
5
|
+
#import "ENRMMathAtom.h"
|
|
6
|
+
#import <Foundation/Foundation.h>
|
|
7
|
+
|
|
8
|
+
@class ENRMFormattingStore;
|
|
9
|
+
@class ENRMBlockStore;
|
|
10
|
+
@class ENRMInputFormatter;
|
|
11
|
+
@protocol ENRMDetectorPipelineTransientRanges;
|
|
12
|
+
|
|
13
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
14
|
+
|
|
15
|
+
@protocol ENRMTransientRangeProvider <NSObject>
|
|
16
|
+
- (NSArray<ENRMFormattingRange *> *)allTransientFormattingRanges;
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@interface ENRMClipboardCoordinator : NSObject
|
|
20
|
+
|
|
21
|
+
- (instancetype)initWithFormattingStore:(ENRMFormattingStore *)formattingStore
|
|
22
|
+
blockStore:(ENRMBlockStore *)blockStore
|
|
23
|
+
transientRangeProvider:(id<ENRMTransientRangeProvider>)transientRangeProvider
|
|
24
|
+
formatter:(ENRMInputFormatter *)formatter;
|
|
25
|
+
|
|
26
|
+
- (NSArray<ENRMFormattingRange *> *)allRangesIncludingTransient;
|
|
27
|
+
|
|
28
|
+
/// `mathAtoms` positions are offsets into `text`. Pass `@[]` only for text that
|
|
29
|
+
/// genuinely holds no chip — every path that serializes the live buffer must
|
|
30
|
+
/// carry its chips, or each formula leaves the editor as a bare placeholder
|
|
31
|
+
/// character instead of `$latex$`.
|
|
32
|
+
- (NSString *)serializeText:(NSString *)text
|
|
33
|
+
mathAtoms:(NSArray<ENRMMathAtom *> *)mathAtoms
|
|
34
|
+
ranges:(NSArray<ENRMFormattingRange *> *)ranges
|
|
35
|
+
blockRanges:(NSArray<ENRMBlockRange *> *)blockRanges;
|
|
36
|
+
|
|
37
|
+
- (NSString *)serializeFullDocument:(NSString *)plainText mathAtoms:(NSArray<ENRMMathAtom *> *)mathAtoms;
|
|
38
|
+
|
|
39
|
+
- (nullable NSString *)serializeSelectedRange:(NSRange)selection
|
|
40
|
+
inText:(NSString *)fullText
|
|
41
|
+
mathAtoms:(NSArray<ENRMMathAtom *> *)mathAtoms;
|
|
42
|
+
|
|
43
|
+
@end
|
|
44
|
+
|
|
45
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#import "ENRMClipboardCoordinator.h"
|
|
2
|
+
#import "ENRMBlockStore.h"
|
|
3
|
+
#import "ENRMFormattingStore.h"
|
|
4
|
+
#import "ENRMInputFormatter.h"
|
|
5
|
+
#import "ENRMMarkdownSerializer.h"
|
|
6
|
+
#import "styles/ENRMBlockHandler.h"
|
|
7
|
+
|
|
8
|
+
@implementation ENRMClipboardCoordinator {
|
|
9
|
+
ENRMFormattingStore *_formattingStore;
|
|
10
|
+
ENRMBlockStore *_blockStore;
|
|
11
|
+
id<ENRMTransientRangeProvider> _transientRangeProvider;
|
|
12
|
+
ENRMInputFormatter *_formatter;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
- (instancetype)initWithFormattingStore:(ENRMFormattingStore *)formattingStore
|
|
16
|
+
blockStore:(ENRMBlockStore *)blockStore
|
|
17
|
+
transientRangeProvider:(id<ENRMTransientRangeProvider>)transientRangeProvider
|
|
18
|
+
formatter:(ENRMInputFormatter *)formatter
|
|
19
|
+
{
|
|
20
|
+
if (self = [super init]) {
|
|
21
|
+
_formattingStore = formattingStore;
|
|
22
|
+
_blockStore = blockStore;
|
|
23
|
+
_transientRangeProvider = transientRangeProvider;
|
|
24
|
+
_formatter = formatter;
|
|
25
|
+
}
|
|
26
|
+
return self;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (NSArray<ENRMFormattingRange *> *)allRangesIncludingTransient
|
|
30
|
+
{
|
|
31
|
+
NSArray<ENRMFormattingRange *> *transient = [_transientRangeProvider allTransientFormattingRanges];
|
|
32
|
+
if (transient.count == 0) {
|
|
33
|
+
return _formattingStore.allRanges;
|
|
34
|
+
}
|
|
35
|
+
NSMutableArray<ENRMFormattingRange *> *merged = [_formattingStore.allRanges mutableCopy];
|
|
36
|
+
[merged addObjectsFromArray:transient];
|
|
37
|
+
return merged;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
- (NSString *)serializeText:(NSString *)text
|
|
41
|
+
mathAtoms:(NSArray<ENRMMathAtom *> *)mathAtoms
|
|
42
|
+
ranges:(NSArray<ENRMFormattingRange *> *)ranges
|
|
43
|
+
blockRanges:(NSArray<ENRMBlockRange *> *)blockRanges
|
|
44
|
+
{
|
|
45
|
+
ENRMInputFormatter *formatter = _formatter;
|
|
46
|
+
return [ENRMMarkdownSerializer serializePlainText:text
|
|
47
|
+
mathAtoms:mathAtoms
|
|
48
|
+
ranges:ranges
|
|
49
|
+
blockRanges:blockRanges
|
|
50
|
+
blockPrefixProvider:^NSString *(ENRMBlockRange *blockRange) {
|
|
51
|
+
id<ENRMBlockHandler> handler = [formatter handlerForBlockType:blockRange.type];
|
|
52
|
+
return [handler markdownLinePrefixForBlockRange:blockRange];
|
|
53
|
+
}];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
- (NSString *)serializeFullDocument:(NSString *)plainText mathAtoms:(NSArray<ENRMMathAtom *> *)mathAtoms
|
|
57
|
+
{
|
|
58
|
+
return [self serializeText:plainText
|
|
59
|
+
mathAtoms:mathAtoms
|
|
60
|
+
ranges:[self allRangesIncludingTransient]
|
|
61
|
+
blockRanges:_blockStore.allRanges];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (nullable NSString *)serializeSelectedRange:(NSRange)selection
|
|
65
|
+
inText:(NSString *)fullText
|
|
66
|
+
mathAtoms:(NSArray<ENRMMathAtom *> *)mathAtoms
|
|
67
|
+
{
|
|
68
|
+
if (selection.length == 0) {
|
|
69
|
+
return nil;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
NSString *selectedText = [fullText substringWithRange:selection];
|
|
73
|
+
NSUInteger selEnd = NSMaxRange(selection);
|
|
74
|
+
|
|
75
|
+
NSMutableArray<ENRMFormattingRange *> *clippedRanges = [NSMutableArray array];
|
|
76
|
+
for (ENRMFormattingRange *range in [self allRangesIncludingTransient]) {
|
|
77
|
+
NSUInteger rangeStart = range.range.location;
|
|
78
|
+
NSUInteger rangeEnd = NSMaxRange(range.range);
|
|
79
|
+
if (rangeEnd <= selection.location || rangeStart >= selEnd) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
NSUInteger clippedStart = MAX(rangeStart, selection.location);
|
|
83
|
+
NSUInteger clippedEnd = MIN(rangeEnd, selEnd);
|
|
84
|
+
NSRange shifted = NSMakeRange(clippedStart - selection.location, clippedEnd - clippedStart);
|
|
85
|
+
[clippedRanges addObject:[ENRMFormattingRange rangeWithType:range.type range:shifted url:range.url]];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
NSMutableArray<ENRMBlockRange *> *clippedBlockRanges = [NSMutableArray array];
|
|
89
|
+
for (ENRMBlockRange *blockRange in _blockStore.allRanges) {
|
|
90
|
+
NSUInteger rangeStart = blockRange.range.location;
|
|
91
|
+
NSUInteger rangeEnd = NSMaxRange(blockRange.range);
|
|
92
|
+
if (rangeEnd <= selection.location || rangeStart >= selEnd) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
NSUInteger clippedStart = MAX(rangeStart, selection.location);
|
|
96
|
+
NSUInteger clippedEnd = MIN(rangeEnd, selEnd);
|
|
97
|
+
NSRange shifted = NSMakeRange(clippedStart - selection.location, clippedEnd - clippedStart);
|
|
98
|
+
[clippedBlockRanges addObject:[ENRMBlockRange rangeWithType:blockRange.type range:shifted level:blockRange.level]];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// A chip is a single character, so it is cleanly inside or outside the
|
|
102
|
+
// selection; rebase the survivors onto the substring like the ranges above.
|
|
103
|
+
// Copying part of a document must serialize its formulas, not the bare
|
|
104
|
+
// placeholder character.
|
|
105
|
+
NSMutableArray<ENRMMathAtom *> *clippedAtoms = [NSMutableArray array];
|
|
106
|
+
for (ENRMMathAtom *atom in mathAtoms) {
|
|
107
|
+
if (atom.position < selection.location || atom.position >= selEnd) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
ENRMMathAtom *clipped = [[ENRMMathAtom alloc] init];
|
|
111
|
+
clipped.position = atom.position - selection.location;
|
|
112
|
+
clipped.latex = atom.latex;
|
|
113
|
+
clipped.displayMode = atom.displayMode;
|
|
114
|
+
[clippedAtoms addObject:clipped];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return [self serializeText:selectedText mathAtoms:clippedAtoms ranges:clippedRanges blockRanges:clippedBlockRanges];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#import "ENRMClipboardCoordinator.h"
|
|
3
4
|
#import "ENRMFormattingRange.h"
|
|
4
5
|
#import "ENRMTextDetector.h"
|
|
5
6
|
#import <Foundation/Foundation.h>
|
|
@@ -8,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
8
9
|
|
|
9
10
|
/// Coordinates a set of ENRMTextDetector instances. The input view calls
|
|
10
11
|
/// this pipeline instead of individual detectors.
|
|
11
|
-
@interface ENRMDetectorPipeline : NSObject
|
|
12
|
+
@interface ENRMDetectorPipeline : NSObject <ENRMTransientRangeProvider>
|
|
12
13
|
|
|
13
14
|
- (void)addDetector:(id<ENRMTextDetector>)detector;
|
|
14
15
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#import "ENRMInputBlockType.h"
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
@class ENRMBlockStore;
|
|
5
|
+
@class ENRMFormattingStore;
|
|
6
|
+
@class ENRMInputFormatter;
|
|
7
|
+
@class ENRMDetectorPipeline;
|
|
8
|
+
@class ENRMBlockRange;
|
|
9
|
+
|
|
10
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
11
|
+
|
|
12
|
+
/// Immutable snapshot of everything the pipeline needs to process a single text change.
|
|
13
|
+
@interface ENRMEditContext : NSObject
|
|
14
|
+
@property (nonatomic, readonly) NSUInteger editLocation;
|
|
15
|
+
@property (nonatomic, readonly) NSUInteger deletedLength;
|
|
16
|
+
@property (nonatomic, readonly) NSUInteger insertedLength;
|
|
17
|
+
@property (nonatomic, readonly) BOOL preEditReplacedNewline;
|
|
18
|
+
@property (nonatomic, readonly) ENRMInputBlockType preEditBlockType;
|
|
19
|
+
@property (nonatomic, readonly) NSInteger preEditBlockLevel;
|
|
20
|
+
@property (nonatomic, readonly) BOOL preEditParagraphWasEmpty;
|
|
21
|
+
@property (nonatomic, readonly) NSSet<NSNumber *> *pendingStyles;
|
|
22
|
+
@property (nonatomic, readonly) NSSet<NSNumber *> *pendingStyleRemovals;
|
|
23
|
+
|
|
24
|
+
- (instancetype)initWithEditLocation:(NSUInteger)editLocation
|
|
25
|
+
deletedLength:(NSUInteger)deletedLength
|
|
26
|
+
insertedLength:(NSUInteger)insertedLength
|
|
27
|
+
preEditReplacedNewline:(BOOL)preEditReplacedNewline
|
|
28
|
+
preEditBlockType:(ENRMInputBlockType)preEditBlockType
|
|
29
|
+
preEditBlockLevel:(NSInteger)preEditBlockLevel
|
|
30
|
+
preEditParagraphWasEmpty:(BOOL)preEditParagraphWasEmpty
|
|
31
|
+
pendingStyles:(NSSet<NSNumber *> *)pendingStyles
|
|
32
|
+
pendingStyleRemovals:(NSSet<NSNumber *> *)pendingStyleRemovals;
|
|
33
|
+
@end
|
|
34
|
+
|
|
35
|
+
/// View-specific operations the pipeline delegates back to its host.
|
|
36
|
+
@protocol ENRMEditPipelineHost <NSObject>
|
|
37
|
+
- (NSString *)plainText;
|
|
38
|
+
- (NSTextStorage *)textStorage;
|
|
39
|
+
@end
|
|
40
|
+
|
|
41
|
+
/// Orchestrates the data-model phases of the per-keystroke edit pipeline:
|
|
42
|
+
/// store adjustment, orphan pruning, pending styles, and block continuation.
|
|
43
|
+
///
|
|
44
|
+
/// Formatting (which needs `_textView`, `_formatterStyle`, `ENRMEditPhaseFormatting`)
|
|
45
|
+
/// and UI updates (typing attributes, placeholder, events, height) stay on the view.
|
|
46
|
+
/// The pipeline tells the view whether the edit touched a newline so the view can
|
|
47
|
+
/// pick full vs scoped formatting.
|
|
48
|
+
@interface ENRMEditPipeline : NSObject
|
|
49
|
+
|
|
50
|
+
- (instancetype)initWithFormattingStore:(ENRMFormattingStore *)formattingStore
|
|
51
|
+
blockStore:(ENRMBlockStore *)blockStore
|
|
52
|
+
formatter:(ENRMInputFormatter *)formatter
|
|
53
|
+
detectorPipeline:(ENRMDetectorPipeline *)detectorPipeline
|
|
54
|
+
host:(id<ENRMEditPipelineHost>)host;
|
|
55
|
+
|
|
56
|
+
/// Runs the data-model phases of the edit pipeline and returns YES if the edit
|
|
57
|
+
/// touched a newline (so the view should do a full-document reformat rather than
|
|
58
|
+
/// a scoped one).
|
|
59
|
+
- (BOOL)processTextChangeWithContext:(ENRMEditContext *)context;
|
|
60
|
+
|
|
61
|
+
/// Drops anchored blocks no longer at a line start. Exposed so the view's
|
|
62
|
+
/// `adjustStoresForEditAtLocation:` can call it too.
|
|
63
|
+
- (void)pruneOrphanedBlockAnchors;
|
|
64
|
+
|
|
65
|
+
/// Adjusts both stores for an edit delta, prunes orphans, normalizes.
|
|
66
|
+
/// Exposed for the view's programmatic text-mutation path.
|
|
67
|
+
- (NSString *)adjustStoresForEditAtLocation:(NSUInteger)editLocation
|
|
68
|
+
deletedLength:(NSUInteger)deletedLength
|
|
69
|
+
insertedLength:(NSUInteger)insertedLength;
|
|
70
|
+
|
|
71
|
+
/// Runs the detector pipeline on the edited portion of the text.
|
|
72
|
+
- (void)detectLinksAtLocation:(NSUInteger)editLocation insertedLength:(NSUInteger)insertedLength;
|
|
73
|
+
|
|
74
|
+
@end
|
|
75
|
+
|
|
76
|
+
NS_ASSUME_NONNULL_END
|