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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (469) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +186 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +35 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -23
  15. package/android/src/main/baseline-prof.txt +1 -1
  16. package/android/src/main/cpp/jni-adapter.cpp +74 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +189 -13
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -1
  21. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
  22. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +42 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
  24. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
  25. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
  27. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  65. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  77. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  96. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
  117. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  120. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +36 -9
  122. package/android/src/main/jni/CMakeLists.txt +53 -0
  123. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  124. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  125. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  126. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  127. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  128. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  129. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  130. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  131. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
  132. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  133. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +6 -4
  134. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  135. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  136. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  137. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  138. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  139. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  140. package/cpp/highlight/gen-registry.mjs +155 -0
  141. package/cpp/highlight/grammar-versions.json +159 -0
  142. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  143. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  144. package/cpp/parser/MD4CParser.cpp +173 -61
  145. package/cpp/parser/MD4CParser.hpp +1 -0
  146. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  147. package/cpp/wasm/ASTSerializer.cpp +2 -0
  148. package/cpp/wasm/build.sh +1 -0
  149. package/cpp/wasm/md4c_wasm.cpp +3 -1
  150. package/docs/ACCESSIBILITY.md +14 -2
  151. package/docs/API_REFERENCE.md +234 -12
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +47 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +108 -11
  158. package/docs/LATEX_MATH.md +87 -45
  159. package/docs/MACOS.md +1 -1
  160. package/docs/MARKDOWN_STREAMING.md +27 -1
  161. package/docs/NATIVE_ASSETS.md +127 -0
  162. package/docs/RTL.md +1 -1
  163. package/docs/STYLES.md +46 -6
  164. package/docs/TESTING.md +112 -0
  165. package/docs/TEXT.md +16 -6
  166. package/docs/WEB.md +3 -1
  167. package/ios/EnrichedMarkdown.h +7 -0
  168. package/ios/EnrichedMarkdown.mm +284 -75
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +101 -73
  171. package/ios/attachments/ENRMImageAttachment.h +9 -0
  172. package/ios/attachments/ENRMImageAttachment.m +143 -40
  173. package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
  174. package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
  175. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  176. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  177. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  178. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +35 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -23
  180. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
  181. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  182. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  183. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  184. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  185. package/ios/input/ENRMBlockRange.h +28 -0
  186. package/ios/input/ENRMBlockRange.mm +30 -0
  187. package/ios/input/ENRMBlockStore.h +56 -0
  188. package/ios/input/ENRMBlockStore.mm +275 -0
  189. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  190. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  191. package/ios/input/ENRMDetectorPipeline.h +2 -1
  192. package/ios/input/ENRMEditPipeline.h +76 -0
  193. package/ios/input/ENRMEditPipeline.mm +228 -0
  194. package/ios/input/ENRMEditSession.h +36 -0
  195. package/ios/input/ENRMEditSession.mm +63 -0
  196. package/ios/input/ENRMFormattingStore.h +17 -0
  197. package/ios/input/ENRMFormattingStore.mm +95 -105
  198. package/ios/input/ENRMInputBlockType.h +91 -0
  199. package/ios/input/ENRMInputBlockType.mm +5 -0
  200. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  201. package/ios/input/ENRMInputEventEmitter.h +56 -0
  202. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  203. package/ios/input/ENRMInputFormatter.h +29 -69
  204. package/ios/input/ENRMInputFormatter.mm +216 -124
  205. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  206. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  207. package/ios/input/ENRMInputLayoutManager.h +9 -0
  208. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  209. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  210. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  211. package/ios/input/ENRMInputParser.h +5 -6
  212. package/ios/input/ENRMInputParser.mm +461 -178
  213. package/ios/input/ENRMInputRemend.mm +2 -2
  214. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  215. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  216. package/ios/input/ENRMInputTextView.mm +103 -8
  217. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  218. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  219. package/ios/input/ENRMLinkCoordinator.h +41 -0
  220. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  221. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  222. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  223. package/ios/input/ENRMMathAtom.h +26 -0
  224. package/ios/input/ENRMMathAtom.mm +12 -0
  225. package/ios/input/ENRMMentionCoordinator.h +45 -0
  226. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  227. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  228. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  229. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  230. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  231. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  232. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  233. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  234. package/ios/input/InputStylePropsUtils.h +109 -68
  235. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  236. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  237. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  238. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  239. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  240. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  241. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  242. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  243. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  244. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  245. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  246. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  248. package/ios/internals/MeasurementCache.h +33 -7
  249. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  250. package/ios/math/ENRMMathChipController.h +74 -0
  251. package/ios/math/ENRMMathChipController.mm +476 -0
  252. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  253. package/ios/parser/ENRMMarkdownParser.h +1 -8
  254. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  255. package/ios/parser/MarkdownASTNode.h +2 -1
  256. package/ios/parser/MarkdownParserBridge.mm +4 -0
  257. package/ios/renderer/AttributedRenderer.m +20 -2
  258. package/ios/renderer/BaseRenderer.h +17 -2
  259. package/ios/renderer/BaseRenderer.m +30 -0
  260. package/ios/renderer/BlockquoteRenderer.h +1 -1
  261. package/ios/renderer/BlockquoteRenderer.m +144 -35
  262. package/ios/renderer/CodeBlockRenderer.h +1 -1
  263. package/ios/renderer/CodeBlockRenderer.m +27 -23
  264. package/ios/renderer/CodeRenderer.h +1 -1
  265. package/ios/renderer/CodeRenderer.m +3 -1
  266. package/ios/renderer/ENRMImageRenderer.h +1 -1
  267. package/ios/renderer/ENRMImageRenderer.m +5 -1
  268. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  269. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  270. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  271. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  272. package/ios/renderer/EmphasisRenderer.h +1 -1
  273. package/ios/renderer/EmphasisRenderer.m +3 -1
  274. package/ios/renderer/HeadingRenderer.h +1 -1
  275. package/ios/renderer/HeadingRenderer.m +13 -6
  276. package/ios/renderer/HighlightRenderer.h +1 -1
  277. package/ios/renderer/HighlightRenderer.m +3 -1
  278. package/ios/renderer/LinkRenderer.h +1 -1
  279. package/ios/renderer/LinkRenderer.m +3 -1
  280. package/ios/renderer/ListItemRenderer.h +13 -1
  281. package/ios/renderer/ListItemRenderer.m +102 -44
  282. package/ios/renderer/ListRenderer.h +2 -2
  283. package/ios/renderer/ListRenderer.m +63 -25
  284. package/ios/renderer/ParagraphRenderer.h +1 -1
  285. package/ios/renderer/ParagraphRenderer.m +16 -8
  286. package/ios/renderer/RenderContext.h +10 -0
  287. package/ios/renderer/RenderContext.m +44 -0
  288. package/ios/renderer/RendererFactory.m +14 -0
  289. package/ios/renderer/StrikethroughRenderer.h +1 -1
  290. package/ios/renderer/StrikethroughRenderer.m +3 -1
  291. package/ios/renderer/StrongRenderer.h +1 -1
  292. package/ios/renderer/StrongRenderer.m +3 -1
  293. package/ios/renderer/SubscriptRenderer.h +1 -1
  294. package/ios/renderer/SubscriptRenderer.m +3 -1
  295. package/ios/renderer/SuperscriptRenderer.h +1 -1
  296. package/ios/renderer/SuperscriptRenderer.m +3 -1
  297. package/ios/renderer/TextRenderer.h +2 -2
  298. package/ios/renderer/TextRenderer.m +3 -1
  299. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  300. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  301. package/ios/renderer/UnderlineRenderer.h +1 -1
  302. package/ios/renderer/UnderlineRenderer.m +3 -1
  303. package/ios/styles/StyleConfig.h +22 -0
  304. package/ios/styles/StyleConfig.mm +132 -0
  305. package/ios/utils/BlockquoteBorder.h +6 -0
  306. package/ios/utils/BlockquoteBorder.m +249 -52
  307. package/ios/utils/CodeBlockBackground.m +16 -2
  308. package/ios/utils/ENRMAtomicSize.h +65 -0
  309. package/ios/utils/ENRMBlockMenu.h +57 -0
  310. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  311. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  312. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  314. package/ios/utils/ENRMFeatureFlags.h +7 -0
  315. package/ios/utils/ENRMImageDownloader.h +11 -1
  316. package/ios/utils/ENRMImageDownloader.m +60 -16
  317. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  318. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  319. package/ios/utils/ENRMMathFallback.h +26 -0
  320. package/ios/utils/ENRMMathFallback.m +18 -0
  321. package/ios/utils/ENRMTextViewSetup.h +35 -17
  322. package/ios/utils/EditMenuUtils.h +22 -5
  323. package/ios/utils/EditMenuUtils.m +53 -9
  324. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  325. package/ios/utils/LastElementUtils.h +1 -0
  326. package/ios/utils/ListMarkerDrawer.m +29 -42
  327. package/ios/utils/MarkdownASTSerializer.m +4 -0
  328. package/ios/utils/ParagraphStyleUtils.h +5 -0
  329. package/ios/utils/ParagraphStyleUtils.m +77 -17
  330. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  331. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  332. package/ios/utils/SegmentRenderer.m +17 -4
  333. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  334. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  335. package/ios/utils/StylePropsUtils.h +63 -0
  336. package/ios/utils/TaskListTapUtils.m +24 -0
  337. package/ios/views/ENRMCodeBlockContainerView.h +53 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +559 -0
  339. package/ios/views/ENRMMathContainerView.h +16 -0
  340. package/ios/views/ENRMMathContainerView.m +74 -19
  341. package/ios/views/TableContainerView.h +22 -0
  342. package/ios/views/TableContainerView.m +261 -175
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -0
  350. package/lib/module/headingDefaults.js +34 -0
  351. package/lib/module/headingDefaults.js.map +1 -0
  352. package/lib/module/index.js.map +1 -1
  353. package/lib/module/jest/index.js +191 -0
  354. package/lib/module/jest/index.js.map +1 -0
  355. package/lib/module/native/EnrichedMarkdownText.js +37 -5
  356. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  357. package/lib/module/normalizeMarkdownStyle.js +81 -19
  358. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  359. package/lib/module/normalizeMarkdownStyle.web.js +56 -18
  360. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  361. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  362. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  363. package/lib/module/normalizeMenuItem.js +1 -1
  364. package/lib/module/utils/textInputState.js +26 -0
  365. package/lib/module/utils/textInputState.js.map +1 -0
  366. package/lib/module/web/EnrichedMarkdownText.js +9 -5
  367. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  368. package/lib/module/web/parseMarkdown.js +4 -3
  369. package/lib/module/web/parseMarkdown.js.map +1 -1
  370. package/lib/module/web/renderers/InlineRenderers.js +6 -0
  371. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  372. package/lib/module/web/renderers/ListRenderers.js +7 -2
  373. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  374. package/lib/module/web/renderers/index.js +7 -4
  375. package/lib/module/web/renderers/index.js.map +1 -1
  376. package/lib/module/web/styles.js +83 -6
  377. package/lib/module/web/styles.js.map +1 -1
  378. package/lib/module/web/utils.js +1 -0
  379. package/lib/module/web/utils.js.map +1 -1
  380. package/lib/module/web/wasm/md4c.js +0 -0
  381. package/lib/module/web/wasm/md4c.js.map +1 -1
  382. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +66 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -0
  389. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  390. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  391. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  392. package/lib/typescript/src/index.d.ts +2 -2
  393. package/lib/typescript/src/index.d.ts.map +1 -1
  394. package/lib/typescript/src/index.web.d.ts +1 -1
  395. package/lib/typescript/src/index.web.d.ts.map +1 -1
  396. package/lib/typescript/src/jest/index.d.ts +6 -0
  397. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  398. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
  399. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  400. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  401. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  402. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  403. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  404. package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
  405. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  406. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
  407. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  408. package/lib/typescript/src/types/MarkdownTextProps.d.ts +104 -9
  409. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  410. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
  411. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  412. package/lib/typescript/src/types/events.d.ts +19 -0
  413. package/lib/typescript/src/types/events.d.ts.map +1 -1
  414. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  415. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  416. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  417. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  418. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  419. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  420. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  421. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  422. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  423. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  424. package/lib/typescript/src/web/styles.d.ts +2 -1
  425. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  426. package/lib/typescript/src/web/types.d.ts +6 -2
  427. package/lib/typescript/src/web/types.d.ts.map +1 -1
  428. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  429. package/package.json +36 -9
  430. package/postinstall.mjs +131 -0
  431. package/ratex-version.json +21 -0
  432. package/src/EnrichedMarkdownNativeComponent.ts +73 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +74 -0
  436. package/src/headingDefaults.ts +21 -0
  437. package/src/index.tsx +9 -0
  438. package/src/index.web.tsx +1 -0
  439. package/src/jest/index.tsx +215 -0
  440. package/src/native/EnrichedMarkdownText.tsx +53 -2
  441. package/src/normalizeMarkdownStyle.ts +102 -16
  442. package/src/normalizeMarkdownStyle.web.ts +63 -15
  443. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  444. package/src/normalizeMenuItem.ts +1 -1
  445. package/src/types/MarkdownStyle.ts +74 -0
  446. package/src/types/MarkdownStyleInternal.ts +39 -0
  447. package/src/types/MarkdownTextProps.ts +101 -9
  448. package/src/types/MarkdownTextProps.web.ts +19 -0
  449. package/src/types/events.ts +21 -0
  450. package/src/utils/textInputState.ts +35 -0
  451. package/src/web/EnrichedMarkdownText.tsx +16 -2
  452. package/src/web/parseMarkdown.ts +6 -2
  453. package/src/web/renderers/InlineRenderers.tsx +5 -0
  454. package/src/web/renderers/ListRenderers.tsx +14 -2
  455. package/src/web/renderers/index.tsx +6 -2
  456. package/src/web/styles.ts +89 -5
  457. package/src/web/types.ts +6 -1
  458. package/src/web/utils.ts +1 -0
  459. package/src/web/wasm/md4c.js +0 -0
  460. package/vendor-grammars.mjs +511 -0
  461. package/vendor-ratex.mjs +173 -0
  462. package/app.plugin.js +0 -2
  463. package/plugin/build/withAndroidMath.js +0 -19
  464. package/plugin/build/withIosMath.js +0 -28
  465. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  466. package/plugin/src/withAndroidMath.ts +0 -24
  467. package/plugin/src/withIosMath.ts +0 -35
  468. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  469. package/plugin/tsconfig.build.json +0 -16
