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.
Files changed (469) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +186 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +35 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -23
  15. package/android/src/main/baseline-prof.txt +1 -1
  16. package/android/src/main/cpp/jni-adapter.cpp +74 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +189 -13
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -1
  21. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
  22. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +42 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
  24. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
  25. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
  27. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  65. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  77. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  96. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
  117. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  120. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +36 -9
  122. package/android/src/main/jni/CMakeLists.txt +53 -0
  123. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  124. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  125. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  126. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  127. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  128. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  129. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  130. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  131. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
  132. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  133. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +6 -4
  134. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  135. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  136. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  137. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  138. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  139. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  140. package/cpp/highlight/gen-registry.mjs +155 -0
  141. package/cpp/highlight/grammar-versions.json +159 -0
  142. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  143. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  144. package/cpp/parser/MD4CParser.cpp +173 -61
  145. package/cpp/parser/MD4CParser.hpp +1 -0
  146. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  147. package/cpp/wasm/ASTSerializer.cpp +2 -0
  148. package/cpp/wasm/build.sh +1 -0
  149. package/cpp/wasm/md4c_wasm.cpp +3 -1
  150. package/docs/ACCESSIBILITY.md +14 -2
  151. package/docs/API_REFERENCE.md +234 -12
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +47 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +108 -11
  158. package/docs/LATEX_MATH.md +87 -45
  159. package/docs/MACOS.md +1 -1
  160. package/docs/MARKDOWN_STREAMING.md +27 -1
  161. package/docs/NATIVE_ASSETS.md +127 -0
  162. package/docs/RTL.md +1 -1
  163. package/docs/STYLES.md +46 -6
  164. package/docs/TESTING.md +112 -0
  165. package/docs/TEXT.md +16 -6
  166. package/docs/WEB.md +3 -1
  167. package/ios/EnrichedMarkdown.h +7 -0
  168. package/ios/EnrichedMarkdown.mm +284 -75
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +101 -73
  171. package/ios/attachments/ENRMImageAttachment.h +9 -0
  172. package/ios/attachments/ENRMImageAttachment.m +143 -40
  173. package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
  174. package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
  175. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  176. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  177. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  178. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +35 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -23
  180. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
  181. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  182. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  183. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  184. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  185. package/ios/input/ENRMBlockRange.h +28 -0
  186. package/ios/input/ENRMBlockRange.mm +30 -0
  187. package/ios/input/ENRMBlockStore.h +56 -0
  188. package/ios/input/ENRMBlockStore.mm +275 -0
  189. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  190. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  191. package/ios/input/ENRMDetectorPipeline.h +2 -1
  192. package/ios/input/ENRMEditPipeline.h +76 -0
  193. package/ios/input/ENRMEditPipeline.mm +228 -0
  194. package/ios/input/ENRMEditSession.h +36 -0
  195. package/ios/input/ENRMEditSession.mm +63 -0
  196. package/ios/input/ENRMFormattingStore.h +17 -0
  197. package/ios/input/ENRMFormattingStore.mm +95 -105
  198. package/ios/input/ENRMInputBlockType.h +91 -0
  199. package/ios/input/ENRMInputBlockType.mm +5 -0
  200. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  201. package/ios/input/ENRMInputEventEmitter.h +56 -0
  202. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  203. package/ios/input/ENRMInputFormatter.h +29 -69
  204. package/ios/input/ENRMInputFormatter.mm +216 -124
  205. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  206. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  207. package/ios/input/ENRMInputLayoutManager.h +9 -0
  208. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  209. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  210. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  211. package/ios/input/ENRMInputParser.h +5 -6
  212. package/ios/input/ENRMInputParser.mm +461 -178
  213. package/ios/input/ENRMInputRemend.mm +2 -2
  214. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  215. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  216. package/ios/input/ENRMInputTextView.mm +103 -8
  217. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  218. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  219. package/ios/input/ENRMLinkCoordinator.h +41 -0
  220. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  221. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  222. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  223. package/ios/input/ENRMMathAtom.h +26 -0
  224. package/ios/input/ENRMMathAtom.mm +12 -0
  225. package/ios/input/ENRMMentionCoordinator.h +45 -0
  226. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  227. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  228. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  229. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  230. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  231. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  232. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  233. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  234. package/ios/input/InputStylePropsUtils.h +109 -68
  235. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  236. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  237. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  238. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  239. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  240. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  241. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  242. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  243. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  244. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  245. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  246. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  248. package/ios/internals/MeasurementCache.h +33 -7
  249. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  250. package/ios/math/ENRMMathChipController.h +74 -0
  251. package/ios/math/ENRMMathChipController.mm +476 -0
  252. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  253. package/ios/parser/ENRMMarkdownParser.h +1 -8
  254. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  255. package/ios/parser/MarkdownASTNode.h +2 -1
  256. package/ios/parser/MarkdownParserBridge.mm +4 -0
  257. package/ios/renderer/AttributedRenderer.m +20 -2
  258. package/ios/renderer/BaseRenderer.h +17 -2
  259. package/ios/renderer/BaseRenderer.m +30 -0
  260. package/ios/renderer/BlockquoteRenderer.h +1 -1
  261. package/ios/renderer/BlockquoteRenderer.m +144 -35
  262. package/ios/renderer/CodeBlockRenderer.h +1 -1
  263. package/ios/renderer/CodeBlockRenderer.m +27 -23
  264. package/ios/renderer/CodeRenderer.h +1 -1
  265. package/ios/renderer/CodeRenderer.m +3 -1
  266. package/ios/renderer/ENRMImageRenderer.h +1 -1
  267. package/ios/renderer/ENRMImageRenderer.m +5 -1
  268. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  269. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  270. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  271. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  272. package/ios/renderer/EmphasisRenderer.h +1 -1
  273. package/ios/renderer/EmphasisRenderer.m +3 -1
  274. package/ios/renderer/HeadingRenderer.h +1 -1
  275. package/ios/renderer/HeadingRenderer.m +13 -6
  276. package/ios/renderer/HighlightRenderer.h +1 -1
  277. package/ios/renderer/HighlightRenderer.m +3 -1
  278. package/ios/renderer/LinkRenderer.h +1 -1
  279. package/ios/renderer/LinkRenderer.m +3 -1
  280. package/ios/renderer/ListItemRenderer.h +13 -1
  281. package/ios/renderer/ListItemRenderer.m +102 -44
  282. package/ios/renderer/ListRenderer.h +2 -2
  283. package/ios/renderer/ListRenderer.m +63 -25
  284. package/ios/renderer/ParagraphRenderer.h +1 -1
  285. package/ios/renderer/ParagraphRenderer.m +16 -8
  286. package/ios/renderer/RenderContext.h +10 -0
  287. package/ios/renderer/RenderContext.m +44 -0
  288. package/ios/renderer/RendererFactory.m +14 -0
  289. package/ios/renderer/StrikethroughRenderer.h +1 -1
  290. package/ios/renderer/StrikethroughRenderer.m +3 -1
  291. package/ios/renderer/StrongRenderer.h +1 -1
  292. package/ios/renderer/StrongRenderer.m +3 -1
  293. package/ios/renderer/SubscriptRenderer.h +1 -1
  294. package/ios/renderer/SubscriptRenderer.m +3 -1
  295. package/ios/renderer/SuperscriptRenderer.h +1 -1
  296. package/ios/renderer/SuperscriptRenderer.m +3 -1
  297. package/ios/renderer/TextRenderer.h +2 -2
  298. package/ios/renderer/TextRenderer.m +3 -1
  299. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  300. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  301. package/ios/renderer/UnderlineRenderer.h +1 -1
  302. package/ios/renderer/UnderlineRenderer.m +3 -1
  303. package/ios/styles/StyleConfig.h +22 -0
  304. package/ios/styles/StyleConfig.mm +132 -0
  305. package/ios/utils/BlockquoteBorder.h +6 -0
  306. package/ios/utils/BlockquoteBorder.m +249 -52
  307. package/ios/utils/CodeBlockBackground.m +16 -2
  308. package/ios/utils/ENRMAtomicSize.h +65 -0
  309. package/ios/utils/ENRMBlockMenu.h +57 -0
  310. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  311. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  312. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  314. package/ios/utils/ENRMFeatureFlags.h +7 -0
  315. package/ios/utils/ENRMImageDownloader.h +11 -1
  316. package/ios/utils/ENRMImageDownloader.m +60 -16
  317. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  318. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  319. package/ios/utils/ENRMMathFallback.h +26 -0
  320. package/ios/utils/ENRMMathFallback.m +18 -0
  321. package/ios/utils/ENRMTextViewSetup.h +35 -17
  322. package/ios/utils/EditMenuUtils.h +22 -5
  323. package/ios/utils/EditMenuUtils.m +53 -9
  324. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  325. package/ios/utils/LastElementUtils.h +1 -0
  326. package/ios/utils/ListMarkerDrawer.m +29 -42
  327. package/ios/utils/MarkdownASTSerializer.m +4 -0
  328. package/ios/utils/ParagraphStyleUtils.h +5 -0
  329. package/ios/utils/ParagraphStyleUtils.m +77 -17
  330. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  331. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  332. package/ios/utils/SegmentRenderer.m +17 -4
  333. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  334. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  335. package/ios/utils/StylePropsUtils.h +63 -0
  336. package/ios/utils/TaskListTapUtils.m +24 -0
  337. package/ios/views/ENRMCodeBlockContainerView.h +53 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +559 -0
  339. package/ios/views/ENRMMathContainerView.h +16 -0
  340. package/ios/views/ENRMMathContainerView.m +74 -19
  341. package/ios/views/TableContainerView.h +22 -0
  342. package/ios/views/TableContainerView.m +261 -175
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -0
  350. package/lib/module/headingDefaults.js +34 -0
  351. package/lib/module/headingDefaults.js.map +1 -0
  352. package/lib/module/index.js.map +1 -1
  353. package/lib/module/jest/index.js +191 -0
  354. package/lib/module/jest/index.js.map +1 -0
  355. package/lib/module/native/EnrichedMarkdownText.js +37 -5
  356. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  357. package/lib/module/normalizeMarkdownStyle.js +81 -19
  358. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  359. package/lib/module/normalizeMarkdownStyle.web.js +56 -18
  360. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  361. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  362. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  363. package/lib/module/normalizeMenuItem.js +1 -1
  364. package/lib/module/utils/textInputState.js +26 -0
  365. package/lib/module/utils/textInputState.js.map +1 -0
  366. package/lib/module/web/EnrichedMarkdownText.js +9 -5
  367. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  368. package/lib/module/web/parseMarkdown.js +4 -3
  369. package/lib/module/web/parseMarkdown.js.map +1 -1
  370. package/lib/module/web/renderers/InlineRenderers.js +6 -0
  371. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  372. package/lib/module/web/renderers/ListRenderers.js +7 -2
  373. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  374. package/lib/module/web/renderers/index.js +7 -4
  375. package/lib/module/web/renderers/index.js.map +1 -1
  376. package/lib/module/web/styles.js +83 -6
  377. package/lib/module/web/styles.js.map +1 -1
  378. package/lib/module/web/utils.js +1 -0
  379. package/lib/module/web/utils.js.map +1 -1
  380. package/lib/module/web/wasm/md4c.js +0 -0
  381. package/lib/module/web/wasm/md4c.js.map +1 -1
  382. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +66 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -0
  389. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  390. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  391. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  392. package/lib/typescript/src/index.d.ts +2 -2
  393. package/lib/typescript/src/index.d.ts.map +1 -1
  394. package/lib/typescript/src/index.web.d.ts +1 -1
  395. package/lib/typescript/src/index.web.d.ts.map +1 -1
  396. package/lib/typescript/src/jest/index.d.ts +6 -0
  397. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  398. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
  399. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  400. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  401. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  402. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  403. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  404. package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
  405. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  406. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
  407. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  408. package/lib/typescript/src/types/MarkdownTextProps.d.ts +104 -9
  409. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  410. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
  411. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  412. package/lib/typescript/src/types/events.d.ts +19 -0
  413. package/lib/typescript/src/types/events.d.ts.map +1 -1
  414. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  415. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  416. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  417. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  418. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  419. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  420. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  421. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  422. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  423. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  424. package/lib/typescript/src/web/styles.d.ts +2 -1
  425. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  426. package/lib/typescript/src/web/types.d.ts +6 -2
  427. package/lib/typescript/src/web/types.d.ts.map +1 -1
  428. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  429. package/package.json +36 -9
  430. package/postinstall.mjs +131 -0
  431. package/ratex-version.json +21 -0
  432. package/src/EnrichedMarkdownNativeComponent.ts +73 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +74 -0
  436. package/src/headingDefaults.ts +21 -0
  437. package/src/index.tsx +9 -0
  438. package/src/index.web.tsx +1 -0
  439. package/src/jest/index.tsx +215 -0
  440. package/src/native/EnrichedMarkdownText.tsx +53 -2
  441. package/src/normalizeMarkdownStyle.ts +102 -16
  442. package/src/normalizeMarkdownStyle.web.ts +63 -15
  443. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  444. package/src/normalizeMenuItem.ts +1 -1
  445. package/src/types/MarkdownStyle.ts +74 -0
  446. package/src/types/MarkdownStyleInternal.ts +39 -0
  447. package/src/types/MarkdownTextProps.ts +101 -9
  448. package/src/types/MarkdownTextProps.web.ts +19 -0
  449. package/src/types/events.ts +21 -0
  450. package/src/utils/textInputState.ts +35 -0
  451. package/src/web/EnrichedMarkdownText.tsx +16 -2
  452. package/src/web/parseMarkdown.ts +6 -2
  453. package/src/web/renderers/InlineRenderers.tsx +5 -0
  454. package/src/web/renderers/ListRenderers.tsx +14 -2
  455. package/src/web/renderers/index.tsx +6 -2
  456. package/src/web/styles.ts +89 -5
  457. package/src/web/types.ts +6 -1
  458. package/src/web/utils.ts +1 -0
  459. package/src/web/wasm/md4c.js +0 -0
  460. package/vendor-grammars.mjs +511 -0
  461. package/vendor-ratex.mjs +173 -0
  462. package/app.plugin.js +0 -2
  463. package/plugin/build/withAndroidMath.js +0 -19
  464. package/plugin/build/withIosMath.js +0 -28
  465. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  466. package/plugin/src/withAndroidMath.ts +0 -24
  467. package/plugin/src/withIosMath.ts +0 -35
  468. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  469. 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