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
@@ -0,0 +1,177 @@
1
+ package com.swmansion.enriched.markdown.spans
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.graphics.Path
6
+ import android.graphics.RectF
7
+ import android.text.SpannableStringBuilder
8
+ import android.text.Spanned
9
+ import android.text.TextPaint
10
+ import android.text.style.LineBackgroundSpan
11
+ import android.text.style.ReplacementSpan
12
+ import com.swmansion.enriched.markdown.styles.LinkChipStyle
13
+ import kotlin.math.max
14
+ import kotlin.math.min
15
+ import kotlin.math.roundToInt
16
+
17
+ /**
18
+ * Reserves a link's `paddingHorizontal` at one outer edge. It covers one [LinkSpacers.CHAR]
19
+ * inserted by `LinkRenderer`: U+00A0 is line-break class GL, so a break is allowed before it
20
+ * after a space but never after it, and never before it after a non-space — the spacer always
21
+ * travels with the link's first (or last) glyph, never orphaned at a wrap.
22
+ *
23
+ * Layout-only: every text exit point strips spacers by this span ([LinkSpacers.strip]).
24
+ */
25
+ class LinkSpacerSpan(
26
+ private val width: Float,
27
+ ) : ReplacementSpan() {
28
+ override fun getSize(
29
+ paint: Paint,
30
+ text: CharSequence?,
31
+ start: Int,
32
+ end: Int,
33
+ fm: Paint.FontMetricsInt?,
34
+ ): Int {
35
+ // Keep the line metrics of the surrounding text.
36
+ if (fm != null) paint.getFontMetricsInt(fm)
37
+ return width.roundToInt()
38
+ }
39
+
40
+ override fun draw(
41
+ canvas: Canvas,
42
+ text: CharSequence?,
43
+ start: Int,
44
+ end: Int,
45
+ x: Float,
46
+ top: Int,
47
+ y: Int,
48
+ bottom: Int,
49
+ paint: Paint,
50
+ ) = Unit
51
+ }
52
+
53
+ object LinkSpacers {
54
+ const val CHAR = '\u00A0'
55
+
56
+ /** [text] without link spacers (returns [text] itself when it has none). */
57
+ fun strip(text: CharSequence): CharSequence {
58
+ if (text !is Spanned) return text
59
+ val spacers = text.getSpans(0, text.length, LinkSpacerSpan::class.java)
60
+ if (spacers.isEmpty()) return text
61
+ val builder = SpannableStringBuilder(text)
62
+ spacers
63
+ .map { builder.getSpanStart(it) to builder.getSpanEnd(it) }
64
+ .filter { (start, end) -> start in 0 until end }
65
+ .sortedByDescending { it.first }
66
+ .forEach { (start, end) -> builder.delete(start, end) }
67
+ return builder
68
+ }
69
+
70
+ /** True when [start, end) lies inside a spacer (a segment exporters must skip). */
71
+ fun isSpacer(
72
+ text: Spanned,
73
+ start: Int,
74
+ end: Int,
75
+ ): Boolean = end > start && text.getSpans(start, end, LinkSpacerSpan::class.java).isNotEmpty()
76
+ }
77
+
78
+ /**
79
+ * Paints a link chip (background + border) behind the link glyphs. One instance per link,
80
+ * spanning the link including its spacers, so the chip already covers `paddingHorizontal`.
81
+ * Vertically the chip spans the link font's ascent..descent ± `paddingVertical`; the vertical
82
+ * padding only bleeds into the surrounding line spacing and never changes the line box.
83
+ */
84
+ class LinkChipBackgroundSpan(
85
+ val chip: LinkChipStyle,
86
+ ) : LineBackgroundSpan {
87
+ private val rect = RectF()
88
+ private val path = Path()
89
+ private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.FILL }
90
+ private val borderPaint =
91
+ Paint(Paint.ANTI_ALIAS_FLAG).apply {
92
+ style = Paint.Style.STROKE
93
+ strokeJoin = Paint.Join.ROUND
94
+ strokeCap = Paint.Cap.ROUND
95
+ }
96
+
97
+ override fun drawBackground(
98
+ canvas: Canvas,
99
+ p: Paint,
100
+ left: Int,
101
+ right: Int,
102
+ top: Int,
103
+ baseline: Int,
104
+ bottom: Int,
105
+ text: CharSequence,
106
+ start: Int,
107
+ end: Int,
108
+ lineNum: Int,
109
+ ) {
110
+ if (!chip.isVisible || text !is Spanned) return
111
+
112
+ val spanStart = text.getSpanStart(this)
113
+ val spanEnd = text.getSpanEnd(this)
114
+ if (spanStart !in 0 until spanEnd || spanEnd <= start || spanStart >= end) return
115
+
116
+ val isFirst = spanStart >= start
117
+ val isLast = spanEnd <= end
118
+
119
+ val leadingMargin = InlineChipPainter.leadingMarginAt(text, start)
120
+ val fragmentStart = max(spanStart, start)
121
+ val fragmentEnd = trimTrailingWhitespace(text, fragmentStart, min(spanEnd, end))
122
+ val startX = InlineChipPainter.horizontalOffset(text, start, end, fragmentStart, p, leadingMargin) + left
123
+ val endX = InlineChipPainter.horizontalOffset(text, start, end, fragmentEnd, p, leadingMargin) + left
124
+
125
+ val (ascent, descent) = linkFontMetrics(text, spanStart, spanEnd, p)
126
+ rect.set(
127
+ min(startX, endX),
128
+ baseline + ascent - chip.paddingVertical,
129
+ max(startX, endX),
130
+ baseline + descent + chip.paddingVertical,
131
+ )
132
+
133
+ backgroundPaint.color = chip.backgroundColor
134
+ borderPaint.color = chip.borderColor
135
+ borderPaint.strokeWidth = chip.borderWidth
136
+ InlineChipPainter.draw(
137
+ canvas,
138
+ rect,
139
+ path,
140
+ chip.borderRadius,
141
+ backgroundPaint.takeIf { android.graphics.Color.alpha(chip.backgroundColor) > 0 },
142
+ borderPaint.takeIf { android.graphics.Color.alpha(chip.borderColor) > 0 && chip.borderWidth > 0f },
143
+ isFirst,
144
+ isLast,
145
+ strokeInset = true,
146
+ )
147
+ }
148
+
149
+ companion object {
150
+ /** A wrapped fragment ends before the whitespace the line break hangs. */
151
+ fun trimTrailingWhitespace(
152
+ text: CharSequence,
153
+ start: Int,
154
+ end: Int,
155
+ ): Int {
156
+ var index = end
157
+ while (index > start && text[index - 1] != LinkSpacers.CHAR && text[index - 1].isWhitespace()) index--
158
+ return index
159
+ }
160
+
161
+ /**
162
+ * Ascent/descent of the link's own font: [LinkSpan] sets its size and typeface at draw
163
+ * time only, so the base paint [p] alone would report the paragraph's metrics.
164
+ */
165
+ fun linkFontMetrics(
166
+ text: Spanned,
167
+ spanStart: Int,
168
+ spanEnd: Int,
169
+ p: Paint,
170
+ ): Pair<Float, Float> {
171
+ val paint = TextPaint(p)
172
+ text.getSpans(spanStart, spanEnd, LinkSpan::class.java).firstOrNull()?.updateDrawState(paint)
173
+ val metrics = paint.fontMetrics
174
+ return metrics.ascent to metrics.descent
175
+ }
176
+ }
177
+ }
@@ -1,7 +1,6 @@
1
1
  package com.swmansion.enriched.markdown.spans