@@ -208,12 +208,20 @@ NS_ASSUME_NONNULL_BEGIN
208
208
  // Image properties
209
209
  - (CGFloat)imageHeight;
210
210
  - (void)setImageHeight:(CGFloat)newValue;
211
+ - (CGFloat)imageMaxHeight;
212
+ - (void)setImageMaxHeight:(CGFloat)newValue;
213
+ - (CGFloat)imageAspectRatio;
214
+ - (void)setImageAspectRatio:(CGFloat)newValue;
215
+ - (NSString *)imageResizeMode;
216
+ - (void)setImageResizeMode:(NSString *)newValue;
211
217
  - (CGFloat)imageBorderRadius;
212
218
  - (void)setImageBorderRadius:(CGFloat)newValue;
213
219
  - (CGFloat)imageMarginTop;
214
220
  - (void)setImageMarginTop:(CGFloat)newValue;
215
221
  - (CGFloat)imageMarginBottom;
216
222
  - (void)setImageMarginBottom:(CGFloat)newValue;
223
+ - (nullable NSDictionary<NSString *, NSString *> *)imageRequestHeaders;
224
+ - (void)setImageRequestHeaders:(nullable NSDictionary<NSString *, NSString *> *)newValue;
217
225
  // Inline image properties
218
226
  - (CGFloat)inlineImageSize;
