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
@@ -20,7 +20,8 @@ class StyleConfig(
20
20
  maxFontSizeMultiplier: Float,
21
21
  ) {
22
22
  private val styleParser = StyleParser(context, allowFontScaling, maxFontSizeMultiplier)
23
- private val assets: AssetManager = context.assets
23
+ internal val assetManager: AssetManager = context.assets
24
+ private val assets: AssetManager get() = assetManager
24
25
 
25
26
  private var paragraphStyleOverride: ParagraphStyle? = null
26
27
 
@@ -89,8 +90,12 @@ class StyleConfig(
89
90
  val fontWeight = parseFontWeight(headingStyle?.fontWeight)
90
91
 
91
92
  if (fontFamily != null) {
92
- // Use applyStyles with null base typeface to load from assets via ReactFontManager
93
- applyStyles(null, ReactConstants.UNSET, fontWeight, fontFamily, assets)
93
+ // Load the base font at NORMAL so the assets/fonts file resolves, then apply the
94
+ // weight on the real typeface. Requesting the weight up front makes ReactFontManager
95
+ // look for a `_bold` asset variant that single-file custom fonts lack and silently
96
+ // fall back to a default system face. See SpanStyleCache.getTypeface.
97
+ val base = applyStyles(null, ReactConstants.UNSET, ReactConstants.UNSET, fontFamily, assets)
98
+ applyStyles(base, ReactConstants.UNSET, fontWeight, null, assets)
94
99
  } else {
95
100
  null
96
101
  }
@@ -161,6 +166,8 @@ class StyleConfig(
161
166
  ImageStyle.fromReadableMap(map, styleParser)
162
167
  }
163
168
 
169
+ var imageRequestHeaders: Map<String, String> = emptyMap()
170
+
164
171
  val inlineImageStyle: InlineImageStyle by lazy {
165
172
  val map =
166
173
  requireNotNull(style.getMap("inlineImage")) {
@@ -332,7 +339,8 @@ class StyleConfig(
332
339
  spoilerStyle == other.spoilerStyle &&
333
340
  superscriptStyle == other.superscriptStyle &&
334
341
  subscriptStyle == other.subscriptStyle &&
335
- highlightStyle == other.highlightStyle
342
+ highlightStyle == other.highlightStyle &&
343
+ imageRequestHeaders == other.imageRequestHeaders
336
344
  }
337
345
 
338
346
  override fun hashCode(): Int {
@@ -359,6 +367,7 @@ class StyleConfig(
359
367
  result = 31 * result + superscriptStyle.hashCode()
360
368
  result = 31 * result + subscriptStyle.hashCode()
361
369
  result = 31 * result + highlightStyle.hashCode()
370
+ result = 31 * result + imageRequestHeaders.hashCode()
362
371
  return result
363
372
  }
364
373
  }
@@ -20,6 +20,8 @@ data class TableStyle(
20
20
  val borderRadius: Float,
21
21
  val cellPaddingHorizontal: Float,
22
22
  val cellPaddingVertical: Float,
23
+ val horizontalOverflow: Float,
24
+ val align: String,
23
25
  ) : BaseBlockStyle {
24
26
  companion object {
25
27
  fun fromReadableMap(
@@ -44,6 +46,8 @@ data class TableStyle(
44
46
  val borderRadius = parser.toPixelFromDIP(map.getDouble("borderRadius").toFloat())
45
47
  val cellPaddingHorizontal = parser.toPixelFromDIP(map.getDouble("cellPaddingHorizontal").toFloat())
46
48
  val cellPaddingVertical = parser.toPixelFromDIP(map.getDouble("cellPaddingVertical").toFloat())
49
+ val horizontalOverflow = parser.toPixelFromDIP(map.getDouble("horizontalOverflow").toFloat())
50
+ val align = parser.parseString(map, "align")
47
51
 
48
52
  return TableStyle(
49
53
  fontSize = fontSize,
@@ -63,6 +67,8 @@ data class TableStyle(
63
67
  borderRadius = borderRadius,
64
68
  cellPaddingHorizontal = cellPaddingHorizontal,
65
69
  cellPaddingVertical = cellPaddingVertical,
70
+ horizontalOverflow = horizontalOverflow,
71
+ align = align,
66
72
  )
67
73
  }
68
74
  }
@@ -0,0 +1,90 @@
1
+ package com.swmansion.enriched.markdown.utils.common
2
+
3
+ import android.text.Spannable
4
+ import android.text.style.ForegroundColorSpan
5
+ import android.util.Log
6
+ import com.swmansion.enriched.markdown.styles.CodeBlockStyle
7
+ import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE
8
+
9
+ /**
10
+ * Mirror of HighlightTokenType in cpp/highlight/CodeBlockHighlighter.hpp.
11
+ * Values cross the JNI boundary as ordinals, the same way
12
+ * MarkdownASTNode.NodeType does; keep the declaration order in sync.
13
+ */
14
+ enum class HighlightTokenType {
15
+ Keyword,
16
+ Operator,
17
+ Punctuation,
18
+ String,
19
+ Number,
20
+ Constant,
21
+ Comment,
22
+ Function,
23
+ Type,
24
+ Variable,
25
+ Property,
26
+ Tag,
27
+ Attribute,
28
+ Embedded,
29
+ }
30
+
31
+ /**
32
+ * Platform adapter over the shared C++ syntax highlighting seam
33
+ * (core/cpp/highlight/CodeBlockHighlighter.hpp).
34
+ *
35
+ * The native call returns semantic tokens as (start, end, type) int triplets
36
+ * with UTF-16 offsets into the code string, or null when highlighting is
37
+ * unavailable (module compiled out, unknown language, parse failure). The
38
+ * adapter applies token colors in place as ForegroundColorSpans onto the
39
+ * plain styled code, so highlighting can never change text metrics and the
40
+ * measured block height stays valid. When highlighting is unavailable the
41
+ * spannable is left untouched and renders as plain text.
42
+ */
43
+ object CodeBlockHighlighter {
44
+ init {
45
+ try {
46
+ System.loadLibrary("react_codegen_EnrichedMarkdownTextSpec")
47
+ } catch (e: UnsatisfiedLinkError) {
48
+ Log.e("CodeBlockHighlighter", "Failed to load native library", e)
49
+ }
50
+ }
51
+
52
+ private external fun nativeHighlightCode(
53
+ code: String,
54
+ language: String,
55
+ ): IntArray?
56
+
57
+ /**
58
+ * Applies token colors onto [target]. Token offsets are relative to [code];
59
+ * [offset] is where that code begins in [target] (0 for the github container
60
+ * view which highlights the code string itself, contentStart for the
61
+ * commonmark flavor which renders code inline). A no-op when highlighting is
62
+ * unavailable, so the plain rendering is preserved.
63
+ */
64
+ fun highlight(
65
+ target: Spannable,
66
+ code: String,
67
+ language: String?,
68
+ style: CodeBlockStyle,
69
+ offset: Int = 0,
70
+ ) {
71
+ val tokens =
72
+ try {
73
+ nativeHighlightCode(code, language.orEmpty())
74
+ } catch (e: UnsatisfiedLinkError) {
75
+ null
76
+ } ?: return
77
+
78
+ val colors = style.syntaxColors
79
+ var i = 0
80
+ while (i + 2 < tokens.size) {
81
+ val start = offset + tokens[i]
82
+ val end = offset + tokens[i + 1]
83
+ val type = HighlightTokenType.entries.getOrNull(tokens[i + 2])
84
+ if (type != null && type.ordinal < colors.size && tokens[i] >= 0 && end > start && end <= target.length) {
85
+ target.setSpan(ForegroundColorSpan(colors[type.ordinal]), start, end, SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE)
86
+ }
87
+ i += 3
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,57 @@
1
+ package com.swmansion.enriched.markdown.utils.common
2
+
3
+ import android.util.Log
4
+ import com.swmansion.enriched.markdown.parser.MarkdownASTNode
5
+
6
+ /**
7
+ * Shared code block node semantics, used by both markdown flavors so the
8
+ * meaning of a CodeBlock AST node (its text, language, fence) is defined in
9
+ * one place. Language display names come from the shared C++ core
10
+ * (cpp/highlight/CodeBlockLanguages.hpp) so all platforms label fences
11
+ * identically; when the native library is unavailable the raw fence string
12
+ * is shown instead.
13
+ */
14
+ object CodeBlockNode {
15
+ init {
16
+ try {
17
+ System.loadLibrary("react_codegen_EnrichedMarkdownTextSpec")
18
+ } catch (e: UnsatisfiedLinkError) {
19
+ Log.e("CodeBlockNode", "Failed to load native library", e)
20
+ }
21
+ }
22
+
23
+ private external fun nativeDisplayLanguageName(language: String): String?
24
+
25
+ fun extractCode(node: MarkdownASTNode): String {
26
+ val builder = StringBuilder()
27
+
28
+ fun append(current: MarkdownASTNode) {
29
+ builder.append(current.content)
30
+ current.children.forEach { append(it) }
31
+ }
32
+ append(node)
33
+ return builder.toString().trimEnd('\n')
34
+ }
35
+
36
+ fun language(node: MarkdownASTNode): String? = node.getAttribute("language")?.takeIf { it.isNotEmpty() }
37
+
38
+ fun fenceChar(node: MarkdownASTNode): String = node.getAttribute("fenceChar")?.takeIf { it.isNotEmpty() } ?: "`"
39
+
40
+ fun fencedMarkdown(
41
+ code: String,
42
+ language: String?,
43
+ fenceChar: String,
44
+ ): String {
45
+ val fence = fenceChar.repeat(3)
46
+ return "$fence${language.orEmpty()}\n$code\n$fence"
47
+ }
48
+
49
+ fun displayLanguageName(language: String?): String {
50
+ if (language.isNullOrEmpty()) return ""
51
+ return try {
52
+ nativeDisplayLanguageName(language)
53
+ } catch (e: UnsatisfiedLinkError) {
54
+ null
55
+ } ?: language
56
+ }
57
+ }
@@ -4,4 +4,5 @@ import com.swmansion.enriched.markdown.BuildConfig
4
4
 
5
5
  object FeatureFlags {
6
6
  const val IS_MATH_ENABLED: Boolean = BuildConfig.ENABLE_MATH
7
+ const val IS_CODE_HIGHLIGHT_ENABLED: Boolean = BuildConfig.ENABLE_CODE_HIGHLIGHT
7
8
  }
@@ -15,6 +15,10 @@ sealed interface MarkdownSegment {
15
15
  val latex: String,
16
16
  val node: MarkdownASTNode,
17
17
  ) : MarkdownSegment
18
+
19
+ data class CodeBlock(
20
+ val node: MarkdownASTNode,
21
+ ) : MarkdownSegment
18
22
  }
19
23
 
20
24
  fun splitASTIntoSegments(root: MarkdownASTNode): List<MarkdownSegment> {
@@ -46,6 +50,11 @@ fun splitASTIntoSegments(root: MarkdownASTNode): List<MarkdownSegment> {
46
50
  segments.add(MarkdownSegment.Math(latex, child))
47
51
  }
48
52
 
53
+ MarkdownASTNode.NodeType.CodeBlock -> {
54
+ flushTextNodes()
55
+ segments.add(MarkdownSegment.CodeBlock(child))
56
+ }
57
+
49
58
  else -> {
50
59
  currentTextNodes.add(child)
51
60
  }
@@ -6,6 +6,7 @@ import com.facebook.react.bridge.ReadableMap
6
6
  import com.facebook.react.uimanager.UIManagerHelper
7
7
  import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels
8
8
  import com.swmansion.enriched.markdown.events.ContextMenuItemPressEvent
9
+ import com.swmansion.enriched.markdown.events.CopyPressEvent
9
10
  import com.swmansion.enriched.markdown.events.LinkLongPressEvent
10
11
  import com.swmansion.enriched.markdown.events.LinkPressEvent
11
12
  import com.swmansion.enriched.markdown.events.TaskListItemPressEvent
@@ -19,6 +20,8 @@ fun markdownEventTypeConstants(): MutableMap<String, Any> {
19
20
  mapOf("registrationName" to LinkLongPressEvent.EVENT_NAME)
20
21
  map[TaskListItemPressEvent.EVENT_NAME] =
21
22
  mapOf("registrationName" to TaskListItemPressEvent.EVENT_NAME)
23
+ map[CopyPressEvent.EVENT_NAME] =
24
+ mapOf("registrationName" to CopyPressEvent.EVENT_NAME)
22
25
  map[ContextMenuItemPressEvent.EVENT_NAME] =
23
26
  mapOf("registrationName" to ContextMenuItemPressEvent.EVENT_NAME)
24
27
  return map
@@ -58,6 +61,19 @@ fun emitTaskListItemPress(
58
61
  )
59
62
  }
60
63
 
64
+ fun emitCopyPress(
65
+ view: View,
66
+ code: String,
67
+ language: String,
68
+ ) {
69
+ val context = view.context as com.facebook.react.bridge.ReactContext
70
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
71
+ val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
72
+ eventDispatcher?.dispatchEvent(
73
+ CopyPressEvent(surfaceId, view.id, code, language),
74
+ )
75
+ }
76
+
61
77
  fun emitContextMenuItemPress(
62
78
  view: View,
63
79
  itemText: String,
@@ -82,26 +98,40 @@ fun emitContextMenuItemPress(
82
98
 
83
99
  fun parseMd4cFlags(flags: ReadableMap?): Md4cFlags =
84
100
  Md4cFlags(
85
- underline = flags?.getBoolean("underline") ?: false,
86
- latexMath = FeatureFlags.IS_MATH_ENABLED && (flags?.getBoolean("latexMath") ?: true),
87
- superscript = flags?.getBoolean("superscript") ?: false,
88
- subscript = flags?.getBoolean("subscript") ?: false,
89
- highlight = flags?.getBoolean("highlight") ?: false,
101
+ underline = flags.getBooleanOrDefault("underline", false),
102
+ latexMath = FeatureFlags.IS_MATH_ENABLED && flags.getBooleanOrDefault("latexMath", true),
103
+ superscript = flags.getBooleanOrDefault("superscript", false),
104
+ subscript = flags.getBooleanOrDefault("subscript", false),
105
+ highlight = flags.getBooleanOrDefault("highlight", false),
106
+ hardSoftBreaks = flags.getBooleanOrDefault("hardSoftBreaks", false),
90
107
  )
91
108
 
92
109
  fun parseContextMenuItems(value: ReadableArray?): List<String> =
93
110
  (0 until (value?.size() ?: 0)).mapNotNull { value?.getMap(it)?.getString("text") }
94
111
 
112
+ fun parseImageRequestHeaders(value: ReadableArray?): Map<String, String> =
113
+ (0 until (value?.size() ?: 0))
114
+ .mapNotNull { index ->
115
+ val header = value?.getMap(index) ?: return@mapNotNull null
116
+ val name = header.getString("name") ?: return@mapNotNull null
117
+ val headerValue = header.getString("value") ?: return@mapNotNull null
118
+ name to headerValue
119
+ }.toMap()
120
+
95
121
  fun parseSelectionMenuConfig(value: ReadableMap?): SelectionMenuConfig {
96
122
  if (value == null) return SelectionMenuConfig()
97
123
  return SelectionMenuConfig(
98
- copyAsMarkdown = value.getBoolean("copyAsMarkdown"),
99
- copyImageUrl = value.getBoolean("copyImageUrl"),
124
+ copyAsMarkdown = value.getBooleanOrDefault("copyAsMarkdown", true),
125
+ copyImageUrl = value.getBooleanOrDefault("copyImageUrl", true),
100
126
  copyLabel = value.getString("copyLabel") ?: "",
101
127
  copyAsMarkdownLabel = value.getString("copyAsMarkdownLabel") ?: "",
102
128
  copyImageUrlLabel = value.getString("copyImageUrlLabel") ?: "",
103
129
  copyImageUrlsLabel = value.getString("copyImageUrlsLabel") ?: "",
104
130
  copyImageUrlPluralTemplates = parseStringList(value.getArray("copyImageUrlPluralTemplates")),
131
+ copyEnabled = value.getBooleanOrDefault("copyEnabled", true),
132
+ copyFormatMarkdown = value.getBooleanOrDefault("copyFormatMarkdown", false),
133
+ systemItemsNone = value.getBooleanOrDefault("systemItemsNone", false),
134
+ codeBlockCopyButton = value.getBooleanOrDefault("codeBlockCopyButton", true),
105
135
  )
106
136
  }
107
137
 
@@ -1,5 +1,6 @@
1
1
  package com.swmansion.enriched.markdown.utils.common
2
2
 
3
+ import com.facebook.react.bridge.ReadableArray
3
4
  import com.facebook.react.bridge.ReadableMap
4
5
 
5
6
  fun ReadableMap?.getBooleanOrDefault(
@@ -18,3 +19,5 @@ fun ReadableMap?.getStringOrDefault(
18
19
  ): String = if (this?.hasKey(key) == true) getString(key) ?: default else default
19
20
 
20
21
  fun ReadableMap?.getMapOrNull(key: String): ReadableMap? = if (this?.hasKey(key) == true) getMap(key) else null
22
+
23
+ fun ReadableMap?.getArrayOrNull(key: String): ReadableArray? = if (this?.hasKey(key) == true) getArray(key) else null
@@ -27,6 +27,11 @@ sealed interface RenderedSegment {
27
27
  val latex: String,
28
28
  override val signature: Long,
29
29
  ) : RenderedSegment
30
+
31
+ data class CodeBlock(
32
+ val node: MarkdownASTNode,
33
+ override val signature: Long,
34
+ ) : RenderedSegment
30
35
  }
31
36
 
32
37
  object MarkdownSegmentRenderer {
@@ -53,6 +58,11 @@ object MarkdownSegmentRenderer {
53
58
  signature = SegmentSignature.fnvMixString(signature, segment.latex)
54
59
  RenderedSegment.Math(segment.latex, signature)
55
60
  }
61
+
62
+ is MarkdownSegment.CodeBlock -> {
63
+ val signature = SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.CODE_BLOCK_KIND_SALT
64
+ RenderedSegment.CodeBlock(segment.node, signature)
65
+ }
56
66
  }
57
67
  }
58
68
 
@@ -11,6 +11,7 @@ object SegmentSignature {
11
11
  internal const val TEXT_KIND_SALT = 0x7465787400000000L // "text"
12
12
  internal const val TABLE_KIND_SALT = 0x7461626C00000000L // "tabl"
13
13
  internal const val MATH_KIND_SALT = 0x6D61746800000000L // "math"
14
+ internal const val CODE_BLOCK_KIND_SALT = 0x63626C6B00000000L // "cblk"
14
15
 
15
16
  private fun fnvMixByte(
16
17
  hash: Long,
@@ -5,23 +5,101 @@ enum class TableStreamingMode {
5
5
  PROGRESSIVE,
6
6
  }
7
7
 
8
+ enum class CodeBlockStreamingMode {
9
+ HIDDEN,
10
+ PROGRESSIVE,
11
+ }
12
+
13
+ /**
14
+ * Filtered markdown plus whether it ends inside a still-open fenced code block
15
+ * (the trailing block whose highlighting/copy chrome the renderer defers).
16
+ */
17
+ data class StreamingFilterResult(
18
+ val markdown: String,
19
+ val endsInsideOpenCodeFence: Boolean,
20
+ )
21
+
8
22
  /**
9
- * Pre-parse filter that hides incomplete trailing tables and block math
10
- * during streaming. A table is considered complete only after a blank
11
- * separator line follows it; a block math (`$$`) is complete only when
12
- * a closing `$$` exists.
23
+ * Pre-parse filter that hides incomplete trailing tables, block math and code
24
+ * blocks while streaming. An open fenced code block is handled first so its
25
+ * body (which may hold `$$` or `|` lines) is not mistaken for a pending
26
+ * math/table block: HIDDEN truncates it, PROGRESSIVE keeps it and only filters
27
+ * the region before it. endsInsideOpenCodeFence flags that trailing open block.
13
28
  */
14
29
  object StreamingMarkdownFilter {
15
30
  fun renderableMarkdownForStreaming(
16
31
  markdown: String,
17
32
  tableMode: TableStreamingMode = TableStreamingMode.PROGRESSIVE,
18
- ): String {
33
+ codeBlockMode: CodeBlockStreamingMode = CodeBlockStreamingMode.PROGRESSIVE,
34
+ ): StreamingFilterResult {
19
35
  val lines = markdown.split("\n")
36
+ val openFenceIndex = findOpenCodeFenceLineIndex(lines)
37
+
38
+ if (openFenceIndex == -1) {
39
+ return StreamingFilterResult(removePendingTablesAndMath(markdown, tableMode, lines), false)
40
+ }
41
+
42
+ val fenceOffset = buildLineOffsets(lines)[openFenceIndex]
43
+ val head = markdown.substring(0, fenceOffset)
44
+ if (codeBlockMode == CodeBlockStreamingMode.HIDDEN) {
45
+ return StreamingFilterResult(removePendingTablesAndMath(head, tableMode), false)
46
+ }
47
+ val tail = markdown.substring(fenceOffset)
48
+ return StreamingFilterResult(removePendingTablesAndMath(head, tableMode) + tail, true)
49
+ }
50
+
51
+ private fun removePendingTablesAndMath(
52
+ markdown: String,
53
+ tableMode: TableStreamingMode,
54
+ lines: List<String> = markdown.split("\n"),
55
+ ): String {
20
56
  val afterMath = removePendingStreamingMathBlock(markdown, lines)
21
57
  val linesForTable = if (afterMath.length == markdown.length) lines else afterMath.split("\n")
22
58
  return removePendingStreamingTableBlock(afterMath, linesForTable, tableMode)
23
59
  }
24
60
 
61
+ private class FenceMarker(
62
+ val char: Char,
63
+ val length: Int,
64
+ val info: String,
65
+ )
66
+
67
+ private fun parseFenceMarker(line: String): FenceMarker? {
68
+ var i = 0
69
+ while (i < line.length && line[i] == ' ' && i < 3) i++
70
+ if (i >= line.length) return null
71
+ val ch = line[i]
72
+ if (ch != '`' && ch != '~') return null
73
+ var runLength = 0
74
+ while (i < line.length && line[i] == ch) {
75
+ i++
76
+ runLength++
77
+ }
78
+ if (runLength < 3) return null
79
+ val info = line.substring(i)
80
+ if (ch == '`' && info.contains('`')) return null
81
+ return FenceMarker(ch, runLength, info)
82
+ }
83
+
84
+ private fun findOpenCodeFenceLineIndex(lines: List<String>): Int {
85
+ var openIndex = -1
86
+ var openChar = ' '
87
+ var openLength = 0
88
+ for (i in lines.indices) {
89
+ val marker = parseFenceMarker(lines[i])
90
+ if (openIndex == -1) {
91
+ if (marker != null) {
92
+ openIndex = i
93
+ openChar = marker.char
94
+ openLength = marker.length
95
+ }
96
+ } else if (marker != null && marker.char == openChar && marker.length >= openLength && marker.info.isBlank()) {
97
+ openIndex = -1
98
+ }
99
+ }
100
+ return openIndex
101
+ }
102
+
25
103
  private fun removePendingStreamingMathBlock(
26
104
  markdown: String,
27
105
  lines: List<String>,
@@ -28,6 +28,10 @@ object MarkdownASTSerializer {
28
28
  }
29
29
 
30
30
  NodeType.LineBreak -> {
31
+ buffer.append("\\\n")
32
+ }
33
+
34
+ NodeType.SoftBreak -> {
31
35
  buffer.append("\n")
32
36
  }
33
37