react-native-enriched-markdown-scaffold 0.6.0-scaffold.4

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 (678) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +53 -0
  3. package/ReactNativeEnrichedMarkdown.podspec +67 -0
  4. package/android/build.gradle +94 -0
  5. package/android/consumer-rules.pro +19 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +87 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +37 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +159 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +59 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +87 -0
  11. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +37 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +318 -0
  15. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +259 -0
  16. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +375 -0
  17. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +5174 -0
  18. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
  19. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.h +23 -0
  20. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.cpp +16 -0
  21. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.h +20 -0
  22. package/android/gradle.properties +5 -0
  23. package/android/src/main/AndroidManifest.xml +2 -0
  24. package/android/src/main/baseline-prof.txt +254 -0
  25. package/android/src/main/cpp/jni-adapter.cpp +264 -0
  26. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +554 -0
  27. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +122 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +255 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +363 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +15 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +253 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextPackage.kt +20 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +653 -0
  34. package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt +33 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/MarkdownAccessibilityHelper.kt +482 -0
  36. package/android/src/main/java/com/swmansion/enriched/markdown/events/ContextMenuItemPressEvent.kt +28 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLongPressEvent.kt +23 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkPressEvent.kt +23 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/events/TaskListItemPressEvent.kt +26 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +465 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +1066 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/autolink/AutoDetectedLinkSpan.kt +29 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/autolink/AutoLinkDetector.kt +188 -0
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/autolink/LinkRegexConfig.kt +9 -0
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/detection/DetectorPipeline.kt +40 -0
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/detection/TextDetector.kt +27 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/detection/WordResult.kt +7 -0
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/detection/WordsUtils.kt +65 -0
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +69 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownEditableFactory.kt +15 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +41 -0
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnCaretRectChangeEvent.kt +20 -0
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeMarkdownEvent.kt +22 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeMentionEvent.kt +24 -0
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeSelectionEvent.kt +24 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +50 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeTextEvent.kt +22 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +48 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnEndMentionEvent.kt +22 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputBlurEvent.kt +18 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputFocusEvent.kt +18 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnLinkDetectedEvent.kt +28 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnMathPressEvent.kt +36 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnRequestCaretRectResultEvent.kt +25 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnRequestMarkdownResultEvent.kt +24 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnStartMentionEvent.kt +22 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +192 -0
  68. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +117 -0
  69. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +117 -0
  70. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputRemend.kt +120 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +176 -0
  72. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +216 -0
  73. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputLayoutManager.kt +28 -0
  74. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +137 -0
  75. package/android/src/main/java/com/swmansion/enriched/markdown/input/math/MathChipController.kt +113 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/CaretRect.kt +17 -0
  77. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +10 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +28 -0
  79. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +7 -0
  80. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +47 -0
  81. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/StyleType.kt +10 -0
  82. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BoldStyleHandler.kt +35 -0
  83. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/ItalicStyleHandler.kt +35 -0
  84. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/LinkStyleHandler.kt +75 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/SpoilerStyleHandler.kt +36 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/StrikethroughStyleHandler.kt +24 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/StyleHandler.kt +18 -0
  88. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/StyleMergingConfig.kt +10 -0
  89. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnderlineStyleHandler.kt +24 -0
  90. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +181 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +43 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +68 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BaselineShiftRenderer.kt +44 -0
  94. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +152 -0
  95. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +87 -0
  96. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +104 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeRenderer.kt +36 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/DocumentRenderer.kt +16 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/EmphasisRenderer.kt +27 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +71 -0
  101. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HighlightRenderer.kt +25 -0
  102. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +61 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LineBreakRenderer.kt +16 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +29 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +89 -0
  106. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +127 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +74 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +161 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ParagraphRenderer.kt +75 -0
  110. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/Renderer.kt +113 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +134 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpoilerRenderer.kt +25 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrikethroughRenderer.kt +27 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrongRenderer.kt +27 -0
  115. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SubscriptRenderer.kt +11 -0
  116. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SuperscriptRenderer.kt +11 -0
  117. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/TextRenderer.kt +30 -0
  118. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ThematicBreakRenderer.kt +45 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/UnderlineRenderer.kt +27 -0
  120. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +127 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaselineShiftSpan.kt +27 -0
  122. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +152 -0
  123. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +180 -0
  124. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +196 -0
  125. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +32 -0
  126. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +42 -0
  127. package/android/src/main/java/com/swmansion/enriched/markdown/spans/FadeInSpan.kt +25 -0
  128. package/android/src/main/java/com/swmansion/enriched/markdown/spans/HeadingSpan.kt +38 -0
  129. package/android/src/main/java/com/swmansion/enriched/markdown/spans/HighlightSpan.kt +26 -0
  130. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +335 -0
  131. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LineHeightSpan.kt +27 -0
  132. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +66 -0
  133. package/android/src/main/java/com/swmansion/enriched/markdown/spans/MarginBottomSpan.kt +76 -0
  134. package/android/src/main/java/com/swmansion/enriched/markdown/spans/MathModels.kt +18 -0
  135. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +85 -0
  136. package/android/src/main/java/com/swmansion/enriched/markdown/spans/SpoilerSpan.kt +33 -0
  137. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrikethroughSpan.kt +12 -0
  138. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +39 -0
  139. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +134 -0
  140. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TextSpan.kt +26 -0
  141. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ThematicBreakSpan.kt +69 -0
  142. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +92 -0
  143. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/ParticleStrategy.kt +68 -0
  144. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SegmentKey.kt +13 -0
  145. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SolidStrategy.kt +95 -0
  146. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerAnimator.kt +89 -0
  147. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerCapable.kt +5 -0
  148. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerConstants.kt +3 -0
  149. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerDrawContext.kt +33 -0
  150. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerDrawUtils.kt +40 -0
  151. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerOverlay.kt +17 -0
  152. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerOverlayDrawer.kt +152 -0
  153. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerParticleDrawable.kt +237 -0
  154. package/android/src/main/java/com/swmansion/enriched/markdown/spoiler/SpoilerStrategy.kt +53 -0
  155. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BaseBlockStyle.kt +11 -0
  156. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +51 -0
  157. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +54 -0
  158. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeStyle.kt +26 -0
  159. package/android/src/main/java/com/swmansion/enriched/markdown/styles/EmphasisStyle.kt +21 -0
  160. package/android/src/main/java/com/swmansion/enriched/markdown/styles/HeadingStyle.kt +33 -0
  161. package/android/src/main/java/com/swmansion/enriched/markdown/styles/HighlightStyle.kt +19 -0
  162. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +23 -0
  163. package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineImageStyle.kt +17 -0
  164. package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +17 -0
  165. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +23 -0
  166. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +29 -0
  167. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +62 -0
  168. package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +29 -0
  169. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ParagraphStyle.kt +33 -0
  170. package/android/src/main/java/com/swmansion/enriched/markdown/styles/SpoilerStyle.kt +27 -0
  171. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrikethroughStyle.kt +17 -0
  172. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrongStyle.kt +21 -0
  173. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +364 -0
  174. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleParser.kt +92 -0
  175. package/android/src/main/java/com/swmansion/enriched/markdown/styles/SubscriptStyle.kt +16 -0
  176. package/android/src/main/java/com/swmansion/enriched/markdown/styles/SuperscriptStyle.kt +16 -0
  177. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +69 -0
  178. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TaskListStyle.kt +29 -0
  179. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TextAlignment.kt +32 -0
  180. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ThematicBreakStyle.kt +23 -0
  181. package/android/src/main/java/com/swmansion/enriched/markdown/styles/UnderlineStyle.kt +17 -0
  182. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/BreakStrategyUtils.kt +32 -0
  183. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +7 -0
  184. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +56 -0
  185. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +100 -0
  186. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MotionPreferences.kt +18 -0
  187. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +20 -0
  188. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +78 -0
  189. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentReconciler.kt +118 -0
  190. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +78 -0
  191. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +142 -0
  192. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/layout/RTLUtils.kt +6 -0
  193. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +115 -0
  194. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/AutoCapitalizeUtils.kt +27 -0
  195. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/BorderPropsApplicator.kt +77 -0
  196. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +184 -0
  197. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +53 -0
  198. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +156 -0
  199. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/TailFadeInAnimator.kt +84 -0
  200. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/HTMLGenerator.kt +1067 -0
  201. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +419 -0
  202. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/ParagraphUtils.kt +9 -0
  203. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/SpannableExtensions.kt +65 -0
  204. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +53 -0
  205. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +54 -0
  206. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +249 -0
  207. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +89 -0
  208. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/SpanFlags.kt +17 -0
  209. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkEvents.kt +43 -0
  210. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +187 -0
  211. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +205 -0
  212. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/TextSelectionColors.kt +48 -0
  213. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/TextViewSetup.kt +40 -0
  214. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockSegmentView.kt +10 -0
  215. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +214 -0
  216. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +501 -0
  217. package/android/src/main/jni/CMakeLists.txt +70 -0
  218. package/android/src/main/jni/EnrichedMarkdownTextSpec.cpp +21 -0
  219. package/android/src/main/jni/EnrichedMarkdownTextSpec.h +15 -0
  220. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +67 -0
  221. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerComponentDescriptor.h +26 -0
  222. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerMeasurementManager.cpp +45 -0
  223. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerMeasurementManager.h +21 -0
  224. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +20 -0
  225. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +34 -0
  226. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextComponentDescriptor.h +29 -0
  227. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextInputMeasurementManager.cpp +44 -0
  228. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextInputMeasurementManager.h +21 -0
  229. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextInputShadowNode.cpp +30 -0
  230. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextInputShadowNode.h +43 -0
  231. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextInputState.cpp +9 -0
  232. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextInputState.h +24 -0
  233. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.cpp +45 -0
  234. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.h +21 -0
  235. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +20 -0
  236. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +37 -0
  237. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +45 -0
  238. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +217 -0
  239. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +47 -0
  240. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +208 -0
  241. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlinePlaceholderSpan.kt +41 -0
  242. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +92 -0
  243. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +57 -0
  244. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +148 -0
  245. package/app.plugin.js +1 -0
  246. package/cpp/md4c/md4c.c +7235 -0
  247. package/cpp/md4c/md4c.h +475 -0
  248. package/cpp/parser/MD4CParser.cpp +539 -0
  249. package/cpp/parser/MD4CParser.hpp +32 -0
  250. package/cpp/parser/MarkdownASTNode.hpp +63 -0
  251. package/cpp/wasm/ASTSerializer.cpp +158 -0
  252. package/cpp/wasm/ASTSerializer.hpp +17 -0
  253. package/cpp/wasm/build.sh +58 -0
  254. package/cpp/wasm/md4c_wasm.cpp +43 -0
  255. package/ios/EnrichedMarkdown.h +20 -0
  256. package/ios/EnrichedMarkdown.mm +1121 -0
  257. package/ios/EnrichedMarkdownText.h +20 -0
  258. package/ios/EnrichedMarkdownText.mm +802 -0
  259. package/ios/attachments/ENRMImageAttachment.h +27 -0
  260. package/ios/attachments/ENRMImageAttachment.m +305 -0
  261. package/ios/attachments/ENRMMathInlineAttachment+macOS.m +60 -0
  262. package/ios/attachments/ENRMMathInlineAttachment.h +47 -0
  263. package/ios/attachments/ENRMMathInlineAttachment.m +142 -0
  264. package/ios/attachments/ENRMMathInlineAttachmentShared.h +17 -0
  265. package/ios/attachments/ThematicBreakAttachment.h +15 -0
  266. package/ios/attachments/ThematicBreakAttachment.m +33 -0
  267. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
  268. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
  269. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +318 -0
  270. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +259 -0
  271. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +375 -0
  272. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +5174 -0
  273. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +436 -0
  274. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
  275. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/ShadowNodes.h +23 -0
  276. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/States.cpp +16 -0
  277. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/States.h +20 -0
  278. package/ios/input/ENRMAutoLinkDetector.h +32 -0
  279. package/ios/input/ENRMAutoLinkDetector.mm +211 -0
  280. package/ios/input/ENRMDetectorPipeline.h +28 -0
  281. package/ios/input/ENRMDetectorPipeline.mm +53 -0
  282. package/ios/input/ENRMFormattingRange.h +19 -0
  283. package/ios/input/ENRMFormattingRange.mm +28 -0
  284. package/ios/input/ENRMFormattingStore.h +29 -0
  285. package/ios/input/ENRMFormattingStore.mm +278 -0
  286. package/ios/input/ENRMInputFormatter.h +84 -0
  287. package/ios/input/ENRMInputFormatter.mm +222 -0
  288. package/ios/input/ENRMInputLayoutManager.h +11 -0
  289. package/ios/input/ENRMInputLayoutManager.mm +5 -0
  290. package/ios/input/ENRMInputLinkPrompt.h +9 -0
  291. package/ios/input/ENRMInputLinkPrompt.mm +71 -0
  292. package/ios/input/ENRMInputMentionCandidate.h +21 -0
  293. package/ios/input/ENRMInputMentionCandidate.mm +18 -0
  294. package/ios/input/ENRMInputParser.h +27 -0
  295. package/ios/input/ENRMInputParser.mm +556 -0
  296. package/ios/input/ENRMInputRemend.h +9 -0
  297. package/ios/input/ENRMInputRemend.mm +136 -0
  298. package/ios/input/ENRMInputStyledRange.h +29 -0
  299. package/ios/input/ENRMInputStyledRange.mm +4 -0
  300. package/ios/input/ENRMInputTextView.h +13 -0
  301. package/ios/input/ENRMInputTextView.mm +175 -0
  302. package/ios/input/ENRMLinkRegexConfig.h +26 -0
  303. package/ios/input/ENRMLinkRegexConfig.mm +60 -0
  304. package/ios/input/ENRMMarkdownSerializer.h +19 -0
  305. package/ios/input/ENRMMarkdownSerializer.mm +283 -0
  306. package/ios/input/ENRMTextDetector.h +30 -0
  307. package/ios/input/ENRMWordsUtils.h +28 -0
  308. package/ios/input/ENRMWordsUtils.mm +88 -0
  309. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +157 -0
  310. package/ios/input/EnrichedMarkdownTextInput+Internal.h +30 -0
  311. package/ios/input/EnrichedMarkdownTextInput.h +20 -0
  312. package/ios/input/EnrichedMarkdownTextInput.mm +2008 -0
  313. package/ios/input/InputStylePropsUtils.h +261 -0
  314. package/ios/input/internals/EnrichedMarkdownTextInputComponentDescriptor.h +19 -0
  315. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.h +40 -0
  316. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +83 -0
  317. package/ios/input/internals/EnrichedMarkdownTextInputState.h +23 -0
  318. package/ios/input/styles/ENRMBoldStyleHandler.h +10 -0
  319. package/ios/input/styles/ENRMBoldStyleHandler.mm +29 -0
  320. package/ios/input/styles/ENRMItalicStyleHandler.h +10 -0
  321. package/ios/input/styles/ENRMItalicStyleHandler.mm +29 -0
  322. package/ios/input/styles/ENRMLinkStyleHandler.h +10 -0
  323. package/ios/input/styles/ENRMLinkStyleHandler.mm +52 -0
  324. package/ios/input/styles/ENRMSpoilerStyleHandler.h +10 -0
  325. package/ios/input/styles/ENRMSpoilerStyleHandler.mm +33 -0
  326. package/ios/input/styles/ENRMStrikethroughStyleHandler.h +10 -0
  327. package/ios/input/styles/ENRMStrikethroughStyleHandler.mm +28 -0
  328. package/ios/input/styles/ENRMStyleHandler.h +26 -0
  329. package/ios/input/styles/ENRMStyleMergingConfig.h +26 -0
  330. package/ios/input/styles/ENRMStyleMergingConfig.mm +21 -0
  331. package/ios/input/styles/ENRMUnderlineStyleHandler.h +10 -0
  332. package/ios/input/styles/ENRMUnderlineStyleHandler.mm +28 -0
  333. package/ios/internals/EnrichedMarkdownComponentDescriptor.h +18 -0
  334. package/ios/internals/EnrichedMarkdownShadowNode.h +43 -0
  335. package/ios/internals/EnrichedMarkdownShadowNode.mm +73 -0
  336. package/ios/internals/EnrichedMarkdownState.h +23 -0
  337. package/ios/internals/EnrichedMarkdownTextComponentDescriptor.h +19 -0
  338. package/ios/internals/EnrichedMarkdownTextShadowNode.h +45 -0
  339. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +74 -0
  340. package/ios/internals/EnrichedMarkdownTextState.h +24 -0
  341. package/ios/internals/MeasurementCache.h +223 -0
  342. package/ios/internals/ShadowMeasurementUtils.h +135 -0
  343. package/ios/math/ENRMRaTeXBridge.swift +58 -0
  344. package/ios/parser/ENRMMarkdownParser.h +21 -0
  345. package/ios/parser/ENRMMarkdownParser.mm +50 -0
  346. package/ios/parser/MarkdownASTNode.h +47 -0
  347. package/ios/parser/MarkdownASTNode.m +32 -0
  348. package/ios/parser/MarkdownParserBridge.mm +161 -0
  349. package/ios/renderer/AttributedRenderer.h +11 -0
  350. package/ios/renderer/AttributedRenderer.m +153 -0
  351. package/ios/renderer/BaseRenderer.h +18 -0
  352. package/ios/renderer/BaseRenderer.m +16 -0
  353. package/ios/renderer/BaselineShiftTextAttributes.h +6 -0
  354. package/ios/renderer/BaselineShiftTextAttributes.m +22 -0
  355. package/ios/renderer/BlockquoteRenderer.h +6 -0
  356. package/ios/renderer/BlockquoteRenderer.m +148 -0
  357. package/ios/renderer/CodeBlockRenderer.h +9 -0
  358. package/ios/renderer/CodeBlockRenderer.m +90 -0
  359. package/ios/renderer/CodeRenderer.h +9 -0
  360. package/ios/renderer/CodeRenderer.m +64 -0
  361. package/ios/renderer/ENRMImageRenderer.h +9 -0
  362. package/ios/renderer/ENRMImageRenderer.m +65 -0
  363. package/ios/renderer/ENRMMathInlineRenderer.h +9 -0
  364. package/ios/renderer/ENRMMathInlineRenderer.m +56 -0
  365. package/ios/renderer/ENRMSpoilerRenderer.h +5 -0
  366. package/ios/renderer/ENRMSpoilerRenderer.m +32 -0
  367. package/ios/renderer/EmphasisRenderer.h +5 -0
  368. package/ios/renderer/EmphasisRenderer.m +98 -0
  369. package/ios/renderer/HeadingRenderer.h +6 -0
  370. package/ios/renderer/HeadingRenderer.m +94 -0
  371. package/ios/renderer/HighlightRenderer.h +7 -0
  372. package/ios/renderer/HighlightRenderer.m +31 -0
  373. package/ios/renderer/LinkRenderer.h +6 -0
  374. package/ios/renderer/LinkRenderer.m +82 -0
  375. package/ios/renderer/ListItemRenderer.h +12 -0
  376. package/ios/renderer/ListItemRenderer.m +175 -0
  377. package/ios/renderer/ListRenderer.h +13 -0
  378. package/ios/renderer/ListRenderer.m +70 -0
  379. package/ios/renderer/NodeRenderer.h +8 -0
  380. package/ios/renderer/ParagraphRenderer.h +6 -0
  381. package/ios/renderer/ParagraphRenderer.m +70 -0
  382. package/ios/renderer/RenderContext.h +118 -0
  383. package/ios/renderer/RenderContext.m +337 -0
  384. package/ios/renderer/RendererFactory.h +12 -0
  385. package/ios/renderer/RendererFactory.m +147 -0
  386. package/ios/renderer/StrikethroughRenderer.h +5 -0
  387. package/ios/renderer/StrikethroughRenderer.m +28 -0
  388. package/ios/renderer/StrongRenderer.h +5 -0
  389. package/ios/renderer/StrongRenderer.m +86 -0
  390. package/ios/renderer/SubscriptRenderer.h +5 -0
  391. package/ios/renderer/SubscriptRenderer.m +22 -0
  392. package/ios/renderer/SuperscriptRenderer.h +5 -0
  393. package/ios/renderer/SuperscriptRenderer.m +22 -0
  394. package/ios/renderer/TextRenderer.h +6 -0
  395. package/ios/renderer/TextRenderer.m +16 -0
  396. package/ios/renderer/ThematicBreakRenderer.h +4 -0
  397. package/ios/renderer/ThematicBreakRenderer.m +40 -0
  398. package/ios/renderer/UnderlineRenderer.h +4 -0
  399. package/ios/renderer/UnderlineRenderer.m +27 -0
  400. package/ios/styles/ENRMFontSlot.h +12 -0
  401. package/ios/styles/ENRMFontSlot.m +24 -0
  402. package/ios/styles/StyleConfig.h +407 -0
  403. package/ios/styles/StyleConfig.mm +2515 -0
  404. package/ios/utils/AccessibilityInfo.h +35 -0
  405. package/ios/utils/AccessibilityInfo.m +24 -0
  406. package/ios/utils/BlockquoteBorder.h +20 -0
  407. package/ios/utils/BlockquoteBorder.m +97 -0
  408. package/ios/utils/CodeBackground.h +19 -0
  409. package/ios/utils/CodeBackground.m +197 -0
  410. package/ios/utils/CodeBlockBackground.h +17 -0
  411. package/ios/utils/CodeBlockBackground.m +89 -0
  412. package/ios/utils/ContextMenuUtils.h +76 -0
  413. package/ios/utils/ContextMenuUtils.mm +73 -0
  414. package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -0
  415. package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -0
  416. package/ios/utils/ENRMFeatureFlags.h +12 -0
  417. package/ios/utils/ENRMImageDownloader.h +16 -0
  418. package/ios/utils/ENRMImageDownloader.m +108 -0
  419. package/ios/utils/ENRMMenuAction.h +27 -0
  420. package/ios/utils/ENRMMenuAction.m +33 -0
  421. package/ios/utils/ENRMParticleOverlayView.h +12 -0
  422. package/ios/utils/ENRMParticleOverlayView.m +159 -0
  423. package/ios/utils/ENRMSolidOverlayView.h +12 -0
  424. package/ios/utils/ENRMSolidOverlayView.m +25 -0
  425. package/ios/utils/ENRMSpoilerCapable.h +15 -0
  426. package/ios/utils/ENRMSpoilerOverlayManager.h +21 -0
  427. package/ios/utils/ENRMSpoilerOverlayManager.m +181 -0
  428. package/ios/utils/ENRMSpoilerOverlayView.h +49 -0
  429. package/ios/utils/ENRMSpoilerOverlayView.m +144 -0
  430. package/ios/utils/ENRMSpoilerTapUtils.h +25 -0
  431. package/ios/utils/ENRMSpoilerTapUtils.m +68 -0
  432. package/ios/utils/ENRMTailFadeInAnimator.h +16 -0
  433. package/ios/utils/ENRMTailFadeInAnimator.m +161 -0
  434. package/ios/utils/ENRMTextHitTest.h +23 -0
  435. package/ios/utils/ENRMTextHitTest.m +20 -0
  436. package/ios/utils/ENRMTextInteractionUtils.h +20 -0
  437. package/ios/utils/ENRMTextInteractionUtils.m +15 -0
  438. package/ios/utils/ENRMTextRenderer.h +30 -0
  439. package/ios/utils/ENRMTextRenderer.m +38 -0
  440. package/ios/utils/ENRMTextViewSetup.h +78 -0
  441. package/ios/utils/ENRMUIKit.h +418 -0
  442. package/ios/utils/EditMenuUtils+macOS.m +60 -0
  443. package/ios/utils/EditMenuUtils.h +35 -0
  444. package/ios/utils/EditMenuUtils.m +119 -0
  445. package/ios/utils/FontScaleObserver.h +10 -0
  446. package/ios/utils/FontScaleObserver.m +55 -0
  447. package/ios/utils/FontUtils.h +30 -0
  448. package/ios/utils/FontUtils.m +47 -0
  449. package/ios/utils/HTMLGenerator.h +25 -0
  450. package/ios/utils/HTMLGenerator.m +1019 -0
  451. package/ios/utils/HeightUpdateUtils.h +25 -0
  452. package/ios/utils/LastElementUtils.h +53 -0
  453. package/ios/utils/LinkTapUtils.h +24 -0
  454. package/ios/utils/LinkTapUtils.m +32 -0
  455. package/ios/utils/ListMarkerDrawer.h +15 -0
  456. package/ios/utils/ListMarkerDrawer.m +212 -0
  457. package/ios/utils/MarkdownASTSerializer.h +24 -0
  458. package/ios/utils/MarkdownASTSerializer.m +114 -0
  459. package/ios/utils/MarkdownAccessibilityElementBuilder.h +41 -0
  460. package/ios/utils/MarkdownAccessibilityElementBuilder.m +450 -0
  461. package/ios/utils/MarkdownExtractor.h +17 -0
  462. package/ios/utils/MarkdownExtractor.m +355 -0
  463. package/ios/utils/ParagraphStyleUtils.h +53 -0
  464. package/ios/utils/ParagraphStyleUtils.m +349 -0
  465. package/ios/utils/PasteboardUtils.h +48 -0
  466. package/ios/utils/PasteboardUtils.m +162 -0
  467. package/ios/utils/RTFExportUtils.h +24 -0
  468. package/ios/utils/RTFExportUtils.m +297 -0
  469. package/ios/utils/RenderedMarkdownSegment.h +49 -0
  470. package/ios/utils/RenderedMarkdownSegment.m +130 -0
  471. package/ios/utils/RuntimeKeys.h +38 -0
  472. package/ios/utils/RuntimeKeys.m +11 -0
  473. package/ios/utils/SegmentReconciler.h +32 -0
  474. package/ios/utils/SegmentReconciler.m +118 -0
  475. package/ios/utils/SegmentRenderer.h +24 -0
  476. package/ios/utils/SegmentRenderer.m +88 -0
  477. package/ios/utils/SegmentViewRegistry.h +36 -0
  478. package/ios/utils/SegmentViewRegistry.m +67 -0
  479. package/ios/utils/SelectionColorUtils.h +14 -0
  480. package/ios/utils/StreamingMarkdownFilter.h +22 -0
  481. package/ios/utils/StreamingMarkdownFilter.m +165 -0
  482. package/ios/utils/StylePropsUtils.h +1146 -0
  483. package/ios/utils/TaskListTapUtils.h +43 -0
  484. package/ios/utils/TaskListTapUtils.m +227 -0
  485. package/ios/utils/TextViewLayoutManager.h +14 -0
  486. package/ios/utils/TextViewLayoutManager.mm +113 -0
  487. package/ios/views/ENRMContextMenuTextView+macOS.h +17 -0
  488. package/ios/views/ENRMContextMenuTextView+macOS.m +97 -0
  489. package/ios/views/ENRMMathContainerView.h +20 -0
  490. package/ios/views/ENRMMathContainerView.m +227 -0
  491. package/ios/views/ENRMTableGridView.h +36 -0
  492. package/ios/views/ENRMTableGridView.m +98 -0
  493. package/ios/views/EnrichedMarkdownInternalText.h +42 -0
  494. package/ios/views/EnrichedMarkdownInternalText.m +161 -0
  495. package/ios/views/TableContainerView.h +39 -0
  496. package/ios/views/TableContainerView.m +686 -0
  497. package/lib/module/EnrichedMarkdownNativeComponent.ts +429 -0
  498. package/lib/module/EnrichedMarkdownTextInput.js +310 -0
  499. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -0
  500. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +364 -0
  501. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +428 -0
  502. package/lib/module/index.js +5 -0
  503. package/lib/module/index.js.map +1 -0
  504. package/lib/module/index.web.js +4 -0
  505. package/lib/module/index.web.js.map +1 -0
  506. package/lib/module/linkVariantUtils.js +28 -0
  507. package/lib/module/linkVariantUtils.js.map +1 -0
  508. package/lib/module/native/EnrichedMarkdownText.js +158 -0
  509. package/lib/module/native/EnrichedMarkdownText.js.map +1 -0
  510. package/lib/module/normalizeMarkdownStyle.js +337 -0
  511. package/lib/module/normalizeMarkdownStyle.js.map +1 -0
  512. package/lib/module/normalizeMarkdownStyle.web.js +264 -0
  513. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -0
  514. package/lib/module/normalizeMarkdownTextInputStyle.js +146 -0
  515. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -0
  516. package/lib/module/package.json +1 -0
  517. package/lib/module/plugin/withAndroidMath.js +20 -0
  518. package/lib/module/plugin/withAndroidMath.js.map +1 -0
  519. package/lib/module/plugin/withIosMath.js +23 -0
  520. package/lib/module/plugin/withIosMath.js.map +1 -0
  521. package/lib/module/plugin/withReactNativeEnrichedMarkdown.js +16 -0
  522. package/lib/module/plugin/withReactNativeEnrichedMarkdown.js.map +1 -0
  523. package/lib/module/styleUtils.js +64 -0
  524. package/lib/module/styleUtils.js.map +1 -0
  525. package/lib/module/types/MarkdownStyle.js +2 -0
  526. package/lib/module/types/MarkdownStyle.js.map +1 -0
  527. package/lib/module/types/MarkdownStyleInternal.js +2 -0
  528. package/lib/module/types/MarkdownStyleInternal.js.map +1 -0
  529. package/lib/module/types/MarkdownTextProps.js +4 -0
  530. package/lib/module/types/MarkdownTextProps.js.map +1 -0
  531. package/lib/module/types/MarkdownTextProps.web.js +4 -0
  532. package/lib/module/types/MarkdownTextProps.web.js.map +1 -0
  533. package/lib/module/types/events.js +2 -0
  534. package/lib/module/types/events.js.map +1 -0
  535. package/lib/module/utils/regexParser.js +43 -0
  536. package/lib/module/utils/regexParser.js.map +1 -0
  537. package/lib/module/web/EnrichedMarkdownText.js +120 -0
  538. package/lib/module/web/EnrichedMarkdownText.js.map +1 -0
  539. package/lib/module/web/globalStyles.js +10 -0
  540. package/lib/module/web/globalStyles.js.map +1 -0
  541. package/lib/module/web/injectStyle.js +20 -0
  542. package/lib/module/web/injectStyle.js.map +1 -0
  543. package/lib/module/web/katex.js +22 -0
  544. package/lib/module/web/katex.js.map +1 -0
  545. package/lib/module/web/parseMarkdown.js +35 -0
  546. package/lib/module/web/parseMarkdown.js.map +1 -0
  547. package/lib/module/web/renderers/BlockRenderers.js +115 -0
  548. package/lib/module/web/renderers/BlockRenderers.js.map +1 -0
  549. package/lib/module/web/renderers/InlineRenderers.js +160 -0
  550. package/lib/module/web/renderers/InlineRenderers.js.map +1 -0
  551. package/lib/module/web/renderers/KaTeXRenderer.js +43 -0
  552. package/lib/module/web/renderers/KaTeXRenderer.js.map +1 -0
  553. package/lib/module/web/renderers/ListRenderers.js +92 -0
  554. package/lib/module/web/renderers/ListRenderers.js.map +1 -0
  555. package/lib/module/web/renderers/TableRenderers.js +77 -0
  556. package/lib/module/web/renderers/TableRenderers.js.map +1 -0
  557. package/lib/module/web/renderers/index.js +49 -0
  558. package/lib/module/web/renderers/index.js.map +1 -0
  559. package/lib/module/web/styles.js +454 -0
  560. package/lib/module/web/styles.js.map +1 -0
  561. package/lib/module/web/types.js +4 -0
  562. package/lib/module/web/types.js.map +1 -0
  563. package/lib/module/web/utils.js +56 -0
  564. package/lib/module/web/utils.js.map +1 -0
  565. package/lib/module/web/wasm/md4c.d.js +4 -0
  566. package/lib/module/web/wasm/md4c.d.js.map +1 -0
  567. package/lib/module/web/wasm/md4c.js +0 -0
  568. package/lib/module/web/wasm/md4c.js.map +1 -0
  569. package/lib/typescript/package.json +1 -0
  570. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +384 -0
  571. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -0
  572. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +173 -0
  573. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -0
  574. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +285 -0
  575. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -0
  576. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +384 -0
  577. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -0
  578. package/lib/typescript/src/index.d.ts +6 -0
  579. package/lib/typescript/src/index.d.ts.map +1 -0
  580. package/lib/typescript/src/index.web.d.ts +5 -0
  581. package/lib/typescript/src/index.web.d.ts.map +1 -0
  582. package/lib/typescript/src/linkVariantUtils.d.ts +5 -0
  583. package/lib/typescript/src/linkVariantUtils.d.ts.map +1 -0
  584. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +9 -0
  585. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -0
  586. package/lib/typescript/src/normalizeMarkdownStyle.d.ts +4 -0
  587. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -0
  588. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts +4 -0
  589. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -0
  590. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +48 -0
  591. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -0
  592. package/lib/typescript/src/plugin/withAndroidMath.d.ts +5 -0
  593. package/lib/typescript/src/plugin/withAndroidMath.d.ts.map +1 -0
  594. package/lib/typescript/src/plugin/withIosMath.d.ts +5 -0
  595. package/lib/typescript/src/plugin/withIosMath.d.ts.map +1 -0
  596. package/lib/typescript/src/plugin/withReactNativeEnrichedMarkdown.d.ts +6 -0
  597. package/lib/typescript/src/plugin/withReactNativeEnrichedMarkdown.d.ts.map +1 -0
  598. package/lib/typescript/src/styleUtils.d.ts +6 -0
  599. package/lib/typescript/src/styleUtils.d.ts.map +1 -0
  600. package/lib/typescript/src/types/MarkdownStyle.d.ts +300 -0
  601. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -0
  602. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +178 -0
  603. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -0
  604. package/lib/typescript/src/types/MarkdownTextProps.d.ts +249 -0
  605. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -0
  606. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +83 -0
  607. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -0
  608. package/lib/typescript/src/types/events.d.ts +29 -0
  609. package/lib/typescript/src/types/events.d.ts.map +1 -0
  610. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  611. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  612. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +4 -0
  613. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -0
  614. package/lib/typescript/src/web/globalStyles.d.ts +3 -0
  615. package/lib/typescript/src/web/globalStyles.d.ts.map +1 -0
  616. package/lib/typescript/src/web/injectStyle.d.ts +9 -0
  617. package/lib/typescript/src/web/injectStyle.d.ts.map +1 -0
  618. package/lib/typescript/src/web/katex.d.ts +11 -0
  619. package/lib/typescript/src/web/katex.d.ts.map +1 -0
  620. package/lib/typescript/src/web/parseMarkdown.d.ts +4 -0
  621. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -0
  622. package/lib/typescript/src/web/renderers/BlockRenderers.d.ts +3 -0
  623. package/lib/typescript/src/web/renderers/BlockRenderers.d.ts.map +1 -0
  624. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts +3 -0
  625. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -0
  626. package/lib/typescript/src/web/renderers/KaTeXRenderer.d.ts +11 -0
  627. package/lib/typescript/src/web/renderers/KaTeXRenderer.d.ts.map +1 -0
  628. package/lib/typescript/src/web/renderers/ListRenderers.d.ts +3 -0
  629. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -0
  630. package/lib/typescript/src/web/renderers/TableRenderers.d.ts +3 -0
  631. package/lib/typescript/src/web/renderers/TableRenderers.d.ts.map +1 -0
  632. package/lib/typescript/src/web/renderers/index.d.ts +14 -0
  633. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -0
  634. package/lib/typescript/src/web/styles.d.ts +49 -0
  635. package/lib/typescript/src/web/styles.d.ts.map +1 -0
  636. package/lib/typescript/src/web/types.d.ts +51 -0
  637. package/lib/typescript/src/web/types.d.ts.map +1 -0
  638. package/lib/typescript/src/web/utils.d.ts +21 -0
  639. package/lib/typescript/src/web/utils.d.ts.map +1 -0
  640. package/package.json +125 -0
  641. package/react-native.config.js +17 -0
  642. package/src/EnrichedMarkdownNativeComponent.ts +429 -0
  643. package/src/EnrichedMarkdownTextInput.tsx +547 -0
  644. package/src/EnrichedMarkdownTextInputNativeComponent.ts +364 -0
  645. package/src/EnrichedMarkdownTextNativeComponent.ts +428 -0
  646. package/src/index.tsx +28 -0
  647. package/src/index.web.tsx +8 -0
  648. package/src/linkVariantUtils.ts +42 -0
  649. package/src/native/EnrichedMarkdownText.tsx +187 -0
  650. package/src/normalizeMarkdownStyle.ts +310 -0
  651. package/src/normalizeMarkdownStyle.web.ts +281 -0
  652. package/src/normalizeMarkdownTextInputStyle.ts +242 -0
  653. package/src/plugin/withAndroidMath.ts +24 -0
  654. package/src/plugin/withIosMath.ts +35 -0
  655. package/src/plugin/withReactNativeEnrichedMarkdown.ts +17 -0
  656. package/src/styleUtils.ts +98 -0
  657. package/src/types/MarkdownStyle.ts +326 -0
  658. package/src/types/MarkdownStyleInternal.ts +208 -0
  659. package/src/types/MarkdownTextProps.ts +253 -0
  660. package/src/types/MarkdownTextProps.web.ts +90 -0
  661. package/src/types/events.ts +32 -0
  662. package/src/utils/regexParser.ts +54 -0
  663. package/src/web/EnrichedMarkdownText.tsx +154 -0
  664. package/src/web/globalStyles.ts +15 -0
  665. package/src/web/injectStyle.ts +17 -0
  666. package/src/web/katex.ts +31 -0
  667. package/src/web/parseMarkdown.ts +78 -0
  668. package/src/web/renderers/BlockRenderers.tsx +90 -0
  669. package/src/web/renderers/InlineRenderers.tsx +121 -0
  670. package/src/web/renderers/KaTeXRenderer.tsx +49 -0
  671. package/src/web/renderers/ListRenderers.tsx +110 -0
  672. package/src/web/renderers/TableRenderers.tsx +61 -0
  673. package/src/web/renderers/index.tsx +75 -0
  674. package/src/web/styles.ts +549 -0
  675. package/src/web/types.ts +92 -0
  676. package/src/web/utils.ts +52 -0
  677. package/src/web/wasm/md4c.d.ts +21 -0
  678. package/src/web/wasm/md4c.js +0 -0