219
227
  - (void)setInlineImageSize:(CGFloat)newValue;
@@ -241,6 +249,10 @@ NS_ASSUME_NONNULL_BEGIN
241
249
  - (void)setBlockquoteGapWidth:(CGFloat)newValue;
242
250
  - (RCTUIColor *)blockquoteBackgroundColor;
243
251
  - (void)setBlockquoteBackgroundColor:(RCTUIColor *)newValue;
252
+ - (CGFloat)blockquoteBorderRadius;
253
+ - (void)setBlockquoteBorderRadius:(CGFloat)newValue;
254
+ - (CGFloat)blockquotePadding;
255
+ - (void)setBlockquotePadding:(CGFloat)newValue;
244
256
  // List style properties (combined for both ordered and unordered lists)
245
257
  - (CGFloat)listStyleFontSize;
246
258
  - (void)setListStyleFontSize:(CGFloat)newValue;
@@ -270,6 +282,8 @@ NS_ASSUME_NONNULL_BEGIN
270
282
  - (void)setListStyleGapWidth:(CGFloat)newValue;
271
283
  - (CGFloat)listStyleMarginLeft;
272
284
  - (void)setListStyleMarginLeft:(CGFloat)newValue;
285
+ - (CGFloat)listStyleItemSpacing;
286
+ - (void)setListStyleItemSpacing:(CGFloat)newValue;
273
287
  - (UIFont *)listMarkerFont;
274
288
  - (UIFont *)listStyleFont;
275
289
  - (CGFloat)effectiveListGapWidth;
@@ -302,6 +316,10 @@ NS_ASSUME_NONNULL_BEGIN
302
316
  - (CGFloat)codeBlockPadding;
303
317
  - (void)setCodeBlockPadding:(CGFloat)newValue;
304
318
  - (UIFont *)codeBlockFont;
319
+ // Syntax highlight colors, indexed by HighlightTokenType ordinal. Resolved on
320
+ // the JS side; the getter returns a cached color with no allocation.
321
+ - (RCTUIColor *_Nullable)codeBlockSyntaxColorForToken:(NSInteger)tokenType;
322
+ - (void)setCodeBlockSyntaxColor:(RCTUIColor *)newValue forToken:(NSInteger)tokenType;
305
323
  // Thematic break properties
306
324
  - (RCTUIColor *)thematicBreakColor;
307
325
  - (void)setThematicBreakColor:(RCTUIColor *)newValue;
