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,476 @@
|
|
|
1
|
+
#import "ENRMMathChipController.h"
|
|
2
|
+
|
|
3
|
+
#import "ENRMFeatureFlags.h"
|
|
4
|
+
|
|
5
|
+
// The single gate for math chips in the editor. `ENRMMathInlineAttachment` does
|
|
6
|
+
// not exist as a class in a math-disabled build (its whole @implementation is
|
|
7
|
+
// compiled out), so this has to be a preprocessor split, not a runtime flag: an
|
|
8
|
+
// unconditional reference here compiles clean and fails at link with
|
|
9
|
+
// "Undefined symbols: _OBJC_CLASS_$_ENRMMathInlineAttachment".
|
|
10
|
+
//
|
|
11
|
+
// The inert twin at the bottom of the file is what lets the host call straight
|
|
12
|
+
// through with no guards of its own — the iOS counterpart of Android returning a
|
|
13
|
+
// null `MathChipController`.
|
|
14
|
+
#if ENRICHED_MARKDOWN_MATH
|
|
15
|
+
|
|
16
|
+
#import "ENRMMathFontWeight.h"
|
|
17
|
+
#import "ENRMMathInlineAttachment.h"
|
|
18
|
+
#import "ENRMTextHitTest.h"
|
|
19
|
+
|
|
20
|
+
/// Fallback point sizes when `markdownStyle` carries none. Block math reads
|
|
21
|
+
/// larger than inline math by convention.
|
|
22
|
+
static const CGFloat kENRMDefaultInlineMathFontSize = 16.0;
|
|
23
|
+
static const CGFloat kENRMDefaultBlockMathFontSize = 20.0;
|
|
24
|
+
|
|
25
|
+
@implementation ENRMMathChipController {
|
|
26
|
+
__weak ENRMPlatformTextView *_textView;
|
|
27
|
+
ENRMInputFormatterStyle *_style;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
+ (BOOL)isAvailable
|
|
31
|
+
{
|
|
32
|
+
return YES;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (instancetype)initWithTextView:(ENRMPlatformTextView *)textView style:(ENRMInputFormatterStyle *)style
|
|
36
|
+
{
|
|
37
|
+
if (self = [super init]) {
|
|
38
|
+
_textView = textView;
|
|
39
|
+
_style = style;
|
|
40
|
+
}
|
|
41
|
+
return self;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#pragma mark - Reading
|
|
45
|
+
|
|
46
|
+
- (nullable NSTextStorage *)storage
|
|
47
|
+
{
|
|
48
|
+
NSTextStorage *storage = _textView.textStorage;
|
|
49
|
+
return storage.length > 0 ? storage : nil;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// The chip attachment at `position`, or nil. Checks the attribute rather than
|
|
53
|
+
/// the character: a placeholder with no attachment is a chip that has not been
|
|
54
|
+
/// stamped yet, and must not be mistaken for one that has.
|
|
55
|
+
- (nullable ENRMMathInlineAttachment *)attachmentAtPosition:(NSUInteger)position inStorage:(NSTextStorage *)storage
|
|
56
|
+
{
|
|
57
|
+
if (position >= storage.length) {
|
|
58
|
+
return nil;
|
|
59
|
+
}
|
|
60
|
+
id value = [storage attribute:NSAttachmentAttributeName atIndex:position effectiveRange:NULL];
|
|
61
|
+
return [value isKindOfClass:[ENRMMathInlineAttachment class]] ? value : nil;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (ENRMMathAtom *)atomFromAttachment:(ENRMMathInlineAttachment *)attachment atPosition:(NSUInteger)position
|
|
65
|
+
{
|
|
66
|
+
ENRMMathAtom *atom = [[ENRMMathAtom alloc] init];
|
|
67
|
+
atom.position = position;
|
|
68
|
+
atom.latex = attachment.latex ?: @"";
|
|
69
|
+
atom.displayMode = attachment.displayMode;
|
|
70
|
+
return atom;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
- (NSArray<ENRMMathAtom *> *)allAtoms
|
|
74
|
+
{
|
|
75
|
+
NSTextStorage *storage = [self storage];
|
|
76
|
+
if (storage == nil) {
|
|
77
|
+
return @[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
NSMutableArray<ENRMMathAtom *> *atoms = [NSMutableArray array];
|
|
81
|
+
[storage enumerateAttribute:NSAttachmentAttributeName
|
|
82
|
+
inRange:NSMakeRange(0, storage.length)
|
|
83
|
+
options:0
|
|
84
|
+
usingBlock:^(id value, NSRange range, BOOL *stop) {
|
|
85
|
+
if (![value isKindOfClass:[ENRMMathInlineAttachment class]]) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
[atoms addObject:[self atomFromAttachment:value atPosition:range.location]];
|
|
89
|
+
}];
|
|
90
|
+
return atoms;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
- (nullable ENRMMathAtom *)atomAtPosition:(NSUInteger)position
|
|
94
|
+
{
|
|
95
|
+
NSTextStorage *storage = [self storage];
|
|
96
|
+
if (storage == nil) {
|
|
97
|
+
return nil;
|
|
98
|
+
}
|
|
99
|
+
ENRMMathInlineAttachment *attachment = [self attachmentAtPosition:position inStorage:storage];
|
|
100
|
+
return attachment != nil ? [self atomFromAttachment:attachment atPosition:position] : nil;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#pragma mark - Styling
|
|
104
|
+
|
|
105
|
+
/// Pushes the current `markdownStyle` onto one attachment.
|
|
106
|
+
///
|
|
107
|
+
/// The two branches read *different* style keys and both compile against either
|
|
108
|
+
/// set, so a wrong branch is silent: `inlineMath*` is `markdownStyle.inlineMath`
|
|
109
|
+
/// and `math*` is `markdownStyle.math`, the block key. They swapped meanings in
|
|
110
|
+
/// the rename, so the pairing below is the thing to check, not the spelling.
|
|
111
|
+
- (void)applyStyleToAttachment:(ENRMMathInlineAttachment *)attachment
|
|
112
|
+
{
|
|
113
|
+
if (attachment.displayMode) {
|
|
114
|
+
attachment.fontSize = _style.mathFontSize > 0 ? _style.mathFontSize : kENRMDefaultBlockMathFontSize;
|
|
115
|
+
attachment.mathTextColor = _style.mathColor ?: _style.baseTextColor;
|
|
116
|
+
attachment.containerBackgroundColor = _style.mathBackgroundColor;
|
|
117
|
+
attachment.containerBorderColor = _style.mathBorderColor;
|
|
118
|
+
attachment.containerBorderWidth = _style.mathBorderWidth;
|
|
119
|
+
attachment.containerBorderRadius = _style.mathBorderRadius;
|
|
120
|
+
attachment.containerPaddingHorizontal = _style.mathPaddingHorizontal;
|
|
121
|
+
attachment.containerPaddingVertical = _style.mathPaddingVertical;
|
|
122
|
+
attachment.blockMarginTop = _style.mathMarginTop;
|
|
123
|
+
attachment.blockMarginBottom = _style.mathMarginBottom;
|
|
124
|
+
attachment.blockAlignment = _style.mathTextAlign;
|
|
125
|
+
attachment.selectedBackgroundColor = _style.mathSelectedBackgroundColor;
|
|
126
|
+
attachment.selectedBorderColor = _style.mathSelectedBorderColor;
|
|
127
|
+
attachment.bold = ENRMMathFontWeightIsBold(_style.mathFontWeight);
|
|
128
|
+
} else {
|
|
129
|
+
attachment.fontSize = _style.inlineMathFontSize > 0 ? _style.inlineMathFontSize : kENRMDefaultInlineMathFontSize;
|
|
130
|
+
attachment.mathTextColor = _style.inlineMathColor ?: _style.baseTextColor;
|
|
131
|
+
attachment.containerBackgroundColor = _style.inlineMathBackgroundColor;
|
|
132
|
+
attachment.containerBorderColor = _style.inlineMathBorderColor;
|
|
133
|
+
attachment.containerBorderWidth = _style.inlineMathBorderWidth;
|
|
134
|
+
attachment.containerBorderRadius = _style.inlineMathBorderRadius;
|
|
135
|
+
attachment.containerPaddingHorizontal = _style.inlineMathPaddingHorizontal;
|
|
136
|
+
attachment.containerPaddingVertical = _style.inlineMathPaddingVertical;
|
|
137
|
+
// Inline math flows with the line: no block margins, no paragraph alignment.
|
|
138
|
+
attachment.blockMarginTop = 0;
|
|
139
|
+
attachment.blockMarginBottom = 0;
|
|
140
|
+
attachment.blockAlignment = NSTextAlignmentNatural;
|
|
141
|
+
attachment.selectedBackgroundColor = _style.inlineMathSelectedBackgroundColor;
|
|
142
|
+
attachment.selectedBorderColor = _style.inlineMathSelectedBorderColor;
|
|
143
|
+
attachment.bold = ENRMMathFontWeightIsBold(_style.inlineMathFontWeight);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
- (ENRMMathInlineAttachment *)attachmentWithLatex:(NSString *)latex displayMode:(BOOL)displayMode
|
|
148
|
+
{
|
|
149
|
+
ENRMMathInlineAttachment *attachment = [[ENRMMathInlineAttachment alloc] init];
|
|
150
|
+
attachment.latex = latex ?: @"";
|
|
151
|
+
attachment.displayMode = displayMode;
|
|
152
|
+
[self applyStyleToAttachment:attachment];
|
|
153
|
+
#if TARGET_OS_OSX
|
|
154
|
+
[attachment renderForMacOS];
|
|
155
|
+
#endif
|
|
156
|
+
return attachment;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/// A block chip claims the whole row, so its paragraph carries the configured
|
|
160
|
+
/// alignment. Applied as a paragraph attribute on the chip character itself.
|
|
161
|
+
- (nullable NSParagraphStyle *)paragraphStyleForAttachment:(ENRMMathInlineAttachment *)attachment
|
|
162
|
+
{
|
|
163
|
+
if (!attachment.displayMode || attachment.blockAlignment == NSTextAlignmentNatural) {
|
|
164
|
+
return nil;
|
|
165
|
+
}
|
|
166
|
+
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
|
167
|
+
paragraphStyle.alignment = attachment.blockAlignment;
|
|
168
|
+
return paragraphStyle;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
- (NSAttributedString *)attributedChipWithLatex:(NSString *)latex displayMode:(BOOL)displayMode
|
|
172
|
+
{
|
|
173
|
+
ENRMMathInlineAttachment *attachment = [self attachmentWithLatex:latex displayMode:displayMode];
|
|
174
|
+
NSMutableAttributedString *chip = [[NSMutableAttributedString alloc]
|
|
175
|
+
initWithAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
|
|
176
|
+
NSParagraphStyle *paragraphStyle = [self paragraphStyleForAttachment:attachment];
|
|
177
|
+
if (paragraphStyle != nil) {
|
|
178
|
+
[chip addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, chip.length)];
|
|
179
|
+
}
|
|
180
|
+
return chip;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#pragma mark - Mutation
|
|
184
|
+
|
|
185
|
+
- (void)applyAtoms:(NSArray<ENRMMathAtom *> *)atoms offset:(NSUInteger)offset
|
|
186
|
+
{
|
|
187
|
+
if (atoms.count == 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
NSTextStorage *storage = [self storage];
|
|
191
|
+
if (storage == nil) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
[storage beginEditing];
|
|
196
|
+
for (ENRMMathAtom *atom in atoms) {
|
|
197
|
+
NSUInteger position = atom.position + offset;
|
|
198
|
+
if (position >= storage.length) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
// The parser put a placeholder here; anything else means the buffer moved
|
|
202
|
+
// under the atom and stamping would overwrite live text.
|
|
203
|
+
if ([storage.string characterAtIndex:position] != kENRMObjectReplacement) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
ENRMMathInlineAttachment *attachment = [self attachmentWithLatex:atom.latex displayMode:atom.displayMode];
|
|
208
|
+
[storage addAttribute:NSAttachmentAttributeName value:attachment range:NSMakeRange(position, 1)];
|
|
209
|
+
NSParagraphStyle *paragraphStyle = [self paragraphStyleForAttachment:attachment];
|
|
210
|
+
if (paragraphStyle != nil) {
|
|
211
|
+
[storage addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(position, 1)];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
[storage endEditing];
|
|
215
|
+
|
|
216
|
+
[self invalidateLayoutInRange:NSMakeRange(0, storage.length)];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
- (BOOL)updateChipAtPosition:(NSUInteger)position latex:(NSString *)latex displayMode:(BOOL)displayMode
|
|
220
|
+
{
|
|
221
|
+
NSTextStorage *storage = [self storage];
|
|
222
|
+
if (storage == nil) {
|
|
223
|
+
return NO;
|
|
224
|
+
}
|
|
225
|
+
ENRMMathInlineAttachment *attachment = [self attachmentAtPosition:position inStorage:storage];
|
|
226
|
+
if (attachment == nil) {
|
|
227
|
+
return NO;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
BOOL modeChanged = (attachment.displayMode != displayMode);
|
|
231
|
+
attachment.latex = latex ?: @"";
|
|
232
|
+
attachment.displayMode = displayMode;
|
|
233
|
+
[self applyStyleToAttachment:attachment];
|
|
234
|
+
[attachment invalidateRender];
|
|
235
|
+
#if TARGET_OS_OSX
|
|
236
|
+
[attachment renderForMacOS];
|
|
237
|
+
#endif
|
|
238
|
+
|
|
239
|
+
NSRange chipRange = NSMakeRange(position, 1);
|
|
240
|
+
if (modeChanged) {
|
|
241
|
+
// Only a mode flip can add or drop the block paragraph style; leaving a stale
|
|
242
|
+
// one behind would centre the rest of the paragraph around a former block chip.
|
|
243
|
+
[storage beginEditing];
|
|
244
|
+
NSParagraphStyle *paragraphStyle = [self paragraphStyleForAttachment:attachment];
|
|
245
|
+
if (paragraphStyle != nil) {
|
|
246
|
+
[storage addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:chipRange];
|
|
247
|
+
} else {
|
|
248
|
+
[storage removeAttribute:NSParagraphStyleAttributeName range:chipRange];
|
|
249
|
+
}
|
|
250
|
+
[storage endEditing];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
[self invalidateLayoutInRange:chipRange];
|
|
254
|
+
return YES;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
- (BOOL)setSelected:(BOOL)selected atPosition:(NSUInteger)position
|
|
258
|
+
{
|
|
259
|
+
NSTextStorage *storage = [self storage];
|
|
260
|
+
if (storage == nil) {
|
|
261
|
+
return NO;
|
|
262
|
+
}
|
|
263
|
+
ENRMMathInlineAttachment *attachment = [self attachmentAtPosition:position inStorage:storage];
|
|
264
|
+
if (attachment == nil || attachment.isSelected == selected) {
|
|
265
|
+
return NO;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
attachment.isSelected = selected;
|
|
269
|
+
[attachment invalidateRender];
|
|
270
|
+
[self invalidateLayoutInRange:NSMakeRange(position, 1)];
|
|
271
|
+
return YES;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (BOOL)clearSelectionsExceptPosition:(NSUInteger)keepPosition
|
|
275
|
+
{
|
|
276
|
+
NSTextStorage *storage = [self storage];
|
|
277
|
+
if (storage == nil) {
|
|
278
|
+
return NO;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
__block BOOL anyChanged = NO;
|
|
282
|
+
NSMutableArray<NSValue *> *changedRanges = [NSMutableArray array];
|
|
283
|
+
[storage enumerateAttribute:NSAttachmentAttributeName
|
|
284
|
+
inRange:NSMakeRange(0, storage.length)
|
|
285
|
+
options:0
|
|
286
|
+
usingBlock:^(id value, NSRange range, BOOL *stop) {
|
|
287
|
+
if (![value isKindOfClass:[ENRMMathInlineAttachment class]]) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
ENRMMathInlineAttachment *attachment = value;
|
|
291
|
+
if (!attachment.isSelected || range.location == keepPosition) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
attachment.isSelected = NO;
|
|
295
|
+
[attachment invalidateRender];
|
|
296
|
+
[changedRanges addObject:[NSValue valueWithRange:range]];
|
|
297
|
+
anyChanged = YES;
|
|
298
|
+
}];
|
|
299
|
+
|
|
300
|
+
for (NSValue *rangeValue in changedRanges) {
|
|
301
|
+
[self invalidateLayoutInRange:rangeValue.rangeValue];
|
|
302
|
+
}
|
|
303
|
+
return anyChanged;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
- (void)refreshAll
|
|
307
|
+
{
|
|
308
|
+
NSTextStorage *storage = [self storage];
|
|
309
|
+
if (storage == nil) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
__block BOOL anyChip = NO;
|
|
314
|
+
[storage beginEditing];
|
|
315
|
+
[storage enumerateAttribute:NSAttachmentAttributeName
|
|
316
|
+
inRange:NSMakeRange(0, storage.length)
|
|
317
|
+
options:0
|
|
318
|
+
usingBlock:^(id value, NSRange range, BOOL *stop) {
|
|
319
|
+
if (![value isKindOfClass:[ENRMMathInlineAttachment class]]) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
ENRMMathInlineAttachment *attachment = value;
|
|
323
|
+
[self applyStyleToAttachment:attachment];
|
|
324
|
+
[attachment invalidateRender];
|
|
325
|
+
anyChip = YES;
|
|
326
|
+
NSParagraphStyle *paragraphStyle = [self paragraphStyleForAttachment:attachment];
|
|
327
|
+
if (paragraphStyle != nil) {
|
|
328
|
+
[storage addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];
|
|
329
|
+
}
|
|
330
|
+
}];
|
|
331
|
+
[storage endEditing];
|
|
332
|
+
|
|
333
|
+
// With no chip in the buffer there is nothing to redraw and no reason to make
|
|
334
|
+
// the layout re-measure.
|
|
335
|
+
if (!anyChip) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
[self invalidateLayoutInRange:NSMakeRange(0, storage.length)];
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
- (void)invalidateLayoutInRange:(NSRange)range
|
|
342
|
+
{
|
|
343
|
+
ENRMPlatformTextView *textView = _textView;
|
|
344
|
+
NSLayoutManager *layoutManager = textView.textStorage.layoutManagers.firstObject;
|
|
345
|
+
if (layoutManager != nil) {
|
|
346
|
+
[layoutManager invalidateLayoutForCharacterRange:range actualCharacterRange:NULL];
|
|
347
|
+
[layoutManager ensureLayoutForCharacterRange:range];
|
|
348
|
+
}
|
|
349
|
+
ENRMSetNeedsDisplay(textView);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
#pragma mark - Geometry
|
|
353
|
+
|
|
354
|
+
- (CGRect)chipRectAtPosition:(NSUInteger)position
|
|
355
|
+
{
|
|
356
|
+
ENRMPlatformTextView *textView = _textView;
|
|
357
|
+
NSTextStorage *storage = [self storage];
|
|
358
|
+
if (storage == nil || position >= storage.length) {
|
|
359
|
+
return CGRectNull;
|
|
360
|
+
}
|
|
361
|
+
NSLayoutManager *layoutManager = storage.layoutManagers.firstObject;
|
|
362
|
+
if (layoutManager == nil) {
|
|
363
|
+
return CGRectNull;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
NSRange glyphRange = [layoutManager glyphRangeForCharacterRange:NSMakeRange(position, 1) actualCharacterRange:NULL];
|
|
367
|
+
CGRect rect = [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textView.textContainer];
|
|
368
|
+
rect.origin.x += textView.textContainerInset.left;
|
|
369
|
+
rect.origin.y += textView.textContainerInset.top;
|
|
370
|
+
return rect;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
- (NSUInteger)chipPositionAtPoint:(CGPoint)point
|
|
374
|
+
{
|
|
375
|
+
ENRMPlatformTextView *textView = _textView;
|
|
376
|
+
NSTextStorage *storage = [self storage];
|
|
377
|
+
if (storage == nil) {
|
|
378
|
+
return NSNotFound;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
NSUInteger index = ENRMCharacterIndexAtPoint(textView, point);
|
|
382
|
+
if (index == NSNotFound) {
|
|
383
|
+
return NSNotFound;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// The reported index can land just past the chip, so probe the character before
|
|
387
|
+
// it too. Requiring the touch inside the glyph rect is what stops a tap beside a
|
|
388
|
+
// chip — or in the padding past the last line — from reading as a tap on it.
|
|
389
|
+
NSUInteger candidates[2] = {index, index > 0 ? index - 1 : index};
|
|
390
|
+
NSUInteger candidateCount = index > 0 ? 2 : 1;
|
|
391
|
+
for (NSUInteger which = 0; which < candidateCount; which++) {
|
|
392
|
+
NSUInteger candidate = candidates[which];
|
|
393
|
+
if ([self attachmentAtPosition:candidate inStorage:storage] == nil) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
// An empty rect means the layout could not give the chip's extent; accept the
|
|
397
|
+
// candidate then, rather than making the chip untappable.
|
|
398
|
+
CGRect rect = [self chipRectAtPosition:candidate];
|
|
399
|
+
if (!CGRectIsNull(rect) && !CGRectIsEmpty(rect) && !CGRectContainsPoint(rect, point)) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
return candidate;
|
|
403
|
+
}
|
|
404
|
+
return NSNotFound;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
@end
|
|
408
|
+
|
|
409
|
+
#else // ENRICHED_MARKDOWN_MATH
|
|
410
|
+
|
|
411
|
+
/// Math compiled out: the buffer can never hold a chip, so every query answers
|
|
412
|
+
/// "no chip" and every mutation does nothing. Kept as a full implementation
|
|
413
|
+
/// rather than `#if`s at the call sites so the host reads the same either way.
|
|
414
|
+
@implementation ENRMMathChipController
|
|
415
|
+
|
|
416
|
+
+ (BOOL)isAvailable
|
|
417
|
+
{
|
|
418
|
+
return NO;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
- (instancetype)initWithTextView:(ENRMPlatformTextView *)textView style:(ENRMInputFormatterStyle *)style
|
|
422
|
+
{
|
|
423
|
+
return [super init];
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
- (NSArray<ENRMMathAtom *> *)allAtoms
|
|
427
|
+
{
|
|
428
|
+
return @[];
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
- (nullable ENRMMathAtom *)atomAtPosition:(NSUInteger)position
|
|
432
|
+
{
|
|
433
|
+
return nil;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
- (NSAttributedString *)attributedChipWithLatex:(NSString *)latex displayMode:(BOOL)displayMode
|
|
437
|
+
{
|
|
438
|
+
return [[NSAttributedString alloc] initWithString:@""];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
- (void)applyAtoms:(NSArray<ENRMMathAtom *> *)atoms offset:(NSUInteger)offset
|
|
442
|
+
{
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
- (BOOL)updateChipAtPosition:(NSUInteger)position latex:(NSString *)latex displayMode:(BOOL)displayMode
|
|
446
|
+
{
|
|
447
|
+
return NO;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
- (BOOL)setSelected:(BOOL)selected atPosition:(NSUInteger)position
|
|
451
|
+
{
|
|
452
|
+
return NO;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
- (BOOL)clearSelectionsExceptPosition:(NSUInteger)keepPosition
|
|
456
|
+
{
|
|
457
|
+
return NO;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
- (void)refreshAll
|
|
461
|
+
{
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
- (CGRect)chipRectAtPosition:(NSUInteger)position
|
|
465
|
+
{
|
|
466
|
+
return CGRectNull;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
- (NSUInteger)chipPositionAtPoint:(CGPoint)point
|
|
470
|
+
{
|
|
471
|
+
return NSNotFound;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
@end
|
|
475
|
+
|
|
476
|
+
#endif // ENRICHED_MARKDOWN_MATH
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import CoreGraphics
|
|
3
3
|
import CoreText
|
|
4
|
-
|
|
4
|
+
// RaTeX's core Swift sources (RaTeXEngine/RaTeXRenderer/RaTeXFontLoader/DisplayList) are
|
|
5
|
+
// vendored into this pod's own module (ios/vendor), so there is no external RaTeX module
|
|
6
|
+
// to import; they resolve as same-module symbols. The vendored files import the RaTeXFFI
|
|
7
|
+
// binary module from the XCFramework themselves.
|
|
5
8
|
|
|
6
9
|
#if canImport(UIKit)
|
|
7
10
|
import UIKit
|
|
@@ -8,17 +8,10 @@
|
|
|
8
8
|
@property (nonatomic, assign) BOOL superscript;
|
|
9
9
|
@property (nonatomic, assign) BOOL subscript;
|
|
10
10
|
@property (nonatomic, assign) BOOL highlight;
|
|
11
|
+
@property (nonatomic, assign) BOOL hardSoftBreaks;
|
|
11
12
|
|
|
12
13
|
+ (instancetype)defaultFlags;
|
|
13
14
|
|
|
14
|
-
/// Flags matching the codegen `md4cFlags` Props defaults (every flag off).
|
|
15
|
-
///
|
|
16
|
-
/// Components mirror `md4cFlags` into an ivar with a per-field diff against the
|
|
17
|
-
/// props baseline, so the ivar has to start from the same baseline the props do.
|
|
18
|
-
/// `defaultFlags` enables `latexMath`, which is the right default for the
|
|
19
|
-
/// standalone parser API but would make a `latexMath: false` prop a no-op.
|
|
20
|
-
+ (instancetype)propsDefaultFlags;
|
|
21
|
-
|
|
22
15
|
@end
|
|
23
16
|
|
|
24
17
|
@interface ENRMMarkdownParser : NSObject
|
|
@@ -13,6 +13,7 @@ extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cF
|
|
|
13
13
|
_superscript = NO;
|
|
14
14
|
_subscript = NO;
|
|
15
15
|
_highlight = NO;
|
|
16
|
+
_hardSoftBreaks = NO;
|
|
16
17
|
}
|
|
17
18
|
return self;
|
|
18
19
|
}
|
|
@@ -22,17 +23,6 @@ extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cF
|
|
|
22
23
|
return [[ENRMMd4cFlags alloc] init];
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
+ (instancetype)propsDefaultFlags
|
|
26
|
-
{
|
|
27
|
-
ENRMMd4cFlags *flags = [[ENRMMd4cFlags alloc] init];
|
|
28
|
-
flags.underline = NO;
|
|
29
|
-
flags.latexMath = NO;
|
|
30
|
-
flags.superscript = NO;
|
|
31
|
-
flags.subscript = NO;
|
|
32
|
-
flags.highlight = NO;
|
|
33
|
-
return flags;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
26
|
- (id)copyWithZone:(NSZone *)zone
|
|
37
27
|
{
|
|
38
28
|
ENRMMd4cFlags *copy = [[ENRMMd4cFlags allocWithZone:zone] init];
|
|
@@ -41,6 +31,7 @@ extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cF
|
|
|
41
31
|
copy.superscript = self.superscript;
|
|
42
32
|
copy.subscript = self.subscript;
|
|
43
33
|
copy.highlight = self.highlight;
|
|
34
|
+
copy.hardSoftBreaks = self.hardSoftBreaks;
|
|
44
35
|
return copy;
|
|
45
36
|
}
|
|
46
37
|
|
|
@@ -30,7 +30,8 @@ typedef NS_ENUM(NSInteger, MarkdownNodeType) {
|
|
|
30
30
|
MarkdownNodeTypeSpoiler,
|
|
31
31
|
MarkdownNodeTypeSuperscript,
|
|
32
32
|
MarkdownNodeTypeSubscript,
|
|
33
|
-
MarkdownNodeTypeHighlight
|
|
33
|
+
MarkdownNodeTypeHighlight,
|
|
34
|
+
MarkdownNodeTypeSoftBreak
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
@interface MarkdownASTNode : NSObject
|
|
@@ -104,6 +104,9 @@ static MarkdownASTNode *convertCppASTToObjC(std::shared_ptr<Markdown::MarkdownAS
|
|
|
104
104
|
case Markdown::NodeType::Highlight:
|
|
105
105
|
objcType = MarkdownNodeTypeHighlight;
|
|
106
106
|
break;
|
|
107
|
+
case Markdown::NodeType::SoftBreak:
|
|
108
|
+
objcType = MarkdownNodeTypeSoftBreak;
|
|
109
|
+
break;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
MarkdownASTNode *objcNode = [[MarkdownASTNode alloc] initWithType:objcType];
|
|
@@ -152,6 +155,7 @@ MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cFlags *f
|
|
|
152
155
|
cppFlags.superscript = flags.superscript;
|
|
153
156
|
cppFlags.subscript = flags.subscript;
|
|
154
157
|
cppFlags.highlight = flags.highlight;
|
|
158
|
+
cppFlags.hardSoftBreaks = flags.hardSoftBreaks;
|
|
155
159
|
|
|
156
160
|
Markdown::MD4CParser parser;
|
|
157
161
|
auto cppAST = parser.parse(cppMarkdown, cppFlags);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "AttributedRenderer.h"
|
|
2
|
+
#import "BlockquoteBorder.h"
|
|
2
3
|
#import "CodeBlockBackground.h"
|
|
3
4
|
#import "LastElementUtils.h"
|
|
4
5
|
#import "MarkdownASTNode.h"
|
|
@@ -110,6 +111,10 @@
|
|
|
110
111
|
// 2. Trim trailing characters
|
|
111
112
|
NSUInteger logicalEnd = NSMaxRange(lastContent);
|
|
112
113
|
BOOL isCodeBlock = isLastBlockACodeBlock(output);
|
|
114
|
+
BOOL isPaddedBlockquote = !isCodeBlock && [_config blockquotePadding] > 0 &&
|
|
115
|
+
[output attribute:BlockquoteDepthAttributeName
|
|
116
|
+
atIndex:lastContent.location
|
|
117
|
+
effectiveRange:NULL] != nil;
|
|
113
118
|
NSRange codeRange = NSMakeRange(0, 0);
|
|
114
119
|
if (isCodeBlock) {
|
|
115
120
|
[output attribute:CodeBlockAttributeName
|
|
@@ -121,15 +126,28 @@
|
|
|
121
126
|
[output appendAttributedString:kNewlineAttributedString];
|
|
122
127
|
}
|
|
123
128
|
logicalEnd = codeEnd + 1;
|
|
129
|
+
} else if (isPaddedBlockquote) {
|
|
130
|
+
NSUInteger blockquoteEnd = NSMaxRange(lastContent);
|
|
131
|
+
while (blockquoteEnd < output.length && [output attribute:BlockquoteDepthAttributeName
|
|
132
|
+
atIndex:blockquoteEnd
|
|
133
|
+
effectiveRange:NULL] != nil) {
|
|
134
|
+
blockquoteEnd++;
|
|
135
|
+
}
|
|
136
|
+
if (blockquoteEnd >= output.length) {
|
|
137
|
+
[output appendAttributedString:kNewlineAttributedString];
|
|
138
|
+
}
|
|
139
|
+
logicalEnd = blockquoteEnd + 1;
|
|
124
140
|
}
|
|
125
141
|
|
|
126
142
|
if (logicalEnd < output.length) {
|
|
127
143
|
[output deleteCharactersInRange:NSMakeRange(logicalEnd, output.length - logicalEnd)];
|
|
128
144
|
}
|
|
129
145
|
|
|
130
|
-
if (isCodeBlock && NSMaxRange(codeRange) < output.length) {
|
|
131
|
-
NSUInteger tailIdx = NSMaxRange(codeRange);
|
|
146
|
+
if ((isCodeBlock && NSMaxRange(codeRange) < output.length) || isPaddedBlockquote) {
|
|
147
|
+
NSUInteger tailIdx = isCodeBlock ? NSMaxRange(codeRange) : logicalEnd - 1;
|
|
132
148
|
[output removeAttribute:CodeBlockAttributeName range:NSMakeRange(tailIdx, 1)];
|
|
149
|
+
[output removeAttribute:BlockquoteDepthAttributeName range:NSMakeRange(tailIdx, 1)];
|
|
150
|
+
[output removeAttribute:BlockquoteBackgroundColorAttributeName range:NSMakeRange(tailIdx, 1)];
|
|
133
151
|
NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName atIndex:tailIdx effectiveRange:NULL];
|
|
134
152
|
NSMutableParagraphStyle *mutableStyle = style ? [style mutableCopy] : [[NSMutableParagraphStyle alloc] init];
|
|
135
153
|
mutableStyle.paragraphSpacing = 0;
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
@class RendererFactory;
|
|
5
5
|
@class StyleConfig;
|
|
6
|
+
@class RenderContext;
|
|
7
|
+
@class MarkdownASTNode;
|
|
6
8
|
|
|
7
9
|
/// Shared base for all node renderers — provides `_rendererFactory` and `_config`
|
|
8
10
|
/// as protected ivars and the common designated initializer.
|
|
9
|
-
///
|
|
10
|
-
|
|
11
|
+
/// `renderNode:into:context:` is a template method: take context snapshot ->
|
|
12
|
+
/// `renderNodeContent:into:context:` -> restore snapshot. Subclasses implement
|
|
13
|
+
/// `renderNodeContent:into:context:` and, when they mutate scoped context state,
|
|
14
|
+
/// override `takeContextSnapshot:` to return `[context snapshotScope]`.
|
|
15
|
+
@interface BaseRenderer : NSObject <NodeRenderer> {
|
|
11
16
|
@protected
|
|
12
17
|
__weak RendererFactory *_rendererFactory;
|
|
13
18
|
StyleConfig *_config;
|
|
@@ -15,4 +20,14 @@
|
|
|
15
20
|
|
|
16
21
|
- (instancetype)initWithRendererFactory:(id)rendererFactory config:(id)config;
|
|
17
22
|
|
|
23
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
24
|
+
into:(NSMutableAttributedString *)output
|
|
25
|
+
context:(RenderContext *)context;
|
|
26
|
+
|
|
27
|
+
/// Default returns nil.
|
|
28
|
+
- (nullable id)takeContextSnapshot:(RenderContext *)context;
|
|
29
|
+
|
|
30
|
+
/// Default restores a scope frame when snapshot is non-nil, no-op otherwise.
|
|
31
|
+
- (void)restoreContextSnapshot:(nullable id)snapshot context:(RenderContext *)context;
|
|
32
|
+
|
|
18
33
|
@end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "BaseRenderer.h"
|
|
2
|
+
#import "RenderContext.h"
|
|
2
3
|
#import "RendererFactory.h"
|
|
3
4
|
#import "StyleConfig.h"
|
|
4
5
|
|
|
@@ -13,4 +14,33 @@
|
|
|
13
14
|
return self;
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
- (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)output context:(RenderContext *)context
|
|
18
|
+
{
|
|
19
|
+
id snapshot = [self takeContextSnapshot:context];
|
|
20
|
+
@try {
|
|
21
|
+
[self renderNodeContent:node into:output context:context];
|
|
22
|
+
} @finally {
|
|
23
|
+
[self restoreContextSnapshot:snapshot context:context];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
- (void)renderNodeContent:(MarkdownASTNode *)node
|
|
28
|
+
into:(NSMutableAttributedString *)output
|
|
29
|
+
context:(RenderContext *)context
|
|
30
|
+
{
|
|
31
|
+
[self doesNotRecognizeSelector:_cmd];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (id)takeContextSnapshot:(RenderContext *)context
|
|
35
|
+
{
|
|
36
|
+
return nil;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
- (void)restoreContextSnapshot:(id)snapshot context:(RenderContext *)context
|
|
40
|
+
{
|
|
41
|
+
if (snapshot) {
|
|
42
|
+
[context restoreScope:snapshot];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
16
46
|
@end
|