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,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
- import RaTeX
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
- /// Concrete subclasses must implement `renderNode:into:context:`.
10
- @interface BaseRenderer : NSObject {
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