@@ -348,6 +366,10 @@ NS_ASSUME_NONNULL_BEGIN
348
366
  - (void)setTableCellPaddingHorizontal:(CGFloat)newValue;
349
367
  - (CGFloat)tableCellPaddingVertical;
350
368
  - (void)setTableCellPaddingVertical:(CGFloat)newValue;
369
+ - (CGFloat)tableHorizontalOverflow;
370
+ - (void)setTableHorizontalOverflow:(CGFloat)newValue;
371
+ - (NSString *)tableAlign;
372
+ - (void)setTableAlign:(NSString *)newValue;
351
373
  // Task list checkbox properties
352
374
  - (RCTUIColor *)taskListCheckedColor;
353
375
  - (void)setTaskListCheckedColor:(RCTUIColor *)newValue;
@@ -1,9 +1,13 @@
1
1
  #import "StyleConfig.h"
2
+ #include "CodeBlockHighlighter.hpp"
2
3
  #import "ENRMFontSlot.h"
3
4
  #import "FontUtils.h"
4
5
  #import <React/RCTFont.h>
5
6
  #import <React/RCTUtils.h>
6
7
 
8
+ static const NSInteger kENRMCodeBlockSyntaxColorCount =
9
+ static_cast<NSInteger>(Markdown::HighlightTokenType::Embedded) + 1;
10
+
7
11
  static inline NSString *normalizedFontWeight(NSString *fontWeight)
8
12
  {
9
13
  // If nil or empty string, return nil to let RCTFont use fontFamily as-is
@@ -134,9 +138,13 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
134
138
  RCTUIColor *_codeBorderColor;
135
139
  // Image properties
136
140
  CGFloat _imageHeight;
141
+ CGFloat _imageMaxHeight;
142
+ CGFloat _imageAspectRatio;
143
+ NSString *_imageResizeMode;
137
144
  CGFloat _imageBorderRadius;
138
145
  CGFloat _imageMarginTop;
139
146
  CGFloat _imageMarginBottom;
147
+ NSDictionary<NSString *, NSString *> *_imageRequestHeaders;
140
148
  // Inline image properties
141
149
  CGFloat _inlineImageSize;
142
150
  // Blockquote properties
@@ -151,6 +159,8 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
151
159
  CGFloat _blockquoteBorderWidth;
152
160
  CGFloat _blockquoteGapWidth;
153
161
  RCTUIColor *_blockquoteBackgroundColor;
162
+ CGFloat _blockquoteBorderRadius;
163
+ CGFloat _blockquotePadding;
154
164
  ENRMFontSlot *_blockquoteFont;
155
165
  // List style properties (combined for both ordered and unordered lists)
156
166
  CGFloat _listStyleFontSize;
@@ -167,6 +177,7 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
167
177
  NSString *_listStyleMarkerFontWeight;
168
178
  CGFloat _listStyleGapWidth;
169
179
  CGFloat _listStyleMarginLeft;
180
+ CGFloat _listStyleItemSpacing;
170
181
  ENRMFontSlot *_listMarkerFont;
171
182
  ENRMFontSlot *_listStyleFont;
172
183
  // Code block properties
@@ -182,6 +193,7 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
182
193
  CGFloat _codeBlockBorderRadius;
183
194
  CGFloat _codeBlockBorderWidth;
184
195
  CGFloat _codeBlockPadding;
196
+ RCTUIColor *_codeBlockSyntaxColors[kENRMCodeBlockSyntaxColorCount];
185
197
  ENRMFontSlot *_codeBlockFont;
186
198
  // Thematic break properties
187
199
  RCTUIColor *_thematicBreakColor;
@@ -208,6 +220,8 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
208
220
  CGFloat _tableBorderRadius;
209
221
  CGFloat _tableCellPaddingHorizontal;
210
222
  CGFloat _tableCellPaddingVertical;
223
+ CGFloat _tableHorizontalOverflow;
224
+ NSString *_tableAlign;
211
225
  // Task list checkbox
212
226
  RCTUIColor *_taskListCheckedColor;
213
227
  RCTUIColor *_taskListBorderColor;
@@ -409,9 +423,13 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
409
423
  copy->_codeBackgroundColor = [_codeBackgroundColor copy];
410
424
  copy->_codeBorderColor = [_codeBorderColor copy];
411
425
  copy->_imageHeight = _imageHeight;
426
+ copy->_imageMaxHeight = _imageMaxHeight;
427
+ copy->_imageAspectRatio = _imageAspectRatio;
428
+ copy->_imageResizeMode = [_imageResizeMode copy];
412
429
  copy->_imageBorderRadius = _imageBorderRadius;
413
430
  copy->_imageMarginTop = _imageMarginTop;
414
431
  copy->_imageMarginBottom = _imageMarginBottom;
432
+ copy->_imageRequestHeaders = [_imageRequestHeaders copy];
415
433
  copy->_inlineImageSize = _inlineImageSize;
416
434
  copy->_blockquoteFontSize = _blockquoteFontSize;
417
435
  copy->_blockquoteFontFamily = [_blockquoteFontFamily copy];
@@ -424,6 +442,8 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
424
442
  copy->_blockquoteBorderWidth = _blockquoteBorderWidth;
425
443
  copy->_blockquoteGapWidth = _blockquoteGapWidth;
426
444
  copy->_blockquoteBackgroundColor = [_blockquoteBackgroundColor copy];
445
+ copy->_blockquoteBorderRadius = _blockquoteBorderRadius;
446
+ copy->_blockquotePadding = _blockquotePadding;
427
447
  copy->_listStyleFontSize = _listStyleFontSize;
428
448
  copy->_listStyleFontFamily = [_listStyleFontFamily copy];
429
449
  copy->_listStyleFontWeight = [_listStyleFontWeight copy];
@@ -438,6 +458,7 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
438
458
  copy->_listStyleMarkerFontWeight = [_listStyleMarkerFontWeight copy];
439
459
  copy->_listStyleGapWidth = _listStyleGapWidth;
440
460
  copy->_listStyleMarginLeft = _listStyleMarginLeft;
461
+ copy->_listStyleItemSpacing = _listStyleItemSpacing;
441
462
  copy->_codeBlockFontSize = _codeBlockFontSize;
442
463
  copy->_codeBlockFontFamily = [_codeBlockFontFamily copy];
443
464
  copy->_codeBlockFontWeight = [_codeBlockFontWeight copy];
@@ -450,6 +471,9 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
450
471
  copy->_codeBlockBorderRadius = _codeBlockBorderRadius;
451
472
  copy->_codeBlockBorderWidth = _codeBlockBorderWidth;
452
473
  copy->_codeBlockPadding = _codeBlockPadding;
474
+ for (NSInteger i = 0; i < kENRMCodeBlockSyntaxColorCount; i++) {
475
+ copy->_codeBlockSyntaxColors[i] = [_codeBlockSyntaxColors[i] copy];
476
+ }
453
477
  copy->_thematicBreakColor = [_thematicBreakColor copy];
454
478
  copy->_thematicBreakHeight = _thematicBreakHeight;
455
479
  copy->_thematicBreakMarginTop = _thematicBreakMarginTop;
@@ -471,6 +495,8 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
471
495
  copy->_tableBorderRadius = _tableBorderRadius;
472
496
  copy->_tableCellPaddingHorizontal = _tableCellPaddingHorizontal;
473
497
  copy->_tableCellPaddingVertical = _tableCellPaddingVertical;
498
+ copy->_tableHorizontalOverflow = _tableHorizontalOverflow;
499
+ copy->_tableAlign = [_tableAlign copy];
474
500
  copy->_taskListCheckedColor = [_taskListCheckedColor copy];
475
501
  copy->_taskListBorderColor = [_taskListBorderColor copy];
476
502
  copy->_taskListCheckboxSize = _taskListCheckboxSize;
@@ -1509,6 +1535,36 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
1509
1535
  _imageHeight = newValue;
1510
1536
  }