@@ -0,0 +1,1019 @@
1
+ #import "HTMLGenerator.h"
2
+ #import "BlockquoteBorder.h"
3
+ #import "CodeBackground.h"
4
+ #import "ENRMFeatureFlags.h"
5
+ #import "ENRMImageAttachment.h"
6
+ #import "HighlightRenderer.h"
7
+ #if ENRICHED_MARKDOWN_MATH
8
+ #import "ENRMMathInlineAttachment.h"
9
+ #endif
10
+ #import "LastElementUtils.h"
11
+ #import "ListItemRenderer.h"
12
+ #import "ParagraphStyleUtils.h"
13
+ #import "RenderContext.h"
14
+ #import "RuntimeKeys.h"
15
+ #import "StyleConfig.h"
16
+ #import "ThematicBreakAttachment.h"
17
+
18
+ static NSString *const kObjectReplacementChar = @"\uFFFC";
19
+ static const CGFloat kBlockquoteVerticalPadding = 8.0;
20
+ static const CGFloat kBlockquoteParagraphSpacing = 4.0;
21
+ static const CGFloat kNestedBlockquoteTopMargin = 8.0;
22
+ static const CGFloat kDefaultListIndent = 24.0;
23
+ static const CGFloat kCodePadding = 2.0;
24
+ static const CGFloat kCodeBorderRadius = 4.0;
25
+
26
+ #pragma mark - Paragraph Types
27
+
28
+ typedef NS_ENUM(NSInteger, ParagraphType) {
29
+ ParagraphTypeNormal,
30
+ ParagraphTypeHeading1,
31
+ ParagraphTypeHeading2,
32
+ ParagraphTypeHeading3,
33
+ ParagraphTypeHeading4,
34
+ ParagraphTypeHeading5,
35
+ ParagraphTypeHeading6,
36
+ ParagraphTypeCodeBlock,
37
+ ParagraphTypeBlockquote,
38
+ ParagraphTypeListItemUnordered,
39
+ ParagraphTypeListItemOrdered,
40
+ ParagraphTypeTaskList
41
+ };
42
+
43
+ typedef struct {
44
+ NSRange range;
45
+ ParagraphType type;
46
+ NSInteger depth;
47
+ NSInteger listNumber;
48
+ BOOL isTaskChecked;
49
+ } ParagraphData;
50
+
51
+ #pragma mark - Cached Style Config
52
+
53
+ /// Pre-fetched style values to avoid repeated StyleConfig method calls
54
+ @interface CachedStyles : NSObject
55
+ @property (nonatomic, copy) NSString *paragraphColor;
56
+ @property (nonatomic, copy) NSString *strongColor;
57
+ @property (nonatomic, copy) NSString *emphasisColor;
58
+ @property (nonatomic, copy) NSString *codeColor;
59
+ @property (nonatomic, copy) NSString *codeBackgroundColor;
60
+ @property (nonatomic, copy) NSString *codeBlockColor;
61
+ @property (nonatomic, copy) NSString *codeBlockBackgroundColor;
62
+ @property (nonatomic, copy) NSString *blockquoteColor;
63
+ @property (nonatomic, copy) NSString *blockquoteBackgroundColor;
64
+ @property (nonatomic, copy) NSString *blockquoteBorderColor;
65
+ @property (nonatomic, copy) NSString *listStyleColor;
66
+ @property (nonatomic, copy) NSString *taskCheckedColor;
67
+ @property (nonatomic, copy) NSString *taskBorderColor;
68
+ @property (nonatomic, copy) NSString *taskCheckmarkColor;
69
+ @property (nonatomic) CGFloat taskCheckboxSize;
70
+ @property (nonatomic) CGFloat taskCheckboxBorderRadius;
71
+ @property (nonatomic, copy) NSString *h1Color;
72
+ @property (nonatomic, copy) NSString *h2Color;
73
+ @property (nonatomic, copy) NSString *h3Color;
74
+ @property (nonatomic, copy) NSString *h4Color;
75
+ @property (nonatomic, copy) NSString *h5Color;
76
+ @property (nonatomic, copy) NSString *h6Color;
77
+ @property (nonatomic) CGFloat paragraphFontSize;
78
+ @property (nonatomic) CGFloat paragraphMarginBottom;
79
+ @property (nonatomic) CGFloat codeBlockFontSize;
80
+ @property (nonatomic) CGFloat codeBlockPadding;
81
+ @property (nonatomic) CGFloat codeBlockBorderRadius;
82
+ @property (nonatomic) CGFloat codeBlockMarginBottom;
83
+ @property (nonatomic) CGFloat blockquoteFontSize;
84
+ @property (nonatomic) CGFloat blockquoteBorderWidth;
85
+ @property (nonatomic) CGFloat blockquoteMarginBottom;
86
+ @property (nonatomic) CGFloat blockquoteGapWidth;
87
+ @property (nonatomic) CGFloat listStyleFontSize;
88
+ @property (nonatomic) CGFloat listStyleMarginBottom;
89
+ @property (nonatomic) CGFloat listStyleMarginLeft;
90
+ @property (nonatomic) CGFloat imageMarginBottom;
91
+ @property (nonatomic) CGFloat imageBorderRadius;
92
+ @property (nonatomic) CGFloat h1FontSize;
93
+ @property (nonatomic) CGFloat h2FontSize;
94
+ @property (nonatomic) CGFloat h3FontSize;
95
+ @property (nonatomic) CGFloat h4FontSize;
96
+ @property (nonatomic) CGFloat h5FontSize;
97
+ @property (nonatomic) CGFloat h6FontSize;
98
+ @property (nonatomic) CGFloat h1MarginBottom;
99
+ @property (nonatomic) CGFloat h2MarginBottom;
100
+ @property (nonatomic) CGFloat h3MarginBottom;
101
+ @property (nonatomic) CGFloat h4MarginBottom;
102
+ @property (nonatomic) CGFloat h5MarginBottom;
103
+ @property (nonatomic) CGFloat h6MarginBottom;
104
+ @property (nonatomic, copy) NSString *h1FontWeight;
105
+ @property (nonatomic, copy) NSString *h2FontWeight;
106
+ @property (nonatomic, copy) NSString *h3FontWeight;
107
+ @property (nonatomic, copy) NSString *h4FontWeight;
108
+ @property (nonatomic, copy) NSString *h5FontWeight;
109
+ @property (nonatomic, copy) NSString *h6FontWeight;
110
+ @property (nonatomic, copy) NSString *linkFontFamily;
111
+ @property (nonatomic, copy) NSString *linkColor;
112
+ @property (nonatomic) BOOL linkUnderline;
113
+ @property (nonatomic, copy) NSString *thematicBreakColor;
114
+ @property (nonatomic) CGFloat thematicBreakHeight;
115
+ @property (nonatomic) CGFloat thematicBreakMarginTop;
116
+ @property (nonatomic) CGFloat thematicBreakMarginBottom;
117
+ @property (nonatomic, copy) NSString *strikethroughColor;
118
+ @property (nonatomic, copy) NSString *underlineColor;
119
+ @property (nonatomic, copy) NSString *highlightColor;
120
+ @property (nonatomic, copy) NSString *highlightBackgroundColor;
121
+ @end
122
+
123
+ @implementation CachedStyles
124
+ @end
125
+
126
+ #pragma mark - Generator State
127
+
128
+ @interface GeneratorState : NSObject
129
+ @property (nonatomic) NSInteger currentListDepth;
130
+ @property (nonatomic) NSInteger currentBlockquoteDepth;
131
+ @property (nonatomic) BOOL inBlockquote;
132
+ @property (nonatomic) BOOL inCodeBlock;
133
+ @property (nonatomic) BOOL previousWasCodeBlock;
134
+ @property (nonatomic) BOOL previousWasBlockquote;
135
+ @property (nonatomic, strong) NSMutableArray<NSNumber *> *openListTypes;
136
+ @end
137
+
138
+ @implementation GeneratorState
139
+ - (instancetype)init
140
+ {
141
+ self = [super init];
142
+ if (self) {
143
+ _currentListDepth = -1;
144
+ _currentBlockquoteDepth = -1;
145
+ _openListTypes = [NSMutableArray array];
146
+ }
147
+ return self;
148
+ }
149
+ @end
150
+
151
+ #pragma mark - Color Conversion
152
+
153
+ static NSString *colorToCSS(RCTUIColor *color)
154
+ {
155
+ if (!color)
156
+ return @"inherit";
157
+
158
+ CGFloat r = 0, g = 0, b = 0, a = 1;
159
+ [color getRed:&r green:&g blue:&b alpha:&a];
160
+
161
+ if (a < 1.0) {
162
+ return [NSString stringWithFormat:@"rgba(%.0f, %.0f, %.0f, %.2f)", r * 255, g * 255, b * 255, a];
163
+ }
164
+ return [NSString stringWithFormat:@"#%02X%02X%02X", (int)(r * 255), (int)(g * 255), (int)(b * 255)];
165
+ }
166
+
167
+ #pragma mark - HTML Escaping
168
+
169
+ static void appendEscapedHTML(NSMutableString *output, NSString *text)
170
+ {
171
+ NSUInteger length = text.length;
172
+ if (length == 0)
173
+ return;
174
+
175
+ for (NSUInteger i = 0; i < length; i++) {
176
+ unichar c = [text characterAtIndex:i];
177
+ switch (c) {
178
+ case '&':
179
+ [output appendString:@"&amp;"];
180
+ break;
181
+ case '<':
182
+ [output appendString:@"&lt;"];
183
+ break;
184
+ case '>':
185
+ [output appendString:@"&gt;"];
186
+ break;
187
+ case '"':
188
+ [output appendString:@"&quot;"];
189
+ break;
190
+ case '\'':
191
+ [output appendString:@"&#39;"];
192
+ break;
193
+ default:
194
+ [output appendFormat:@"%C", c];
195
+ break;
196
+ }
197
+ }
198
+ }
199
+
200
+ static NSString *escapeHTML(NSString *text)
201
+ {
202
+ // Fast path: skip if no special chars
203
+ static NSCharacterSet *escapeChars = nil;
204
+ static dispatch_once_t onceToken;
205
+ dispatch_once(&onceToken, ^{ escapeChars = [NSCharacterSet characterSetWithCharactersInString:@"&<>\"'"]; });
206
+
207
+ if ([text rangeOfCharacterFromSet:escapeChars].location == NSNotFound) {
208
+ return text;
209
+ }
210
+
211
+ NSMutableString *escaped = [NSMutableString stringWithCapacity:text.length + 16];
212
+ appendEscapedHTML(escaped, text);
213
+ return escaped;
214
+ }
215
+
216
+ #pragma mark - Font Weight Conversion
217
+
218
+ static NSString *fontWeightToCSS(NSString *fontWeight)
219
+ {
220
+ if (!fontWeight || fontWeight.length == 0)
221
+ return @"normal";
222
+
223
+ if ([fontWeight integerValue] > 0)
224
+ return fontWeight;
225
+
226
+ static NSDictionary *weightMap = nil;
227
+ static dispatch_once_t onceToken;
228
+ dispatch_once(&onceToken, ^{ weightMap = @{@"bold" : @"700", @"semibold" : @"600", @"medium" : @"500"}; });
229
+
230
+ NSString *mapped = weightMap[fontWeight.lowercaseString];
231
+ return mapped ?: @"normal";
232
+ }
233
+
234
+ #pragma mark - Style Caching
235
+
236
+ static CachedStyles *cacheStyles(StyleConfig *styleConfig)
237
+ {
238
+ CachedStyles *cache = [[CachedStyles alloc] init];
239
+
240
+ cache.paragraphColor = colorToCSS([styleConfig paragraphColor]);
241
+ cache.strongColor = colorToCSS([styleConfig strongColor]);
242
+ cache.emphasisColor = colorToCSS([styleConfig emphasisColor]);
243
+ cache.codeColor = colorToCSS([styleConfig codeColor]);
244
+ cache.codeBackgroundColor = colorToCSS([styleConfig codeBackgroundColor]);
245
+ cache.codeBlockColor = colorToCSS([styleConfig codeBlockColor]);
246
+ cache.codeBlockBackgroundColor = colorToCSS([styleConfig codeBlockBackgroundColor]);
247
+ cache.blockquoteColor = colorToCSS([styleConfig blockquoteColor]);
248
+ cache.blockquoteBackgroundColor = colorToCSS([styleConfig blockquoteBackgroundColor]);
249
+ cache.blockquoteBorderColor = colorToCSS([styleConfig blockquoteBorderColor]);
250
+ cache.listStyleColor = colorToCSS([styleConfig listStyleColor]);
251
+ cache.taskCheckedColor = colorToCSS([styleConfig taskListCheckedColor]);
252
+ cache.taskBorderColor = colorToCSS([styleConfig taskListBorderColor]);
253
+ cache.taskCheckmarkColor = colorToCSS([styleConfig taskListCheckmarkColor]);
254
+ cache.taskCheckboxSize = [styleConfig taskListCheckboxSize];
255
+ cache.taskCheckboxBorderRadius = [styleConfig taskListCheckboxBorderRadius];
256
+ cache.h1Color = colorToCSS([styleConfig h1Color]);
257
+ cache.h2Color = colorToCSS([styleConfig h2Color]);
258
+ cache.h3Color = colorToCSS([styleConfig h3Color]);
259
+ cache.h4Color = colorToCSS([styleConfig h4Color]);
260
+ cache.h5Color = colorToCSS([styleConfig h5Color]);
261
+ cache.h6Color = colorToCSS([styleConfig h6Color]);
262
+
263
+ cache.paragraphFontSize = [styleConfig paragraphFontSize];
264
+ cache.paragraphMarginBottom = [styleConfig paragraphMarginBottom];
265
+ cache.codeBlockFontSize = [styleConfig codeBlockFontSize];
266
+ cache.codeBlockPadding = [styleConfig codeBlockPadding];
267
+ cache.codeBlockBorderRadius = [styleConfig codeBlockBorderRadius];
268
+ cache.codeBlockMarginBottom = [styleConfig codeBlockMarginBottom];
269
+ cache.blockquoteFontSize = [styleConfig blockquoteFontSize];
270
+ cache.blockquoteBorderWidth = [styleConfig blockquoteBorderWidth];
271
+ cache.blockquoteMarginBottom = [styleConfig blockquoteMarginBottom];
272
+ cache.blockquoteGapWidth = [styleConfig blockquoteGapWidth];
273
+ cache.listStyleFontSize = [styleConfig listStyleFontSize];
274
+ cache.listStyleMarginBottom = [styleConfig listStyleMarginBottom];
275
+ cache.listStyleMarginLeft = [styleConfig listStyleMarginLeft];
276
+ cache.imageMarginBottom = [styleConfig imageMarginBottom];
277
+ cache.imageBorderRadius = [styleConfig imageBorderRadius];
278
+ cache.h1FontSize = [styleConfig h1FontSize];
279
+ cache.h2FontSize = [styleConfig h2FontSize];
280
+ cache.h3FontSize = [styleConfig h3FontSize];
281
+ cache.h4FontSize = [styleConfig h4FontSize];
282
+ cache.h5FontSize = [styleConfig h5FontSize];
283
+ cache.h6FontSize = [styleConfig h6FontSize];
284
+ cache.h1MarginBottom = [styleConfig h1MarginBottom];
285
+ cache.h2MarginBottom = [styleConfig h2MarginBottom];
286
+ cache.h3MarginBottom = [styleConfig h3MarginBottom];
287
+ cache.h4MarginBottom = [styleConfig h4MarginBottom];
288
+ cache.h5MarginBottom = [styleConfig h5MarginBottom];
289
+ cache.h6MarginBottom = [styleConfig h6MarginBottom];
290
+ cache.h1FontWeight = fontWeightToCSS([styleConfig h1FontWeight]);
291
+ cache.h2FontWeight = fontWeightToCSS([styleConfig h2FontWeight]);
292
+ cache.h3FontWeight = fontWeightToCSS([styleConfig h3FontWeight]);
293
+ cache.h4FontWeight = fontWeightToCSS([styleConfig h4FontWeight]);
294
+ cache.h5FontWeight = fontWeightToCSS([styleConfig h5FontWeight]);
295
+ cache.h6FontWeight = fontWeightToCSS([styleConfig h6FontWeight]);
296
+ cache.linkFontFamily = [styleConfig linkFontFamily];
297
+ cache.linkColor = colorToCSS([styleConfig linkColor]);
298
+ cache.linkUnderline = [styleConfig linkUnderline];
299
+ cache.thematicBreakColor = colorToCSS([styleConfig thematicBreakColor]);
300
+ cache.thematicBreakHeight = [styleConfig thematicBreakHeight];
301
+ cache.thematicBreakMarginTop = [styleConfig thematicBreakMarginTop];
302
+ cache.thematicBreakMarginBottom = [styleConfig thematicBreakMarginBottom];
303
+ cache.strikethroughColor = colorToCSS([styleConfig strikethroughColor]);
304
+ cache.underlineColor = colorToCSS([styleConfig underlineColor]);
305
+ cache.highlightColor = colorToCSS([styleConfig highlightColor]);
306
+ cache.highlightBackgroundColor = colorToCSS([styleConfig highlightBackgroundColor]);
307
+
308
+ return cache;
309
+ }
310
+
311
+ #pragma mark - Font Helpers
312
+
313
+ static BOOL isMonospaceFont(UIFont *font)
314
+ {
315
+ if (!font)
316
+ return NO;
317
+ NSString *fontName = font.fontName.lowercaseString;
318
+ return [fontName containsString:@"menlo"] || [fontName containsString:@"courier"] ||
319
+ [fontName containsString:@"monaco"] || [fontName containsString:@"consolas"];
320
+ }
321
+
322
+ static BOOL isCodeSpan(NSDictionary *attrs, BOOL isCodeBlock)
323
+ {
324
+ if (isCodeBlock)
325
+ return NO;
326
+
327
+ NSNumber *codeAttr = attrs[CodeAttributeName];
328
+ if ([codeAttr boolValue])
329
+ return YES;
330
+
331
+ return isMonospaceFont(attrs[NSFontAttributeName]);
332
+ }
333
+
334
+ #pragma mark - Paragraph Type Detection
335
+
336
+ static ParagraphType getParagraphType(NSDictionary *attrs)
337
+ {
338
+ NSNumber *isCodeBlock = attrs[CodeBlockAttributeName];
339
+ if ([isCodeBlock boolValue])
340
+ return ParagraphTypeCodeBlock;
341
+
342
+ NSString *markdownType = attrs[MarkdownTypeAttributeName];
343
+ if (markdownType) {
344
+ if ([markdownType hasPrefix:@"heading-"]) {
345
+ NSInteger level = [[markdownType substringFromIndex:8] integerValue];
346
+ if (level >= 1 && level <= 6) {
347
+ return ParagraphTypeHeading1 + (level - 1);
348
+ }
349
+ }
350
+ if ([markdownType isEqualToString:@"code-block"])
351
+ return ParagraphTypeCodeBlock;
352
+ }
353
+
354
+ NSNumber *blockquoteDepth = attrs[BlockquoteDepthAttributeName];
355
+ if (blockquoteDepth && [blockquoteDepth integerValue] >= 0)
356
+ return ParagraphTypeBlockquote;
357
+
358
+ NSNumber *listDepth = attrs[ListDepthAttribute];
359
+ if (listDepth && [listDepth integerValue] >= 0) {
360
+ if ([attrs[TaskItemAttribute] boolValue])
361
+ return ParagraphTypeTaskList;
362
+ NSNumber *listType = attrs[ListTypeAttribute];
363
+ if (listType && [listType integerValue] == ListTypeOrdered)
364
+ return ParagraphTypeListItemOrdered;
365
+ return ParagraphTypeListItemUnordered;
366
+ }
367
+
368
+ return ParagraphTypeNormal;
369
+ }
370
+
371
+ #pragma mark - Paragraph Collection
372
+
373
+ static NSData *collectParagraphsData(NSAttributedString *attributedString, NSUInteger *outCount)
374
+ {
375
+ NSString *string = attributedString.string;
376
+ NSMutableData *data = [NSMutableData dataWithCapacity:string.length / 20 * sizeof(ParagraphData)];
377
+ NSUInteger currentIndex = 0;
378
+ NSUInteger count = 0;
379
+
380
+ while (currentIndex < string.length) {
381
+ NSRange lineRange = [string lineRangeForRange:NSMakeRange(currentIndex, 0)];
382
+
383
+ ParagraphData para = {
384
+ .range = lineRange, .type = ParagraphTypeNormal, .depth = 0, .listNumber = 1, .isTaskChecked = NO};
385
+
386
+ if (lineRange.location < attributedString.length) {
387
+ NSDictionary *attrs = [attributedString attributesAtIndex:lineRange.location effectiveRange:NULL];
388
+ para.type = getParagraphType(attrs);
389
+
390
+ NSNumber *listDepth = attrs[ListDepthAttribute];
391
+ NSNumber *blockquoteDepth = attrs[BlockquoteDepthAttributeName];
392
+ NSNumber *listNumber = attrs[ListItemNumberAttribute];
393
+
394
+ para.depth = listDepth ? [listDepth integerValue] : (blockquoteDepth ? [blockquoteDepth integerValue] : 0);
395
+ para.listNumber = listNumber ? [listNumber integerValue] : 1;
396
+
397
+ if (para.type == ParagraphTypeTaskList) {
398
+ para.isTaskChecked = [attrs[TaskCheckedAttribute] boolValue];
399
+ }
400
+ }
401
+
402
+ [data appendBytes:&para length:sizeof(ParagraphData)];
403
+ count++;
404
+ currentIndex = NSMaxRange(lineRange);
405
+ }
406
+
407
+ *outCount = count;
408
+ return data;
409
+ }
410
+
411
+ #pragma mark - Heading Helpers
412
+
413
+ static NSInteger headingLevel(ParagraphType type)
414
+ {
415
+ if (type >= ParagraphTypeHeading1 && type <= ParagraphTypeHeading6) {
416
+ return type - ParagraphTypeHeading1 + 1;
417
+ }
418
+ return 0;
419
+ }
420
+
421
+ #pragma mark - Container Closing Helpers
422
+
423
+ static void closeBlockquotes(NSMutableString *html, GeneratorState *state)
424
+ {
425
+ while (state.currentBlockquoteDepth >= 0) {
426
+ [html appendString:@"</blockquote>"];
427
+ state.currentBlockquoteDepth--;
428
+ }
429
+ state.inBlockquote = NO;
430
+ }
431
+
432
+ static void closeLists(NSMutableString *html, GeneratorState *state)
433
+ {
434
+ while (state.openListTypes.count > 0) {
435
+ NSString *closeTag = ([state.openListTypes.lastObject integerValue] == 1) ? @"</ol>" : @"</ul>";
436
+ [html appendString:closeTag];
437
+ [state.openListTypes removeLastObject];
438
+ }
439
+ state.currentListDepth = -1;
440
+ }
441
+
442
+ static void closeCodeBlock(NSMutableString *html, GeneratorState *state)
443
+ {
444
+ if (state.inCodeBlock) {
445
+ [html appendString:@"</code></pre>"];
446
+ state.inCodeBlock = NO;
447
+ }
448
+ }
449
+
450
+ #pragma mark - Inline Content Generation
451
+
452
+ static void generateInlineHTML(NSMutableString *html, NSAttributedString *attributedString, NSRange range,
453
+ CachedStyles *styles, BOOL isCodeBlock)
454
+ {
455
+ NSString *string = attributedString.string;
456
+
457
+ [attributedString
458
+ enumerateAttributesInRange:range
459
+ options:0
460
+ usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange attrRange, BOOL *stop) {
461
+ NSString *text = [string substringWithRange:attrRange];
462
+
463
+ if ([text isEqualToString:@"\n"])
464
+ return;
465
+
466
+ if ([text containsString:kObjectReplacementChar]) {
467
+ id attachment = attrs[NSAttachmentAttributeName];
468
+ if ([attachment isKindOfClass:[ENRMImageAttachment class]]) {
469
+ ENRMImageAttachment *img = (ENRMImageAttachment *)attachment;
470
+ if (img.imageURL) {
471
+ if (img.isInline) {
472
+ [html appendFormat:
473
+ @"<img src=\"%@\" style=\"height: 1.2em; width: auto; "
474
+ @"vertical-align: -0.2em;\">",
475
+ img.imageURL];
476
+ } else {
477
+ [html appendFormat:
478
+ @"</p><div style=\"margin-bottom: %.0fpx;\"><img src=\"%@\" "
479
+ @"style=\"max-width: 100%%; border-radius: %.0fpx;\"></div><p>",
480
+ styles.imageMarginBottom, img.imageURL, styles.imageBorderRadius];
481
+ }
482
+ }
483
+ } else if ([attachment isKindOfClass:[ThematicBreakAttachment class]]) {
484
+ [html appendFormat:
485
+ @"</p><hr style=\"border: none; border-top: %.0fpx solid %@; "
486
+ @"margin: %.0fpx 0 %.0fpx 0;\"><p>",
487
+ styles.thematicBreakHeight, styles.thematicBreakColor,
488
+ styles.thematicBreakMarginTop, styles.thematicBreakMarginBottom];
489
+ #if ENRICHED_MARKDOWN_MATH
490
+ } else if ([attachment isKindOfClass:[ENRMMathInlineAttachment class]]) {
491
+ ENRMMathInlineAttachment *math = (ENRMMathInlineAttachment *)attachment;
492
+ if (math.latex.length > 0) {
493
+ [html appendFormat:
494
+ @"<code style=\"background-color: %@; color: %@; "
495
+ @"padding: %.0fpx %.0fpx; border-radius: %.0fpx; "
496
+ @"font-size: 1em; font-family: Menlo, Monaco, Consolas, monospace;\">%@</code>",
497
+ styles.codeBackgroundColor, styles.codeColor, kCodePadding, kCodePadding * 2,
498
+ kCodeBorderRadius, escapeHTML(math.latex)];
499
+ }
500
+ #endif
501
+ }
502
+ return;
503
+ }
504
+
505
+ UIFont *font = attrs[NSFontAttributeName];
506
+ NSNumber *underline = attrs[NSUnderlineStyleAttributeName];
507
+ NSNumber *strikethrough = attrs[NSStrikethroughStyleAttributeName];
508
+ id linkAttr = attrs[NSLinkAttributeName];
509
+ BOOL isCode = isCodeSpan(attrs, isCodeBlock);
510
+
511
+ BOOL isBold = NO, isItalic = NO;
512
+ if (font) {
513
+ UIFontDescriptorSymbolicTraits traits = font.fontDescriptor.symbolicTraits;
514
+ isBold = (traits & UIFontDescriptorTraitBold) != 0;
515
+ isItalic = (traits & UIFontDescriptorTraitItalic) != 0;
516
+ }
517
+
518
+ BOOL isHighlight = [attrs[HighlightAttributeName] boolValue];
519
+
520
+ if (isHighlight) {
521
+ NSMutableString *markStyle = [NSMutableString
522
+ stringWithFormat:@"background-color: %@", styles.highlightBackgroundColor];
523
+ if (styles.highlightColor && ![styles.highlightColor isEqualToString:styles.paragraphColor]) {
524
+ [markStyle appendFormat:@"; color: %@", styles.highlightColor];
525
+ } else {
526
+ [markStyle appendString:@"; color: inherit"];
527
+ }
528
+ [html appendFormat:@"<mark style=\"%@\">", markStyle];
529
+ }
530
+
531
+ if (linkAttr) {
532
+ NSString *href =
533
+ [linkAttr isKindOfClass:[NSURL class]] ? [(NSURL *)linkAttr absoluteString] : linkAttr;
534
+ if (styles.linkFontFamily.length > 0) {
535
+ [html appendFormat:
536
+ @"<a href=\"%@\" style=\"color: %@; text-decoration: %@; font-family: '%@';\">",
537
+ escapeHTML(href), styles.linkColor, styles.linkUnderline ? @"underline" : @"none",
538
+ styles.linkFontFamily];
539
+ } else {
540
+ [html appendFormat:@"<a href=\"%@\" style=\"color: %@; text-decoration: %@;\">",
541
+ escapeHTML(href), styles.linkColor,
542
+ styles.linkUnderline ? @"underline" : @"none"];
543
+ }
544
+ }
545
+
546
+ if (isCode) {
547
+ [html appendFormat:
548
+ @"<code style=\"background-color: %@; color: %@; "
549
+ @"padding: %.0fpx %.0fpx; border-radius: %.0fpx; "
550
+ @"font-size: 1em; font-family: Menlo, Monaco, Consolas, monospace;\">",
551
+ styles.codeBackgroundColor, styles.codeColor, kCodePadding, kCodePadding * 2,
552
+ kCodeBorderRadius];
553
+ }
554
+
555
+ if (isBold) {
556
+ if (styles.strongColor && ![styles.strongColor isEqualToString:@"inherit"]) {
557
+ [html appendFormat:@"<strong style=\"color: %@;\">", styles.strongColor];
558
+ } else {
559
+ [html appendString:@"<strong>"];
560
+ }
561
+ }
562
+
563
+ if (isItalic) {
564
+ if (styles.emphasisColor && ![styles.emphasisColor isEqualToString:@"inherit"]) {
565
+ [html appendFormat:@"<em style=\"color: %@;\">", styles.emphasisColor];
566
+ } else {
567
+ [html appendString:@"<em>"];
568
+ }
569
+ }
570
+
571
+ if ([strikethrough integerValue] > 0) {
572
+ if (styles.strikethroughColor && ![styles.strikethroughColor isEqualToString:@"inherit"]) {
573
+ [html appendFormat:@"<s style=\"text-decoration-color: %@;\">", styles.strikethroughColor];
574
+ } else {
575
+ [html appendString:@"<s>"];
576
+ }
577
+ }
578
+ if ([underline integerValue] > 0 && !linkAttr) {
579
+ if (styles.underlineColor && ![styles.underlineColor isEqualToString:@"inherit"]) {
580
+ [html appendFormat:@"<u style=\"text-decoration-color: %@;\">", styles.underlineColor];
581
+ } else {
582
+ [html appendString:@"<u>"];
583
+ }
584
+ }
585
+
586
+ [html appendString:escapeHTML(text)];
587
+
588
+ // Reverse order
589
+ if ([underline integerValue] > 0 && !linkAttr)
590
+ [html appendString:@"</u>"];
591
+ if ([strikethrough integerValue] > 0)
592
+ [html appendString:@"</s>"];
593
+ if (isItalic)
594
+ [html appendString:@"</em>"];
595
+ if (isBold)
596
+ [html appendString:@"</strong>"];
597
+ if (isCode)
598
+ [html appendString:@"</code>"];
599
+ if (linkAttr)
600
+ [html appendString:@"</a>"];
601
+ if (isHighlight)
602
+ [html appendString:@"</mark>"];
603
+ }];
604
+ }
605
+
606
+ #pragma mark - Block Handlers
607
+
608
+ static void handleCodeBlock(NSMutableString *html, NSMutableString *inlineContent, CachedStyles *styles,
609
+ GeneratorState *state)
610
+ {
611
+ if (!state.inCodeBlock) {
612
+ state.inCodeBlock = YES;
613
+ [html appendFormat:
614
+ @"<pre dir=\"ltr\" style=\"background-color: %@; padding: %.0fpx; border-radius: %.0fpx; "
615
+ @"margin: 0 0 %.0fpx 0; overflow-x: auto; text-align: left;\"><code style=\"font-family: Menlo, Monaco, "
616
+ @"Consolas, monospace; font-size: %.0fpx; color: %@;\">",
617
+ styles.codeBlockBackgroundColor, styles.codeBlockPadding, styles.codeBlockBorderRadius,
618
+ styles.codeBlockMarginBottom, styles.codeBlockFontSize, styles.codeBlockColor];
619
+ } else if (state.previousWasCodeBlock) {
620
+ [html appendString:@"\n"];
621
+ }
622
+
623
+ [html appendString:inlineContent];
624
+ state.previousWasCodeBlock = YES;
625
+ }
626
+
627
+ static void handleBlockquote(NSMutableString *html, ParagraphData *para, NSMutableString *inlineContent,
628
+ CachedStyles *styles, GeneratorState *state)
629
+ {
630
+ NSInteger depth = para->depth;
631
+
632
+ // Reset if starting a new blockquote block
633
+ if (!state.previousWasBlockquote && state.inBlockquote) {
634
+ closeBlockquotes(html, state);
635
+ }
636
+
637
+ while (state.currentBlockquoteDepth > depth) {
638
+ [html appendString:@"</blockquote>"];
639
+ state.currentBlockquoteDepth--;
640
+ }
641
+
642
+ while (state.currentBlockquoteDepth < depth) {
643
+ state.currentBlockquoteDepth++;
644
+ state.inBlockquote = YES;
645
+
646
+ if (state.currentBlockquoteDepth == 0) {
647
+ [html appendFormat:
648
+ @"<blockquote style=\"background-color: %@; border-inline-start: %.0fpx solid %@; "
649
+ @"padding: %.0fpx %.0fpx; margin: 0 0 %.0fpx 0; border-start-end-radius: 8px; border-end-end-radius: "
650
+ @"8px;\">",
651
+ styles.blockquoteBackgroundColor, styles.blockquoteBorderWidth, styles.blockquoteBorderColor,
652
+ kBlockquoteVerticalPadding, styles.blockquoteGapWidth, styles.blockquoteMarginBottom];
653
+ } else {
654
+ [html appendFormat:
655
+ @"<blockquote style=\"border-inline-start: %.0fpx solid %@; padding-inline-start: %.0fpx; "
656
+ @"margin: %.0fpx 0 0 0;\">",
657
+ styles.blockquoteBorderWidth, styles.blockquoteBorderColor, styles.blockquoteGapWidth,
658
+ kNestedBlockquoteTopMargin];
659
+ }
660
+ }
661
+
662
+ [html appendFormat:@"<p style=\"margin: 0 0 %.0fpx 0; color: %@; font-size: %.0fpx;\">%@</p>",
663
+ kBlockquoteParagraphSpacing, styles.blockquoteColor, styles.blockquoteFontSize, inlineContent];
664
+
665
+ state.previousWasBlockquote = YES;
666
+ }
667
+
668
+ static void handleListItem(NSMutableString *html, ParagraphData *para, NSMutableString *inlineContent,
669
+ CachedStyles *styles, GeneratorState *state)
670
+ {
671
+ NSInteger depth = para->depth;
672
+ BOOL isOrdered = (para->type == ParagraphTypeListItemOrdered);
673
+ BOOL isTask = (para->type == ParagraphTypeTaskList);
674
+ NSInteger listTypeValue = isOrdered ? 1 : 0;
675
+
676
+ while (state.currentListDepth > depth) {
677
+ NSString *closeTag = ([state.openListTypes.lastObject integerValue] == 1) ? @"</ol>" : @"</ul>";
678
+ [html appendString:closeTag];
679
+ [state.openListTypes removeLastObject];
680
+ state.currentListDepth--;
681
+ }
682
+
683
+ // List type change at same depth (ul <-> ol)
684
+ if (state.currentListDepth == depth && state.openListTypes.count > 0) {
685
+ NSInteger currentType = [state.openListTypes.lastObject integerValue];
686
+ if (currentType != listTypeValue) {
687
+ NSString *closeTag = (currentType == 1) ? @"</ol>" : @"</ul>";
688
+ [html appendString:closeTag];
689
+ [state.openListTypes removeLastObject];
690
+ state.currentListDepth--;
691
+ }
692
+ }
693
+
694
+ CGFloat indent = styles.listStyleMarginLeft > 0 ? styles.listStyleMarginLeft : kDefaultListIndent;
695
+
696
+ while (state.currentListDepth < depth) {
697
+ state.currentListDepth++;
698
+ if (isOrdered) {
699
+ [html appendFormat:@"<ol style=\"margin: 0; padding-inline-start: %.0fpx;\">", indent];
700
+ } else {
701
+ NSString *listStyleType = isTask ? @"none" : @"disc";
702
+ [html appendFormat:@"<ul style=\"margin: 0; padding-inline-start: %.0fpx; list-style-type: %@;\">", indent,
703
+ listStyleType];
704
+ }
705
+ [state.openListTypes addObject:@(listTypeValue)];
706
+ }
707
+
708
+ [html appendFormat:@"<li style=\"margin-bottom: %.0fpx; color: %@; font-size: %.0fpx;\">",
709
+ styles.listStyleMarginBottom, styles.listStyleColor, styles.listStyleFontSize];
710
+
711
+ if (isTask) {
712
+ CGFloat size = styles.taskCheckboxSize;
713
+ CGFloat radius = styles.taskCheckboxBorderRadius;
714
+ if (para->isTaskChecked) {
715
+ [html appendFormat:
716
+ @"<span style=\"display: inline-block; width: %.0fpx; height: %.0fpx; "
717
+ @"border-radius: %.0fpx; background-color: %@; color: %@; "
718
+ @"font-size: %.0fpx; line-height: %.0fpx; text-align: center; "
719
+ @"vertical-align: middle; margin-inline-end: 4px;\">&#10003;</span> ",
720
+ size, size, radius, styles.taskCheckedColor, styles.taskCheckmarkColor, size - 2, size];
721
+ } else {
722
+ [html appendFormat:
723
+ @"<span style=\"display: inline-block; width: %.0fpx; height: %.0fpx; "
724
+ @"border-radius: %.0fpx; border: 1.5px solid %@; "
725
+ @"vertical-align: middle; margin-inline-end: 4px;\"></span> ",
726
+ size, size, radius, styles.taskBorderColor];
727
+ }
728
+ }
729
+
730
+ [html appendFormat:@"%@</li>", inlineContent];
731
+ }
732
+
733
+ static void handleHeading(NSMutableString *html, ParagraphData *para, NSMutableString *inlineContent,
734
+ CachedStyles *styles)
735
+ {
736
+ NSInteger level = headingLevel(para->type);
737
+ CGFloat fontSize, marginBottom;
738
+ NSString *fontWeight, *color;
739
+
740
+ switch (level) {
741
+ case 1:
742
+ fontSize = styles.h1FontSize;
743
+ fontWeight = styles.h1FontWeight;
744
+ color = styles.h1Color;
745
+ marginBottom = styles.h1MarginBottom;
746
+ break;
747
+ case 2:
748
+ fontSize = styles.h2FontSize;
749
+ fontWeight = styles.h2FontWeight;
750
+ color = styles.h2Color;
751
+ marginBottom = styles.h2MarginBottom;
752
+ break;
753
+ case 3:
754
+ fontSize = styles.h3FontSize;
755
+ fontWeight = styles.h3FontWeight;
756
+ color = styles.h3Color;
757
+ marginBottom = styles.h3MarginBottom;
758
+ break;
759
+ case 4:
760
+ fontSize = styles.h4FontSize;
761
+ fontWeight = styles.h4FontWeight;
762
+ color = styles.h4Color;
763
+ marginBottom = styles.h4MarginBottom;
764
+ break;
765
+ case 5:
766
+ fontSize = styles.h5FontSize;
767
+ fontWeight = styles.h5FontWeight;
768
+ color = styles.h5Color;
769
+ marginBottom = styles.h5MarginBottom;
770
+ break;
771
+ case 6:
772
+ fontSize = styles.h6FontSize;
773
+ fontWeight = styles.h6FontWeight;
774
+ color = styles.h6Color;
775
+ marginBottom = styles.h6MarginBottom;
776
+ break;
777
+ default:
778
+ fontSize = 16;
779
+ fontWeight = @"normal";
780
+ color = @"inherit";
781
+ marginBottom = 0;
782
+ break;
783
+ }
784
+
785
+ [html appendFormat:@"<h%ld style=\"font-size: %.0fpx; font-weight: %@; color: %@; margin: 0 0 %.0fpx 0;\">%@</h%ld>",
786
+ (long)level, fontSize, fontWeight, color, marginBottom, inlineContent, (long)level];
787
+ }
788
+
789
+ static void handleParagraph(NSMutableString *html, NSMutableString *inlineContent, CachedStyles *styles)
790
+ {
791
+ [html appendFormat:@"<p style=\"margin: 0 0 %.0fpx 0; color: %@; font-size: %.0fpx;\">%@</p>",
792
+ styles.paragraphMarginBottom, styles.paragraphColor, styles.paragraphFontSize, inlineContent];
793
+ }
794
+
795
+ #pragma mark - Main Generator
796
+
797
+ static NSString *dirAttrFromParagraphStyle(NSParagraphStyle *_Nullable style)
798
+ {
799
+ if (!style || style.baseWritingDirection == NSWritingDirectionNatural) {
800
+ return @"auto";
801
+ }
802
+ return style.baseWritingDirection == NSWritingDirectionRightToLeft ? @"rtl" : @"ltr";
803
+ }
804
+
805
+ NSString *_Nullable generateHTML(NSAttributedString *attributedString, StyleConfig *styleConfig)
806
+ {
807
+ if (!attributedString || attributedString.length == 0)
808
+ return nil;
809
+
810
+ CachedStyles *styles = cacheStyles(styleConfig);
811
+
812
+ NSParagraphStyle *firstParagraphStyle = [attributedString attribute:NSParagraphStyleAttributeName
813
+ atIndex:0
814
+ effectiveRange:NULL];
815
+ NSString *dirAttr = dirAttrFromParagraphStyle(firstParagraphStyle);
816
+
817
+ NSMutableString *html = [NSMutableString stringWithCapacity:attributedString.length * 2];
818
+ [html appendFormat:
819
+ @"<!DOCTYPE html><html dir=\"%@\"><head><meta charset=\"UTF-8\"></head><body "
820
+ @"style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">",
821
+ dirAttr];
822
+
823
+ NSUInteger paragraphCount = 0;
824
+ NSData *paragraphsData = collectParagraphsData(attributedString, &paragraphCount);
825
+ ParagraphData *paragraphs = (ParagraphData *)paragraphsData.bytes;
826
+
827
+ GeneratorState *state = [[GeneratorState alloc] init];
828
+ NSMutableString *inlineBuffer = [NSMutableString stringWithCapacity:256];
829
+
830
+ for (NSUInteger i = 0; i < paragraphCount; i++) {
831
+ ParagraphData *para = &paragraphs[i];
832
+
833
+ NSString *content = [[attributedString.string substringWithRange:para->range]
834
+ stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
835
+
836
+ if (content.length == 0) {
837
+ state.previousWasBlockquote = NO;
838
+ continue;
839
+ }
840
+
841
+ [inlineBuffer setString:@""];
842
+ NSRange contentRange = para->range;
843
+ if (contentRange.length > 0 &&
844
+ [[attributedString.string substringWithRange:NSMakeRange(NSMaxRange(contentRange) - 1, 1)]
845
+ isEqualToString:@"\n"]) {
846
+ contentRange.length--;
847
+ }
848
+
849
+ BOOL isCodeBlockPara = (para->type == ParagraphTypeCodeBlock);
850
+ generateInlineHTML(inlineBuffer, attributedString, contentRange, styles, isCodeBlockPara);
851
+
852
+ if (isCodeBlockPara) {
853
+ handleCodeBlock(html, inlineBuffer, styles, state);
854
+ continue;
855
+ }
856
+
857
+ if (state.inCodeBlock) {
858
+ closeCodeBlock(html, state);
859
+ }
860
+ state.previousWasCodeBlock = NO;
861
+
862
+ if (para->type == ParagraphTypeBlockquote) {
863
+ handleBlockquote(html, para, inlineBuffer, styles, state);
864
+ continue;
865
+ }
866
+
867
+ if (state.inBlockquote) {
868
+ closeBlockquotes(html, state);
869
+ }
870
+ state.previousWasBlockquote = NO;
871
+
872
+ if (para->type == ParagraphTypeListItemUnordered || para->type == ParagraphTypeListItemOrdered ||
873
+ para->type == ParagraphTypeTaskList) {
874
+ handleListItem(html, para, inlineBuffer, styles, state);
875
+ continue;
876
+ }
877
+
878
+ if (state.currentListDepth >= 0) {
879
+ closeLists(html, state);
880
+ }
881
+
882
+ NSInteger hLevel = headingLevel(para->type);
883
+ if (hLevel > 0) {
884
+ handleHeading(html, para, inlineBuffer, styles);
885
+ continue;
886
+ }
887
+
888
+ handleParagraph(html, inlineBuffer, styles);
889
+ }
890
+
891
+ closeCodeBlock(html, state);
892
+ closeBlockquotes(html, state);
893
+ closeLists(html, state);
894
+
895
+ [html appendString:@"</body></html>"];
896
+
897
+ return html;
898
+ }
899
+
900
+ #pragma mark - Table HTML Generator
901
+
902
+ typedef NSString *HTMLString;
903
+
904
+ static NSString *alignmentToCSS(NSTextAlignment alignment)
905
+ {
906
+ switch (alignment) {
907
+ case NSTextAlignmentCenter:
908
+ return @"center";
909
+ case NSTextAlignmentRight:
910
+ return @"right";
911
+ case NSTextAlignmentJustified:
912
+ return @"justify";
913
+ default:
914
+ return @"left";
915
+ }
916
+ }
917
+
918
+ static NSString *styleForCell(BOOL isHeader, NSUInteger rowIndex, StyleConfig *styleConfig, NSTextAlignment alignment)
919
+ {
920
+ NSString *backgroundColor = isHeader ? colorToCSS(styleConfig.tableHeaderBackgroundColor)
921
+ : (rowIndex % 2 == 0 ? colorToCSS(styleConfig.tableRowEvenBackgroundColor)
922
+ : colorToCSS(styleConfig.tableRowOddBackgroundColor));
923
+
924
+ NSString *textColor = isHeader ? colorToCSS(styleConfig.tableHeaderTextColor) : colorToCSS(styleConfig.tableColor);
925
+
926
+ return [NSString stringWithFormat:
927
+ @"padding: %.0fpx %.0fpx; "
928
+ "text-align: %@; "
929
+ "background-color: %@; "
930
+ "color: %@; "
931
+ "border: %.0fpx solid %@; "
932
+ "font-weight: %@;",
933
+ styleConfig.tableCellPaddingVertical, styleConfig.tableCellPaddingHorizontal,
934
+ alignmentToCSS(alignment), backgroundColor, textColor, styleConfig.tableBorderWidth,
935
+ colorToCSS(styleConfig.tableBorderColor), isHeader ? @"bold" : @"normal"];
936
+ }
937
+
938
+ static NSString *tableDirAttrFromRows(NSArray<NSArray<NSDictionary *> *> *rows)
939
+ {
940
+ for (NSArray<NSDictionary *> *row in rows) {
941
+ for (NSDictionary *cell in row) {
942
+ NSAttributedString *cellText = cell[@"attributedText"];
943
+ if (cellText.length == 0) {
944
+ continue;
945
+ }
946
+ NSParagraphStyle *style = [cellText attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL];
947
+ return dirAttrFromParagraphStyle(style);
948
+ }
949
+ }
950
+ return @"auto";
951
+ }
952
+
953
+ HTMLString _Nullable generateTableHTML(NSArray<NSArray<NSDictionary *> *> *rows, StyleConfig *styleConfig)
954
+ {
955
+ if (rows.count == 0)
956
+ return nil;
957
+
958
+ CachedStyles *cachedStyles = cacheStyles(styleConfig);
959
+ NSMutableString *htmlOutput = [NSMutableString stringWithCapacity:rows.count * 250];
960
+
961
+ NSString *dirAttr = tableDirAttrFromRows(rows);
962
+
963
+ [htmlOutput appendFormat:
964
+ @"<table dir=\"%@\" style=\"border-collapse: separate; border-spacing: 0; "
965
+ "border: %.0fpx solid %@; border-radius: %.0fpx; overflow: hidden; font-size: %.0fpx;\">",
966
+ dirAttr, styleConfig.tableBorderWidth, colorToCSS(styleConfig.tableBorderColor),
967
+ styleConfig.tableBorderRadius, styleConfig.tableFontSize];
968
+
969
+ BOOL hasOpenedBody = NO;
970
+ NSUInteger bodyRowIndex = 0;
971
+
972
+ for (NSArray<NSDictionary *> *row in rows) {
973
+ if (row.count == 0)
974
+ continue;
975
+
976
+ BOOL isHeaderRow = [row.firstObject[@"isHeader"] boolValue];
977
+
978
+ if (isHeaderRow) {
979
+ [htmlOutput appendString:@"<thead>"];
980
+ } else if (!hasOpenedBody) {
981
+ [htmlOutput appendString:@"<tbody>"];
982
+ hasOpenedBody = YES;
983
+ }
984
+
985
+ [htmlOutput appendString:@"<tr>"];
986
+
987
+ for (NSDictionary *cellInfo in row) {
988
+ BOOL isHeaderCell = [cellInfo[@"isHeader"] boolValue];
989
+ NSTextAlignment alignment = (NSTextAlignment)[cellInfo[@"alignment"] integerValue];
990
+ NSAttributedString *attributedText = cellInfo[@"attributedText"];
991
+
992
+ NSString *htmlTag = isHeaderCell ? @"th" : @"td";
993
+ NSString *cellStyle = styleForCell(isHeaderCell, bodyRowIndex, styleConfig, alignment);
994
+
995
+ [htmlOutput appendFormat:@"<%@ style=\"%@\">", htmlTag, cellStyle];
996
+
997
+ if (attributedText.length > 0) {
998
+ generateInlineHTML(htmlOutput, attributedText, NSMakeRange(0, attributedText.length), cachedStyles, NO);
999
+ }
1000
+
1001
+ [htmlOutput appendFormat:@"</%@>", htmlTag];
1002
+ }
1003
+
1004
+ [htmlOutput appendString:@"</tr>"];
1005
+
1006
+ if (isHeaderRow) {
1007
+ [htmlOutput appendString:@"</thead>"];
1008
+ } else {
1009
+ bodyRowIndex++;
1010
+ }
1011
+ }
1012
+
1013
+ if (hasOpenedBody) {
1014
+ [htmlOutput appendString:@"</tbody>"];
1015
+ }
1016
+
1017
+ [htmlOutput appendString:@"</table>"];
1018
+ return [htmlOutput copy];
1019
+ }