2
2
 
3
3
  import android.content.Context
4
- import android.graphics.Color
5
4
  import android.text.TextPaint
6
5
  import android.text.style.ClickableSpan
7
6
  import android.view.View
@@ -57,10 +56,6 @@ class LinkSpan(
57
56
 
58
57
  textPaint.color = variant?.color ?: styleCache.linkColor
59
58
  textPaint.isUnderlineText = variant?.underline ?: styleCache.linkUnderline
60
-
61
- val backgroundColor = variant?.backgroundColor ?: styleCache.linkBackgroundColor
62
- if (Color.alpha(backgroundColor) > 0) {
63
- textPaint.bgColor = backgroundColor
64
- }
59
+ // The background is painted as a chip by LinkChipBackgroundSpan.
65
60
  }
66
61
  }
@@ -0,0 +1,33 @@
1
+ package com.swmansion.enriched.markdown.spans
2
+
3
+ import android.graphics.Paint
4
+ import android.text.Spanned
5
+ import android.text.style.LineHeightSpan
6
+
7
+ /**
8
+ * Adds vertical spacing between list items using LineHeightSpan.
9
+ *
10
+ * Attached over the newline that separates two items; extends only the line
11
+ * ending at that newline so the gap appears below the preceding item.
12
+ *
13
+ * @param spacing The spacing in pixels to add below the line (0 = no spacing)
14
+ */
15
+ class ListItemSpacingSpan(
16
+ val spacing: Float,
17
+ ) : LineHeightSpan {
18
+ override fun chooseHeight(
19
+ text: CharSequence,
20
+ start: Int,
21
+ end: Int,
22
+ spanstartv: Int,
23
+ lineHeight: Int,
24
+ fm: Paint.FontMetricsInt,
25
+ ) {
26
+ val spanEnd = (text as? Spanned)?.getSpanEnd(this) ?: return
27
+ if (end != spanEnd) return
28
+
29
+ val spacingPixels = spacing.toInt()
30
+ fm.descent += spacingPixels
31
+ fm.bottom += spacingPixels
32
+ }
33
+ }
@@ -0,0 +1,38 @@
1
+ package com.swmansion.enriched.markdown.spans
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.text.Layout
6
+ import android.text.Spanned
7
+ import android.text.style.LeadingMarginSpan
8
+
9
+ // Draws a list marker on a line owned by another block (code block, nested
10
+ // sublist) without contributing any margin of its own.
11
+ class ListMarkerAnchorSpan(
12
+ internal val marker: BaseListSpan,
13
+ ) : LeadingMarginSpan {
14
+ override fun getLeadingMargin(first: Boolean): Int = 0
15
+
16
+ override fun drawLeadingMargin(
17
+ c: Canvas,
18
+ p: Paint,
19
+ x: Int,
20
+ dir: Int,
21
+ top: Int,
22
+ baseline: Int,
23
+ bottom: Int,
24
+ text: CharSequence?,
25
+ start: Int,
26
+ end: Int,
27
+ first: Boolean,
28
+ layout: Layout?,
29
+ ) {
30
+ if (!first) return
31
+ if (text is Spanned && text.getSpanStart(this) != start) return
32
+
33
+ // Pass the paragraph origin: drawMarker reconstructs its offset from depth,
34
+ // matching the x its own span would receive on a plain text line.
35
+ val originX = if (dir > 0) 0 else layout?.width ?: 0
36
+ marker.drawMarkerAt(c, p, originX, dir, top, baseline, bottom, layout, start)
37
+ }
38
+ }
@@ -18,6 +18,7 @@ class OrderedListSpan(
18
18
  depth: Int,
19
19
  context: Context,
20
20
  styleCache: SpanStyleCache,
21
+ drawsMarker: Boolean = true,
21
22
  ) : BaseListSpan(
22
23
  depth = depth,
23
24
  context = context,
@@ -31,6 +32,7 @@ class OrderedListSpan(
31
32
  ),
32
33
  marginLeft = listStyle.marginLeft,
33
34
  gapWidth = listStyle.gapWidth,
35
+ drawsMarker = drawsMarker,
34
36
  ) {
35
37
  companion object {
36
38
  private val sharedMarkerPaint = TextPaint().apply { isAntiAlias = true }
@@ -31,7 +31,7 @@ class StrongSpan(
31
31
  tp.typeface =
32
32
  if (styleCache.strongFontFamily.isNotEmpty()) {
33
33
  val resolvedStyle = if (styleCache.strongFontWeight == "normal") Typeface.NORMAL else style
34
- SpanStyleCache.getTypeface(styleCache.strongFontFamily, resolvedStyle)
34
+ styleCache.getTypeface(styleCache.strongFontFamily, resolvedStyle)
35
35
  } else {
36
36
  Typeface.create(currentTypeface, style)
37
37
  }
@@ -19,6 +19,7 @@ class TaskListSpan(
19
19
  styleCache: SpanStyleCache,
20
20
  val taskIndex: Int,
21
21
  val isChecked: Boolean,
22
+ drawsMarker: Boolean = true,
22
23
  ) : BaseListSpan(
23
24
  depth = depth,
24
25
  context = context,
@@ -32,6 +33,7 @@ class TaskListSpan(
32
33
  ),
33
34
  marginLeft = listStyle.marginLeft,
34
35
  gapWidth = listStyle.gapWidth,
36
+ drawsMarker = drawsMarker,
35
37
  ) {
36
38
  private val checkboxSize = taskStyle.checkboxSize
37
39
  private val markerColumnWidth = listStyle.effectiveMarkerWidth(checkboxSize)
@@ -69,8 +71,7 @@ class TaskListSpan(
69
71
  layout: Layout?,
70
72
  start: Int,
71
73
  ) {
72
- val fontMetrics = paint.fontMetrics
73
- val capHeight = -fontMetrics.ascent * CAP_HEIGHT_RATIO
74
+ val capHeight = -markerFontMetrics.ascent * CAP_HEIGHT_RATIO
74
75
  val centerY = baseline - capHeight / HALF_DIVISOR
75
76
  // Right-align the checkbox inside the reserved marker column so it hugs
76
77
  // the gap before the text. At the default (markerColumnWidth ==
@@ -13,6 +13,7 @@ class UnorderedListSpan(
13
13
  depth: Int,
14
14
  context: Context,
15
15
  styleCache: SpanStyleCache,
16
+ drawsMarker: Boolean = true,
16
17
  ) : BaseListSpan(
17
18
  depth = depth,
18
19
  context = context,
@@ -26,6 +27,7 @@ class UnorderedListSpan(
26
27
  ),
27
28
  marginLeft = listStyle.marginLeft,
28
29
  gapWidth = listStyle.gapWidth,
30
+ drawsMarker = drawsMarker,
29
31
  ) {
30
32
  companion object {
31
33
  private val sharedBulletPaint =
@@ -64,8 +66,7 @@ class UnorderedListSpan(
64
66
  // visually flush-left when the column width equals the bullet radius
65
67
  // (the default).
66
68
  val bulletX = x + (depth * marginLeft + markerColumnWidth) * dir
67
- val fontMetrics = paint.fontMetrics
68
- val bulletY = baseline + (fontMetrics.ascent + fontMetrics.descent) / 2f
69
+ val bulletY = baseline + (markerFontMetrics.ascent + markerFontMetrics.descent) / 2f
69
70
 
70
71
  when (depth) {
71
72
  0 -> {
@@ -14,6 +14,8 @@ data class BlockquoteStyle(
14
14
  val borderWidth: Float,
15
15
  val gapWidth: Float,
16
16
  val backgroundColor: Int?,
17
+ val borderRadius: Float,
18
+ val padding: Float,
17
19
  ) : BaseBlockStyle {
18
20
  companion object {
19
21
  fun fromReadableMap(
@@ -32,6 +34,8 @@ data class BlockquoteStyle(
32
34
  val borderWidth = parser.toPixelFromDIP(map.getDouble("borderWidth").toFloat())
33
35
  val gapWidth = parser.toPixelFromDIP(map.getDouble("gapWidth").toFloat())
34
36
  val backgroundColor = parser.parseOptionalColor(map, "backgroundColor")
37
+ val borderRadius = parser.toPixelFromDIP(map.getDouble("borderRadius").toFloat())
38
+ val padding = parser.toPixelFromDIP(map.getDouble("padding").toFloat())
35
39
 
36
40
  return BlockquoteStyle(
37
41
  fontSize,
@@ -45,6 +49,8 @@ data class BlockquoteStyle(
45
49
  borderWidth,
46
50
  gapWidth,
47
51
  backgroundColor,
52
+ borderRadius,
53
+ padding,
48
54
  )
49
55
  }
50
56
  }
@@ -15,8 +15,27 @@ data class CodeBlockStyle(
15
15
  val borderRadius: Float,
16
16
  val borderWidth: Float,
17
17
  val padding: Float,
18
+ val syntaxColors: List<Int>,
18
19
  ) : BaseBlockStyle {
19
20
  companion object {
21
+ private val SYNTAX_COLOR_KEYS =
22
+ listOf(
23
+ "keyword",
24
+ "operatorColor",
25
+ "punctuation",
26
+ "string",
27
+ "number",
28
+ "constant",
29
+ "comment",
30
+ "function",
31
+ "type",
32
+ "variable",
33
+ "property",
34
+ "tag",
35
+ "attribute",
36
+ "embedded",
37
+ )
38
+
20
39
  fun fromReadableMap(
21
40
  map: ReadableMap,
22
41
  parser: StyleParser,
@@ -35,6 +54,12 @@ data class CodeBlockStyle(
35
54
  val borderWidth = parser.toPixelFromDIP(map.getDouble("borderWidth").toFloat())
36
55
  val padding = parser.toPixelFromDIP(map.getDouble("padding").toFloat())
37
56
 
57
+ val syntaxMap = map.getMap("syntaxColors")
58
+ val syntaxColors =
59
+ SYNTAX_COLOR_KEYS.map { key ->
60
+ syntaxMap?.let { parser.parseOptionalColor(it, key) } ?: color
61
+ }
62
+
38
63
  return CodeBlockStyle(
39
64
  fontSize,
40
65
  fontFamily,
@@ -48,6 +73,7 @@ data class CodeBlockStyle(
48
73
  borderRadius,
49
74
  borderWidth,
50
75
  padding,
76
+ syntaxColors,
51
77
  )
52
78
  }
53
79
  }
@@ -4,6 +4,9 @@ import com.facebook.react.bridge.ReadableMap
4
4
 
5
5
  data class ImageStyle(
6
6
  val height: Float,
7
+ val maxHeight: Float,
8
+ val aspectRatio: Float,
9
+ val resizeMode: String,
7
10
  val borderRadius: Float,
8
11
  val marginTop: Float,
9
12
  val marginBottom: Float,
@@ -14,10 +17,13 @@ data class ImageStyle(
14
17
  parser: StyleParser,
15
18
  ): ImageStyle {
16
19
  val height = parser.toPixelFromDIP(map.getDouble("height").toFloat())
20
+ val maxHeight = parser.toPixelFromDIP(map.getDouble("maxHeight").toFloat())
21
+ val aspectRatio = map.getDouble("aspectRatio").toFloat()
22
+ val resizeMode = map.getString("resizeMode") ?: ""
17
23
  val borderRadius = parser.toPixelFromDIP(map.getDouble("borderRadius").toFloat())
18
24
  val marginTop = parser.toPixelFromDIP(map.getDouble("marginTop").toFloat())
19
25
  val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
20
- return ImageStyle(height, borderRadius, marginTop, marginBottom)
26
+ return ImageStyle(height, maxHeight, aspectRatio, resizeMode, borderRadius, marginTop, marginBottom)
21
27
  }
22
28
  }
23
29
  }
@@ -1,12 +1,17 @@
1
1
  package com.swmansion.enriched.markdown.styles
2
2
 
3
3
  import com.facebook.react.bridge.ReadableMap
4
+ import kotlin.math.ceil
4
5
 
5
6
  data class InlineMathStyle(
6
7
  val color: Int,
7
8
  val paddingVertical: Float,
8
9
  val fontWeight: String,
10
+ val glyphOverflow: Float = 0f,
9
11
  ) {
12
+ /** Line-box padding the span reports: author padding plus the ink headroom. */
13
+ val boxPaddingVertical: Float get() = paddingVertical + glyphOverflow
14
+
10
15
  companion object {
11
16
  fun fromReadableMap(
12
17
  map: ReadableMap,
@@ -15,7 +20,17 @@ data class InlineMathStyle(
15
20
  val color = parser.parseColor(map, "color")
16
21
  val paddingVertical = parser.toPixelFromDIP(map.getDouble("paddingVertical").toFloat())
17
22
  val fontWeight = parser.parseString(map, "fontWeight", "normal")
18
- return InlineMathStyle(color, paddingVertical, fontWeight)
23
+ val glyphOverflow = glyphOverflowPx(parser.parseOptionalDouble(map, "glyphOverflow").toFloat(), parser)
24
+ return InlineMathStyle(color, paddingVertical, fontWeight, glyphOverflow)
19
25
  }
20
26
  }
21
27
  }
28
+
29
+ /**
30
+ * `glyphOverflow` in whole pixels. Rounded up so a measured box and the bitmap or
31
+ * canvas it holds always grow by the same integer amount on each side.
32
+ */
33
+ internal fun glyphOverflowPx(
34
+ dip: Float,
35
+ parser: StyleParser,
36
+ ): Float = if (dip <= 0f) 0f else ceil(parser.toPixelFromDIP(dip))
@@ -7,6 +7,7 @@ data class LinkStyle(
7
7
  val color: Int,
8
8
  val underline: Boolean,
9
9
  val backgroundColor: Int,
10
+ val chip: LinkChipStyle,
10
11
  ) {
11
12
  companion object {
12
13
  fun fromReadableMap(
@@ -17,7 +18,41 @@ data class LinkStyle(
17
18
  val color = parser.parseColor(map, "color")
18
19
  val underline = map.getBoolean("underline")
19
20
  val backgroundColor = parser.parseColor(map, "backgroundColor")
20
- return LinkStyle(fontFamily, color, underline, backgroundColor)
21
+ return LinkStyle(fontFamily, color, underline, backgroundColor, LinkChipStyle.fromReadableMap(map, parser, backgroundColor))
21
22
  }
22
23
  }
23
24
  }
25
+
26
+ /**
27
+ * Chip ("box") properties of a link, in pixels. Never inherited from the base link
28
+ * style by variants — the JS normalizer fills missing values with 0 / transparent.
29
+ */
30
+ data class LinkChipStyle(
31
+ val backgroundColor: Int,
32
+ val borderColor: Int,
33
+ val borderRadius: Float,
34
+ val borderWidth: Float,
35
+ val paddingHorizontal: Float,
36
+ val paddingVertical: Float,
37
+ ) {
38
+ val isVisible: Boolean
39
+ get() =
40
+ android.graphics.Color.alpha(backgroundColor) > 0 ||
41
+ (android.graphics.Color.alpha(borderColor) > 0 && borderWidth > 0f)
42
+
43
+ companion object {
44
+ fun fromReadableMap(
45
+ map: ReadableMap,
46
+ parser: StyleParser,
47
+ backgroundColor: Int,
48
+ ): LinkChipStyle =
49
+ LinkChipStyle(
50
+ backgroundColor = backgroundColor,
51
+ borderColor = parser.parseOptionalColor(map, "borderColor") ?: 0,
52
+ borderRadius = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "borderRadius").toFloat()),
53
+ borderWidth = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "borderWidth").toFloat()),
54
+ paddingHorizontal = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "paddingHorizontal").toFloat()),
55
+ paddingVertical = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "paddingVertical").toFloat()),
56
+ )
57
+ }
58
+ }
@@ -13,17 +13,21 @@ data class LinkVariantEntry(
13
13
  val color: Int,
14
14
  val underline: Boolean,
15
15
  val backgroundColor: Int,
16
+ val chip: LinkChipStyle,
16
17
  ) {
17
18
  companion object {
18
19
  fun fromReadableMap(
19
20
  map: ReadableMap,
20
21
  parser: StyleParser,
21
- ): LinkVariantEntry =
22
- LinkVariantEntry(
22
+ ): LinkVariantEntry {
23
+ val backgroundColor = parser.parseColor(map, "backgroundColor")
24
+ return LinkVariantEntry(
23
25
  pattern = map.getString("pattern") ?: "",
24
26
  color = parser.parseColor(map, "color"),
25
27
  underline = parser.parseBoolean(map, "underline"),
26
- backgroundColor = parser.parseColor(map, "backgroundColor"),
28
+ backgroundColor = backgroundColor,
29
+ chip = LinkChipStyle.fromReadableMap(map, parser, backgroundColor),
27
30
  )
31
+ }
28
32
  }
29
33
  }
@@ -17,6 +17,7 @@ data class ListStyle(
17
17
  val markerFontWeight: String,
18
18
  val gapWidth: Float,
19
19
  val marginLeft: Float,
20
+ val itemSpacing: Float,
20
21
  ) : BaseBlockStyle {
21
22
  fun effectiveMarkerWidth(naturalWidth: Float): Float = naturalWidth.coerceAtLeast(markerMinWidth)
22
23
 
@@ -34,12 +35,13 @@ data class ListStyle(
34
35
  val lineHeightRaw = map.getDouble("lineHeight").toFloat()
35
36
  val lineHeight = parser.toPixelFromSP(lineHeightRaw)
36
37
  val bulletColor = parser.parseColor(map, "bulletColor")
37
- val bulletSize = parser.toPixelFromDIP(map.getDouble("bulletSize").toFloat())
38
+ val bulletSize = parser.toPixelFromSP(map.getDouble("bulletSize").toFloat())
38
39
  val markerMinWidth = parser.toPixelFromDIP(map.getDouble("markerMinWidth").toFloat().coerceAtLeast(0f))
39
40
  val markerColor = parser.parseColor(map, "markerColor")
40
41
  val markerFontWeight = parser.parseString(map, "markerFontWeight", "normal")
41
42
  val gapWidth = parser.toPixelFromDIP(map.getDouble("gapWidth").toFloat())
42
43
  val marginLeft = parser.toPixelFromDIP(map.getDouble("marginLeft").toFloat())
44
+ val itemSpacing = parser.toPixelFromDIP(map.getDouble("itemSpacing").toFloat().coerceAtLeast(0f))
43
45
 
44
46
  return ListStyle(
45
47
  fontSize,
@@ -56,6 +58,7 @@ data class ListStyle(
56
58
  markerFontWeight,
57
59
  gapWidth,
58
60
  marginLeft,
61
+ itemSpacing,
59
62
  )
60
63
  }
61
64
  }
@@ -11,6 +11,7 @@ data class MathStyle(
11
11
  val marginBottom: Float,
12
12
  val textAlign: String,
13
13
  val fontWeight: String,
14
+ val glyphOverflow: Float = 0f,
14
15
  ) {
15
16
  companion object {
16
17
  fun fromReadableMap(
@@ -25,6 +26,7 @@ data class MathStyle(
25
26
  val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
26
27
  val textAlign = parser.parseString(map, "textAlign", "center")
27
28
  val fontWeight = parser.parseString(map, "fontWeight", "normal")
29
+ val glyphOverflow = glyphOverflowPx(parser.parseOptionalDouble(map, "glyphOverflow").toFloat(), parser)
28
30
  return MathStyle(
29
31
  fontSize,
30
32
  color,
@@ -34,6 +36,7 @@ data class MathStyle(
34
36
  marginBottom,
35
37
  textAlign,
36
38
  fontWeight,
39
+ glyphOverflow,
37
40
  )
38
41
  }
39
42
  }
@@ -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
  }