1511
1537
 
1538
+ - (CGFloat)imageMaxHeight
1539
+ {
1540
+ return _imageMaxHeight;
1541
+ }
1542
+
1543
+ - (void)setImageMaxHeight:(CGFloat)newValue
1544
+ {
1545
+ _imageMaxHeight = newValue;
1546
+ }
1547
+
1548
+ - (CGFloat)imageAspectRatio
1549
+ {
1550
+ return _imageAspectRatio;
1551
+ }
1552
+
1553
+ - (void)setImageAspectRatio:(CGFloat)newValue
1554
+ {
1555
+ _imageAspectRatio = newValue;
1556
+ }
1557
+
1558
+ - (NSString *)imageResizeMode
1559
+ {
1560
+ return _imageResizeMode ?: @"";
1561
+ }
1562
+
1563
+ - (void)setImageResizeMode:(NSString *)newValue
1564
+ {
1565
+ _imageResizeMode = newValue;
1566
+ }
1567
+
1512
1568
  - (CGFloat)imageBorderRadius
1513
1569
  {
1514
1570
  return _imageBorderRadius;
@@ -1539,6 +1595,16 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
1539
1595
  _imageMarginBottom = newValue;
1540
1596
  }
1541
1597
 
1598
+ - (NSDictionary<NSString *, NSString *> *)imageRequestHeaders
1599
+ {
1600
+ return _imageRequestHeaders;
1601
+ }
1602
+
1603
+ - (void)setImageRequestHeaders:(NSDictionary<NSString *, NSString *> *)newValue
1604
+ {
1605
+ _imageRequestHeaders = [newValue copy];
1606
+ }
1607
+
1542
1608
  - (CGFloat)inlineImageSize
1543
1609
  {
1544
1610
  return _inlineImageSize;
@@ -1681,6 +1747,26 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
1681
1747
  _blockquoteBackgroundColor = newValue;
1682
1748
  }
1683
1749
 
1750
+ - (CGFloat)blockquoteBorderRadius
1751
+ {
1752
+ return _blockquoteBorderRadius;
1753
+ }
1754
+
1755
+ - (void)setBlockquoteBorderRadius:(CGFloat)newValue
1756
+ {
1757
+ _blockquoteBorderRadius = newValue;
1758
+ }
1759
+
1760
+ - (CGFloat)blockquotePadding
1761
+ {
1762
+ return _blockquotePadding;
1763
+ }
1764
+
1765
+ - (void)setBlockquotePadding:(CGFloat)newValue
1766
+ {
1767
+ _blockquotePadding = newValue;
1768
+ }
1769
+
1684
1770
  // List style properties (combined for both ordered and unordered lists)
1685
1771
  - (CGFloat)listStyleFontSize
1686
1772
  {
@@ -1831,6 +1917,16 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
1831
1917
  _listStyleMarginLeft = newValue;
1832
1918
  }
1833
1919
 
1920
+ - (CGFloat)listStyleItemSpacing
1921
+ {
1922
+ return _listStyleItemSpacing;
1923
+ }
1924
+
1925
+ - (void)setListStyleItemSpacing:(CGFloat)newValue
1926
+ {
1927
+ _listStyleItemSpacing = newValue;
1928
+ }
1929
+
1834
1930
  - (UIFont *)listMarkerFont
