react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.10

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