1835
1931
  {
1836
1932
  if (_listMarkerFont.needsRecreation || !_listMarkerFont.cachedFont) {
@@ -2028,6 +2124,22 @@ static const CGFloat kDefaultMinGap = 4.0;
2028
2124
  return _codeBlockFont.cachedFont;
2029
2125
  }
2030
2126
 
2127
+ - (RCTUIColor *)codeBlockSyntaxColorForToken:(NSInteger)tokenType
2128
+ {
2129
+ if (tokenType < 0 || tokenType >= kENRMCodeBlockSyntaxColorCount) {
2130
+ return nil;
2131
+ }
2132
+ return _codeBlockSyntaxColors[tokenType];
2133
+ }
2134
+
2135
+ - (void)setCodeBlockSyntaxColor:(RCTUIColor *)newValue forToken:(NSInteger)tokenType
2136
+ {
2137
+ if (tokenType < 0 || tokenType >= kENRMCodeBlockSyntaxColorCount) {
2138
+ return;
2139
+ }
2140
+ _codeBlockSyntaxColors[tokenType] = newValue;
2141
+ }
2142
+
2031
2143
  // Thematic break properties
2032
2144
  - (RCTUIColor *)thematicBreakColor
2033
2145
  {
@@ -2280,6 +2392,26 @@ static const CGFloat kDefaultMinGap = 4.0;
2280
2392
  _tableCellPaddingVertical = newValue;
2281
2393
  }
2282
2394
 
2395
+ - (CGFloat)tableHorizontalOverflow
2396
+ {
2397
+ return _tableHorizontalOverflow;
2398
+ }
2399
+
2400
+ - (void)setTableHorizontalOverflow:(CGFloat)newValue
2401
+ {
2402
+ _tableHorizontalOverflow = newValue;
2403
+ }
2404
+
2405
+ - (NSString *)tableAlign
2406
+ {
2407
+ return _tableAlign ?: @"";
2408
+ }
2409
+
2410
+ - (void)setTableAlign:(NSString *)newValue
2411
+ {
2412
+ _tableAlign = newValue;
2413
+ }
2414
+
2283
2415
  // Task list
2284
2416
 
2285
2417
  - (RCTUIColor *)taskListCheckedColor
@@ -6,6 +6,12 @@ NS_ASSUME_NONNULL_BEGIN
6
6
 
7
7
  extern NSString *const BlockquoteDepthAttributeName;
8
8
  extern NSString *const BlockquoteBackgroundColorAttributeName;
9
+ extern NSString *const BlockquoteSpacerAttributeName;
10
+
11
+ static inline CGFloat blockquoteIndentForDepth(NSInteger depth, CGFloat levelSpacing)
12
+ {
13
+ return depth * levelSpacing;
14
+ }
9
15
 
10
16
  @interface BlockquoteBorder : NSObject
11
17
 
@@ -5,6 +5,7 @@
5
5
  // Attribute constants for identifying blockquote segments in text storage
6
6
  NSString *const BlockquoteDepthAttributeName = @"BlockquoteDepth";
7
7
  NSString *const BlockquoteBackgroundColorAttributeName = @"BlockquoteBackgroundColor";
8
+ NSString *const BlockquoteSpacerAttributeName = @"BlockquoteSpacer";
8
9
 
9
10
  @implementation BlockquoteBorder {
10
11
  StyleConfig *_config;
@@ -20,7 +21,15 @@ NSString *const BlockquoteBackgroundColorAttributeName = @"BlockquoteBackgroundC
20
21
 
21
22
  /**
22
23
  * Main drawing entry point called by the LayoutManager.
23
- * Iterates through line fragments to draw backgrounds and borders for nested blockquotes.
24
+ * Collects contiguous blockquote regions and draws each as one rounded box:
25
+ * background fill first, then the vertical borders clipped to the box shape.
26
+ * When a border radius is set, each nested quote's stripes are additionally
27
+ * clipped to that quote's own rounded box, mirroring per-element CSS
28
+ * border-radius on web.
29
+ * Regions are discovered by scanning only the drawn character range; regions
30
+ * touching its edges are extended run-by-run to their true boundaries, so the
31
+ * cost scales with the visible text plus the intersecting quotes rather than
32
+ * the whole document.
24
33
  */
25
34
  - (void)drawBordersForGlyphRange:(NSRange)glyphsToShow
26
35
  layoutManager:(NSLayoutManager *)layoutManager
@@ -32,66 +41,254 @@ NSString *const BlockquoteBackgroundColorAttributeName = @"BlockquoteBackgroundC
32
41
  return;
33
42
  }
34
43
 
44
+ NSRange charRange = [layoutManager characterRangeForGlyphRange:glyphsToShow actualGlyphRange:NULL];
45
+ if (charRange.location == NSNotFound || charRange.length == 0) {
46
+ return;
47
+ }
48
+
49
+ NSMutableArray<NSValue *> *regions = [NSMutableArray array];
50
+ __block NSRange currentRegion = NSMakeRange(NSNotFound, 0);
51
+ [textStorage enumerateAttribute:BlockquoteDepthAttributeName
52
+ inRange:charRange
53
+ options:0
54
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
55
+ if (!value) {
56
+ if (currentRegion.location != NSNotFound) {
57
+ [regions addObject:[NSValue valueWithRange:currentRegion]];
58
+ currentRegion = NSMakeRange(NSNotFound, 0);
59
+ }
60
+ return;
61
+ }
62
+ currentRegion =
63
+ currentRegion.location == NSNotFound ? range : NSUnionRange(currentRegion, range);
64
+ }];
65
+ if (currentRegion.location != NSNotFound) {
66
+ [regions addObject:[NSValue valueWithRange:currentRegion]];
67
+ }
68
+
69
+ if (regions.count == 0) {
70
+ return;
71
+ }
72
+
73
+ NSRange firstRegion = regions.firstObject.rangeValue;
74
+ if (firstRegion.location == charRange.location) {
75
+ while (firstRegion.location > 0) {
76
+ NSRange runRange;
77
+ if (![textStorage attribute:BlockquoteDepthAttributeName
78
+ atIndex:firstRegion.location - 1
79
+ effectiveRange:&runRange]) {
80
+ break;
81
+ }
82
+ firstRegion = NSUnionRange(firstRegion, runRange);
83
+ }
84
+ regions[0] = [NSValue valueWithRange:firstRegion];
85
+ }
86
+
87
+ NSRange lastRegion = regions.lastObject.rangeValue;
88
+ if (NSMaxRange(lastRegion) == NSMaxRange(charRange)) {
89
+ while (NSMaxRange(lastRegion) < textStorage.length) {
90
+ NSRange runRange;
91
+ if (![textStorage attribute:BlockquoteDepthAttributeName
92
+ atIndex:NSMaxRange(lastRegion)
93
+ effectiveRange:&runRange]) {
94
+ break;
95
+ }
96
+ lastRegion = NSUnionRange(lastRegion, runRange);
97
+ }
98
+ regions[regions.count - 1] = [NSValue valueWithRange:lastRegion];
99
+ }
100
+
101
+ for (NSValue *value in regions) {
102
+ [self drawBlockquoteRegion:value.rangeValue layoutManager:layoutManager textContainer:textContainer atPoint:origin];
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Groups the depth runs of a region into nested quote boxes: for each level
108
+ * >= 1, a box is a maximal contiguous stretch where depth >= level (a nested
109
+ * quote's own range). Outputs parallel arrays of ranges and levels.
110
+ */
111
+ static void collectNestedBoxes(NSArray<NSValue *> *runRanges, NSArray<NSNumber *> *runDepths,
112
+ NSMutableArray<NSValue *> *boxRanges, NSMutableArray<NSNumber *> *boxLevels)
113
+ {
114
+ NSInteger maxDepth = 0;
115
+ for (NSNumber *depth in runDepths) {
116
+ maxDepth = MAX(maxDepth, depth.integerValue);
117
+ }
118
+
119
+ for (NSInteger level = 1; level <= maxDepth; level++) {
120
+ NSRange current = NSMakeRange(NSNotFound, 0);
121
+ for (NSUInteger i = 0; i < runRanges.count; i++) {
122
+ if (runDepths[i].integerValue >= level) {
123
+ NSRange runRange = runRanges[i].rangeValue;
124
+ current = current.location == NSNotFound ? runRange : NSUnionRange(current, runRange);
125
+ } else if (current.location != NSNotFound) {
126
+ [boxRanges addObject:[NSValue valueWithRange:current]];
127
+ [boxLevels addObject:@(level)];
128
+ current = NSMakeRange(NSNotFound, 0);
129
+ }
130
+ }
131
+ if (current.location != NSNotFound) {
132
+ [boxRanges addObject:[NSValue valueWithRange:current]];
133
+ [boxLevels addObject:@(level)];
134
+ }
135
+ }
136
+ }
137
+
138
+ - (void)drawBlockquoteRegion:(NSRange)region
139
+ layoutManager:(NSLayoutManager *)layoutManager
140
+ textContainer:(NSTextContainer *)textContainer
141
+ atPoint:(CGPoint)origin
142
+ {
143
+ NSTextStorage *textStorage = layoutManager.textStorage;
144
+
35
145
  // Cache configuration values to minimize pointer chasing and method lookups in the loop
36
146
  StyleConfig *c = _config;
37
147
  CGFloat borderWidth = c.blockquoteBorderWidth;
38
148
  CGFloat gapWidth = c.blockquoteGapWidth;
39
149
  CGFloat levelSpacing = borderWidth + gapWidth;
150
+ CGFloat borderRadius = c.blockquoteBorderRadius;
40
151
  CGFloat containerWidth = textContainer.size.width;
41
152
  RCTUIColor *defaultBgColor = c.blockquoteBackgroundColor;
42
153
  RCTUIColor *borderColor = c.blockquoteBorderColor;
43
154
 
44
- UIBezierPath *borderPath = [UIBezierPath bezierPath];
45
-
46
- [layoutManager
47
- enumerateLineFragmentsForGlyphRange:glyphsToShow
48
- usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *container,
49
- NSRange glyphRange, BOOL *stop) {
50
- // Map the glyph range back to character indices to retrieve attributes
51
- NSRange charRange = [layoutManager characterRangeForGlyphRange:glyphRange
52
- actualGlyphRange:NULL];
53
- if (charRange.location == NSNotFound || charRange.length == 0) {
54
- return;
55
- }
56
-
57
- // Perform a single attribute lookup for the current line fragment
58
- NSDictionary *attrs = [textStorage attributesAtIndex:charRange.location
59
- effectiveRange:NULL];
60
- NSNumber *depthNum = attrs[BlockquoteDepthAttributeName];
61
-
62
- // If no depth is found, this fragment is not part of a blockquote
63
- if (!depthNum) {
64
- return;
65
- }
66
-
67
- NSInteger depth = [depthNum integerValue];
68
- CGFloat baseY = origin.y + rect.origin.y;
69
- BOOL isRTL = ENRMParagraphIsRTL(attrs[NSParagraphStyleAttributeName]);
70
-
71
- // 1. Draw Background (Painter's algorithm: draw backgrounds before borders)
72
- RCTUIColor *bgColor = attrs[BlockquoteBackgroundColorAttributeName] ?: defaultBgColor;
73
- if (bgColor && bgColor != [RCTUIColor clearColor]) {
74
- CGContextRef ctx = UIGraphicsGetCurrentContext();
75
- [bgColor setFill];
76
- CGContextFillRect(ctx,
77
- CGRectMake(origin.x, baseY, containerWidth, rect.size.height));
78
- }
79
-
80
- // 2. Aggregate vertical borders into the batch path
81
- for (NSInteger level = 0; level <= depth; level++) {
82
- CGFloat borderX =
83
- isRTL ? origin.x + containerWidth - borderWidth - (levelSpacing * level)
84
- : origin.x + (levelSpacing * level);
85
- CGRect borderRect = CGRectMake(borderX, baseY, borderWidth, rect.size.height);
86
- UIBezierPathAppendPath(borderPath, [UIBezierPath bezierPathWithRect:borderRect]);
87
- }
88
- }];
89
-
90
- // 3. Perform a single batch fill for all borders
91
- if (!borderPath.isEmpty) {
92
- [borderColor setFill];
93
- [borderPath fill];
155
+ NSRange glyphRange = [layoutManager glyphRangeForCharacterRange:region actualCharacterRange:NULL];
156
+ CGRect blockRect = [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];
157
+ if (CGRectIsEmpty(blockRect)) {
158
+ return;
159
+ }
160
+
161
+ blockRect.origin.x = origin.x;
162
+ blockRect.origin.y += origin.y;
163
+ blockRect.size.width = containerWidth;
164
+
165
+ BOOL isLastBlockquote = (NSMaxRange(region) == textStorage.length);
166
+ if (isLastBlockquote) {
167
+ blockRect.size.height += c.blockquotePadding;
168
+ }
169
+
170
+ NSMutableArray<NSValue *> *boxRanges = [NSMutableArray array];
171
+ NSMutableArray<NSNumber *> *boxLevels = [NSMutableArray array];
172
+ NSMutableArray<UIBezierPath *> *boxStripePaths = [NSMutableArray array];
173
+ if (borderRadius > 0) {
174
+ NSMutableArray<NSValue *> *runRanges = [NSMutableArray array];
175
+ NSMutableArray<NSNumber *> *runDepths = [NSMutableArray array];
176
+ [textStorage enumerateAttribute:BlockquoteDepthAttributeName
177
+ inRange:region
178
+ options:0
179
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
180
+ if (!value) {
181
+ return;
182
+ }
183
+ [runRanges addObject:[NSValue valueWithRange:range]];
184
+ [runDepths addObject:value];
185
+ }];
186
+ collectNestedBoxes(runRanges, runDepths, boxRanges, boxLevels);
187
+ for (NSUInteger i = 0; i < boxRanges.count; i++) {
188
+ [boxStripePaths addObject:[UIBezierPath bezierPath]];
189
+ }
190
+ }
191
+
192
+ CGContextRef ctx = UIGraphicsGetCurrentContext();
193
+ CGContextSaveGState(ctx);
194
+ {
195
+ UIBezierPath *boxPath = UIBezierPathWithRoundedRect(blockRect, MAX(0, borderRadius));
196
+ [boxPath addClip];
197
+
198
+ // 1. Draw Background (Painter's algorithm: draw backgrounds before borders)
199
+ RCTUIColor *bgColor = [textStorage attribute:BlockquoteBackgroundColorAttributeName
200
+ atIndex:region.location
201
+ effectiveRange:NULL]
202
+ ?: defaultBgColor;
203
+ if (bgColor && bgColor != [RCTUIColor clearColor]) {
204
+ [bgColor setFill];
205
+ CGContextFillRect(ctx, blockRect);
206
+ }
207
+
208
+ // 2. Aggregate vertical borders into batch paths; level-0 stripes are
209
+ // rounded by the region clip, nested stripes by their own box clip below
210
+ UIBezierPath *borderPath = [UIBezierPath bezierPath];
211
+ [layoutManager
212
+ enumerateLineFragmentsForGlyphRange:glyphRange
213
+ usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *container,
214
+ NSRange lineGlyphRange, BOOL *stop) {
215
+ NSRange lineCharRange = [layoutManager characterRangeForGlyphRange:lineGlyphRange
216
+ actualGlyphRange:NULL];
217
+ if (lineCharRange.location == NSNotFound || lineCharRange.length == 0) {
218
+ return;
219
+ }
220
+
221
+ NSDictionary *attrs = [textStorage attributesAtIndex:lineCharRange.location
222
+ effectiveRange:NULL];
223
+ NSNumber *depthNum = attrs[BlockquoteDepthAttributeName];
224
+
225
+ if (!depthNum) {
226
+ return;
227
+ }
228
+
229
+ NSInteger depth = [depthNum integerValue];
230
+ CGFloat baseY = origin.y + rect.origin.y;
231
+ CGFloat lineHeight = rect.size.height;
232
+ BOOL isLastLine = NSMaxRange(lineGlyphRange) == NSMaxRange(glyphRange);
233
+ if (isLastBlockquote && isLastLine) {
234
+ lineHeight += c.blockquotePadding;
235
+ }
236
+ BOOL isRTL = ENRMParagraphIsRTL(attrs[NSParagraphStyleAttributeName]);
237
+
238
+ for (NSInteger level = 0; level <= depth; level++) {
239
+ CGFloat borderX =
240
+ isRTL ? origin.x + containerWidth - borderWidth - (levelSpacing * level)
241
+ : origin.x + (levelSpacing * level);
242
+ CGRect borderRect = CGRectMake(borderX, baseY, borderWidth, lineHeight);
243
+
244
+ UIBezierPath *target = borderPath;
245
+ for (NSUInteger b = 0; b < boxRanges.count; b++) {
246
+ if (boxLevels[b].integerValue == level &&
247
+ NSLocationInRange(lineCharRange.location, boxRanges[b].rangeValue)) {
248
+ target = boxStripePaths[b];
249
+ break;
250
+ }
251
+ }
252
+ UIBezierPathAppendPath(target, [UIBezierPath bezierPathWithRect:borderRect]);
253
+ }
254
+ }];
255
+
256
+ // 3. Perform a single batch fill for the root-level borders
257
+ if (!borderPath.isEmpty) {
258
+ [borderColor setFill];
259
+ [borderPath fill];
260
+ }
261
+
262
+ // 4. Nested stripes: clip each to its own quote's rounded box (the clips
263
+ // compose with the still-active region clip)
264
+ for (NSUInteger b = 0; b < boxRanges.count; b++) {
265
+ UIBezierPath *stripes = boxStripePaths[b];
266
+ if (stripes.isEmpty) {
267
+ continue;
268
+ }
269
+
270
+ NSRange boxRange = boxRanges[b].rangeValue;
271
+ NSRange boxGlyphRange = [layoutManager glyphRangeForCharacterRange:boxRange actualCharacterRange:NULL];
272
+ CGRect boxRect = [layoutManager boundingRectForGlyphRange:boxGlyphRange inTextContainer:textContainer];
273
+ if (CGRectIsEmpty(boxRect)) {
274
+ continue;
275
+ }
276
+
277
+ NSDictionary *boxAttrs = [textStorage attributesAtIndex:boxRange.location effectiveRange:NULL];
278
+ BOOL boxRTL = ENRMParagraphIsRTL(boxAttrs[NSParagraphStyleAttributeName]);
279
+ CGFloat leadingInset = levelSpacing * boxLevels[b].integerValue;
280
+ boxRect.origin.x = boxRTL ? origin.x : origin.x + leadingInset;
281
+ boxRect.origin.y += origin.y;
282
+ boxRect.size.width = containerWidth - leadingInset;
283
+
284
+ CGContextSaveGState(ctx);
285
+ [UIBezierPathWithRoundedRect(boxRect, borderRadius) addClip];
286
+ [borderColor setFill];
287
+ [stripes fill];
288
+ CGContextRestoreGState(ctx);
289
+ }
94
290
  }
291
+ CGContextRestoreGState(ctx);
95
292
  }
96
293
 
97
- @end
294
+ @end