react-native-marcus 0.1.0 → 0.2.0

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 (294) hide show
  1. package/README.md +220 -63
  2. package/RNMarcus.podspec +6 -0
  3. package/android/src/main/java/app/getbullet/marcus/MarcusPackage.kt +2 -1
  4. package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorView.kt +168 -0
  5. package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorViewManager.kt +38 -0
  6. package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorViewManagerSpec.kt +19 -0
  7. package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorView.kt +23 -1
  8. package/android/src/main/java/app/getbullet/marcus/MarkdownBackgroundPainter.kt +147 -0
  9. package/android/src/main/java/app/getbullet/marcus/MarkdownBackgroundPass.kt +19 -0
  10. package/android/src/main/java/app/getbullet/marcus/MarkdownCopy.kt +87 -0
  11. package/android/src/main/java/app/getbullet/marcus/MarkdownFormatter.kt +652 -113
  12. package/android/src/main/java/app/getbullet/marcus/MarkdownRanges.kt +47 -0
  13. package/android/src/main/java/app/getbullet/marcus/MarkdownStyle.kt +140 -61
  14. package/android/src/main/java/app/getbullet/marcus/MarkdownUtils.kt +37 -7
  15. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownAbsoluteLineHeightSpan.kt +48 -0
  16. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundSpan.kt +102 -48
  17. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBlockIndentSpan.kt +22 -4
  18. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBulletSpan.kt +78 -0
  19. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownCodeBlockSpan.kt +177 -0
  20. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontStyleSpan.kt +32 -0
  21. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontWeightSpan.kt +34 -0
  22. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownGapSpan.kt +24 -11
  23. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownLetterSpacingSpan.kt +32 -0
  24. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownTextShadowSpan.kt +32 -0
  25. package/android/src/main/new_arch/CMakeLists.txt +17 -0
  26. package/android/src/main/new_arch/RNMarcusSpec.h +1 -0
  27. package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorShadowNode.cpp +235 -0
  28. package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorShadowNode.h +62 -0
  29. package/android/src/reactNativeVersionPatch/CustomMountingManager/81/app/getbullet/marcus/CustomFabricUIManager.java +22 -3
  30. package/android/src/reactNativeVersionPatch/CustomMountingManager/latest/app/getbullet/marcus/CustomFabricUIManager.java +22 -3
  31. package/android/src/test/java/app/getbullet/marcus/MarkdownCopyTest.kt +69 -0
  32. package/android/src/test/java/app/getbullet/marcus/MarkdownFormatterTest.kt +170 -25
  33. package/android/src/test/java/app/getbullet/marcus/RenderModel.kt +22 -5
  34. package/android/src/test/java/app/getbullet/marcus/spans/MarkdownCodeBlockSpanTest.kt +91 -0
  35. package/android/src/test/resources/render-model.txt +221 -16
  36. package/apple/MarcusSwizzle.h +25 -0
  37. package/apple/MarcusTextDecoratorComponentView.h +22 -0
  38. package/apple/MarcusTextDecoratorComponentView.mm +72 -0
  39. package/apple/MarcusTextDecoratorShadowNode.h +62 -0
  40. package/apple/MarcusTextDecoratorShadowNode.mm +192 -0
  41. package/apple/MarcusTextDecoratorViewManager.h +4 -0
  42. package/apple/MarcusTextDecoratorViewManager.mm +11 -0
  43. package/apple/MarcusTextInputDecoratorComponentView.mm +1 -1
  44. package/apple/MarcusTextInputDecoratorShadowNode.mm +1 -1
  45. package/apple/MarcusTextLayoutManager.h +40 -0
  46. package/apple/MarcusTextLayoutManager.mm +173 -0
  47. package/apple/MarkdownAttributes.h +23 -2
  48. package/apple/MarkdownAttributes.m +6 -0
  49. package/apple/MarkdownCopy.swift +63 -0
  50. package/apple/MarkdownDecorator.swift +2 -2
  51. package/apple/MarkdownFormatter+React.swift +23 -0
  52. package/apple/MarkdownFormatter.swift +869 -148
  53. package/apple/MarkdownParagraphLayoutManager.swift +455 -0
  54. package/apple/MarkdownSwiftInterop.h +0 -1
  55. package/apple/MarkdownTextBackground.swift +59 -1
  56. package/apple/MarkdownTextFieldObserver.swift +2 -2
  57. package/apple/MarkdownTextLayoutFragment.swift +159 -33
  58. package/apple/MarkdownTextLayoutManagerDelegate.swift +67 -3
  59. package/apple/MarkdownTextStorageDelegate.swift +2 -2
  60. package/apple/MarkdownTextViewObserver.swift +2 -2
  61. package/apple/MarkdownUtils.swift +38 -0
  62. package/apple/MarkdownWritingDirection.swift +132 -0
  63. package/apple/RCTMarcusStyle+Codegen.h +115 -9
  64. package/apple/RCTMarcusStyle.h +128 -31
  65. package/apple/RCTMarcusStyle.m +48 -0
  66. package/apple/RCTParagraphComponentView+Marcus.h +17 -0
  67. package/apple/RCTParagraphComponentView+Marcus.mm +38 -0
  68. package/apple/RCTTextInputComponentView+Marcus.mm +1 -25
  69. package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorState.h +37 -0
  70. package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorViewComponentDescriptor.h +17 -0
  71. package/lib/commonjs/MarcusTextDecoratorViewNativeComponent.ts +199 -0
  72. package/lib/commonjs/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
  73. package/lib/commonjs/MarkdownText.js +330 -0
  74. package/lib/commonjs/MarkdownText.js.map +1 -0
  75. package/lib/commonjs/MarkdownText.web.js +529 -0
  76. package/lib/commonjs/MarkdownText.web.js.map +1 -0
  77. package/lib/commonjs/MarkdownTextInput.js +22 -27
  78. package/lib/commonjs/MarkdownTextInput.js.map +1 -1
  79. package/lib/commonjs/MarkdownTextInput.web.js +12 -7
  80. package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
  81. package/lib/commonjs/atomUtils.js +112 -0
  82. package/lib/commonjs/atomUtils.js.map +1 -0
  83. package/lib/commonjs/childrenUtils.js +36 -0
  84. package/lib/commonjs/childrenUtils.js.map +1 -0
  85. package/lib/commonjs/index.js +8 -7
  86. package/lib/commonjs/index.js.map +1 -1
  87. package/lib/commonjs/math/environment.js +69 -0
  88. package/lib/commonjs/math/environment.js.map +1 -0
  89. package/lib/commonjs/math/index.js +61 -0
  90. package/lib/commonjs/math/index.js.map +1 -0
  91. package/lib/commonjs/math/mathjax.js +548 -0
  92. package/lib/commonjs/math/mathjax.js.map +1 -0
  93. package/lib/commonjs/metro.js +172 -0
  94. package/lib/commonjs/metro.js.map +1 -0
  95. package/lib/commonjs/parser/index.d.ts +3 -0
  96. package/lib/commonjs/parser/index.js +450 -42
  97. package/lib/commonjs/parser/index.js.map +4 -4
  98. package/lib/commonjs/stripUtils.js +743 -0
  99. package/lib/commonjs/stripUtils.js.map +1 -0
  100. package/lib/commonjs/styleUtils.js +194 -23
  101. package/lib/commonjs/styleUtils.js.map +1 -1
  102. package/lib/commonjs/web/MarkdownElements.css +67 -0
  103. package/lib/commonjs/web/MarkdownTextInput.css +9 -7
  104. package/lib/commonjs/web/utils/blockLayout.js +95 -7
  105. package/lib/commonjs/web/utils/blockLayout.js.map +1 -1
  106. package/lib/commonjs/web/utils/blockUtils.js +327 -54
  107. package/lib/commonjs/web/utils/blockUtils.js.map +1 -1
  108. package/lib/commonjs/web/utils/elementUtils.js +80 -0
  109. package/lib/commonjs/web/utils/elementUtils.js.map +1 -0
  110. package/lib/commonjs/web/utils/parserUtils.js +84 -28
  111. package/lib/commonjs/web/utils/parserUtils.js.map +1 -1
  112. package/lib/commonjs/web/utils/treeUtils.js +6 -0
  113. package/lib/commonjs/web/utils/treeUtils.js.map +1 -1
  114. package/lib/commonjs/web/utils/webStyleUtils.js +25 -5
  115. package/lib/commonjs/web/utils/webStyleUtils.js.map +1 -1
  116. package/lib/module/MarcusTextDecoratorViewNativeComponent.ts +199 -0
  117. package/lib/module/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
  118. package/lib/module/MarkdownText.js +325 -0
  119. package/lib/module/MarkdownText.js.map +1 -0
  120. package/lib/module/MarkdownText.web.js +524 -0
  121. package/lib/module/MarkdownText.web.js.map +1 -0
  122. package/lib/module/MarkdownTextInput.js +24 -29
  123. package/lib/module/MarkdownTextInput.js.map +1 -1
  124. package/lib/module/MarkdownTextInput.web.js +12 -7
  125. package/lib/module/MarkdownTextInput.web.js.map +1 -1
  126. package/lib/module/atomUtils.js +106 -0
  127. package/lib/module/atomUtils.js.map +1 -0
  128. package/lib/module/childrenUtils.js +33 -0
  129. package/lib/module/childrenUtils.js.map +1 -0
  130. package/lib/module/index.js +1 -1
  131. package/lib/module/index.js.map +1 -1
  132. package/lib/module/math/environment.js +67 -0
  133. package/lib/module/math/environment.js.map +1 -0
  134. package/lib/module/math/index.js +56 -0
  135. package/lib/module/math/index.js.map +1 -0
  136. package/lib/module/math/mathjax.js +541 -0
  137. package/lib/module/math/mathjax.js.map +1 -0
  138. package/lib/module/metro.js +169 -0
  139. package/lib/module/metro.js.map +1 -0
  140. package/lib/module/parser/index.d.ts +3 -0
  141. package/lib/module/parser/index.js +450 -42
  142. package/lib/module/parser/index.js.map +4 -4
  143. package/lib/module/stripUtils.js +739 -0
  144. package/lib/module/stripUtils.js.map +1 -0
  145. package/lib/module/styleUtils.js +196 -25
  146. package/lib/module/styleUtils.js.map +1 -1
  147. package/lib/module/web/MarkdownElements.css +67 -0
  148. package/lib/module/web/MarkdownTextInput.css +9 -7
  149. package/lib/module/web/utils/blockLayout.js +94 -8
  150. package/lib/module/web/utils/blockLayout.js.map +1 -1
  151. package/lib/module/web/utils/blockUtils.js +328 -56
  152. package/lib/module/web/utils/blockUtils.js.map +1 -1
  153. package/lib/module/web/utils/elementUtils.js +75 -0
  154. package/lib/module/web/utils/elementUtils.js.map +1 -0
  155. package/lib/module/web/utils/parserUtils.js +86 -30
  156. package/lib/module/web/utils/parserUtils.js.map +1 -1
  157. package/lib/module/web/utils/treeUtils.js +6 -0
  158. package/lib/module/web/utils/treeUtils.js.map +1 -1
  159. package/lib/module/web/utils/webStyleUtils.js +25 -5
  160. package/lib/module/web/utils/webStyleUtils.js.map +1 -1
  161. package/lib/typescript/commonjs/e2e/links.test.d.ts +2 -0
  162. package/lib/typescript/commonjs/e2e/links.test.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/src/MarcusTextDecoratorViewNativeComponent.d.ts +93 -0
  164. package/lib/typescript/commonjs/src/MarcusTextDecoratorViewNativeComponent.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +64 -51
  166. package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
  167. package/lib/typescript/commonjs/src/MarkdownText.d.ts +127 -0
  168. package/lib/typescript/commonjs/src/MarkdownText.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/src/MarkdownText.web.d.ts +126 -0
  170. package/lib/typescript/commonjs/src/MarkdownText.web.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts +23 -1
  172. package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts +26 -4
  174. package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts.map +1 -1
  175. package/lib/typescript/commonjs/src/atomUtils.d.ts +58 -0
  176. package/lib/typescript/commonjs/src/atomUtils.d.ts.map +1 -0
  177. package/lib/typescript/commonjs/src/childrenUtils.d.ts +12 -0
  178. package/lib/typescript/commonjs/src/childrenUtils.d.ts.map +1 -0
  179. package/lib/typescript/commonjs/src/commonTypes.d.ts +39 -3
  180. package/lib/typescript/commonjs/src/commonTypes.d.ts.map +1 -1
  181. package/lib/typescript/commonjs/src/index.d.ts +2 -1
  182. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/src/math/environment.d.ts +7 -0
  184. package/lib/typescript/commonjs/src/math/environment.d.ts.map +1 -0
  185. package/lib/typescript/commonjs/src/math/index.d.ts +64 -0
  186. package/lib/typescript/commonjs/src/math/index.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/src/math/mathjax.d.ts +63 -0
  188. package/lib/typescript/commonjs/src/math/mathjax.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/src/metro.d.ts +59 -0
  190. package/lib/typescript/commonjs/src/metro.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/src/parser/index.d.ts +3 -3
  192. package/lib/typescript/commonjs/src/parser/index.d.ts.map +1 -1
  193. package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts.map +1 -1
  194. package/lib/typescript/commonjs/src/rangeUtils.d.ts +1 -1
  195. package/lib/typescript/commonjs/src/stripUtils.d.ts +108 -0
  196. package/lib/typescript/commonjs/src/stripUtils.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/src/styleUtils.d.ts +62 -4
  198. package/lib/typescript/commonjs/src/styleUtils.d.ts.map +1 -1
  199. package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts +32 -4
  200. package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts.map +1 -1
  201. package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts +20 -8
  202. package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts.map +1 -1
  203. package/lib/typescript/commonjs/src/web/utils/elementUtils.d.ts +37 -0
  204. package/lib/typescript/commonjs/src/web/utils/elementUtils.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts +5 -5
  206. package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts.map +1 -1
  207. package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts +6 -1
  208. package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts.map +1 -1
  209. package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts +2 -2
  210. package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts.map +1 -1
  211. package/lib/typescript/module/e2e/links.test.d.ts +2 -0
  212. package/lib/typescript/module/e2e/links.test.d.ts.map +1 -0
  213. package/lib/typescript/module/src/MarcusTextDecoratorViewNativeComponent.d.ts +93 -0
  214. package/lib/typescript/module/src/MarcusTextDecoratorViewNativeComponent.d.ts.map +1 -0
  215. package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +64 -51
  216. package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
  217. package/lib/typescript/module/src/MarkdownText.d.ts +127 -0
  218. package/lib/typescript/module/src/MarkdownText.d.ts.map +1 -0
  219. package/lib/typescript/module/src/MarkdownText.web.d.ts +126 -0
  220. package/lib/typescript/module/src/MarkdownText.web.d.ts.map +1 -0
  221. package/lib/typescript/module/src/MarkdownTextInput.d.ts +23 -1
  222. package/lib/typescript/module/src/MarkdownTextInput.d.ts.map +1 -1
  223. package/lib/typescript/module/src/MarkdownTextInput.web.d.ts +26 -4
  224. package/lib/typescript/module/src/MarkdownTextInput.web.d.ts.map +1 -1
  225. package/lib/typescript/module/src/atomUtils.d.ts +58 -0
  226. package/lib/typescript/module/src/atomUtils.d.ts.map +1 -0
  227. package/lib/typescript/module/src/childrenUtils.d.ts +12 -0
  228. package/lib/typescript/module/src/childrenUtils.d.ts.map +1 -0
  229. package/lib/typescript/module/src/commonTypes.d.ts +39 -3
  230. package/lib/typescript/module/src/commonTypes.d.ts.map +1 -1
  231. package/lib/typescript/module/src/index.d.ts +2 -1
  232. package/lib/typescript/module/src/index.d.ts.map +1 -1
  233. package/lib/typescript/module/src/math/environment.d.ts +7 -0
  234. package/lib/typescript/module/src/math/environment.d.ts.map +1 -0
  235. package/lib/typescript/module/src/math/index.d.ts +64 -0
  236. package/lib/typescript/module/src/math/index.d.ts.map +1 -0
  237. package/lib/typescript/module/src/math/mathjax.d.ts +63 -0
  238. package/lib/typescript/module/src/math/mathjax.d.ts.map +1 -0
  239. package/lib/typescript/module/src/metro.d.ts +59 -0
  240. package/lib/typescript/module/src/metro.d.ts.map +1 -0
  241. package/lib/typescript/module/src/parser/index.d.ts +3 -3
  242. package/lib/typescript/module/src/parser/index.d.ts.map +1 -1
  243. package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts.map +1 -1
  244. package/lib/typescript/module/src/rangeUtils.d.ts +1 -1
  245. package/lib/typescript/module/src/stripUtils.d.ts +108 -0
  246. package/lib/typescript/module/src/stripUtils.d.ts.map +1 -0
  247. package/lib/typescript/module/src/styleUtils.d.ts +62 -4
  248. package/lib/typescript/module/src/styleUtils.d.ts.map +1 -1
  249. package/lib/typescript/module/src/web/utils/blockLayout.d.ts +32 -4
  250. package/lib/typescript/module/src/web/utils/blockLayout.d.ts.map +1 -1
  251. package/lib/typescript/module/src/web/utils/blockUtils.d.ts +20 -8
  252. package/lib/typescript/module/src/web/utils/blockUtils.d.ts.map +1 -1
  253. package/lib/typescript/module/src/web/utils/elementUtils.d.ts +37 -0
  254. package/lib/typescript/module/src/web/utils/elementUtils.d.ts.map +1 -0
  255. package/lib/typescript/module/src/web/utils/parserUtils.d.ts +5 -5
  256. package/lib/typescript/module/src/web/utils/parserUtils.d.ts.map +1 -1
  257. package/lib/typescript/module/src/web/utils/treeUtils.d.ts +6 -1
  258. package/lib/typescript/module/src/web/utils/treeUtils.d.ts.map +1 -1
  259. package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts +2 -2
  260. package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts.map +1 -1
  261. package/package.json +29 -2
  262. package/react-native.config.js +8 -1
  263. package/src/MarcusTextDecoratorViewNativeComponent.ts +199 -0
  264. package/src/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
  265. package/src/MarkdownText.tsx +472 -0
  266. package/src/MarkdownText.web.tsx +668 -0
  267. package/src/MarkdownTextInput.tsx +42 -38
  268. package/src/MarkdownTextInput.web.tsx +36 -13
  269. package/src/atomUtils.ts +112 -0
  270. package/src/childrenUtils.ts +39 -0
  271. package/src/commonTypes.ts +69 -9
  272. package/src/index.tsx +2 -1
  273. package/src/math/environment.ts +68 -0
  274. package/src/math/index.ts +78 -0
  275. package/src/math/mathjax.ts +604 -0
  276. package/src/metro.ts +238 -0
  277. package/src/parser/index.ts +175 -10
  278. package/src/parser/micromark-extension-mentions.ts +104 -11
  279. package/src/stripUtils.ts +919 -0
  280. package/src/styleUtils.ts +290 -26
  281. package/src/web/MarkdownElements.css +67 -0
  282. package/src/web/MarkdownTextInput.css +9 -7
  283. package/src/web/utils/blockLayout.ts +124 -14
  284. package/src/web/utils/blockUtils.ts +365 -59
  285. package/src/web/utils/elementUtils.ts +87 -0
  286. package/src/web/utils/parserUtils.ts +119 -31
  287. package/src/web/utils/treeUtils.ts +6 -1
  288. package/src/web/utils/webStyleUtils.ts +32 -8
  289. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundColorSpan.kt +0 -6
  290. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBoldSpan.kt +0 -6
  291. package/android/src/main/java/app/getbullet/marcus/spans/MarkdownItalicSpan.kt +0 -6
  292. package/apple/RCTMarcusStyle+Codegen.mm +0 -64
  293. package/apple/RCTMarcusUtils.h +0 -26
  294. package/apple/RCTMarcusUtils.mm +0 -26
@@ -1,16 +1,18 @@
1
1
  import type { HTMLMarkdownElement, MarkdownTextInputElement } from "../../MarkdownTextInput.web"
2
2
  import { addNodeToTree, createRootTreeNode } from "./treeUtils"
3
3
  import type { NodeType, TreeNode } from "./treeUtils"
4
- import type { PartialMarkdownStyle } from "../../styleUtils"
4
+ import type { ResolvedMarkdownStyle } from "../../styleUtils"
5
5
  import { getCurrentCursorPosition, moveCursorToEnd, setCursorPosition } from "./cursorUtils"
6
6
  import {
7
7
  addBlockPrefixGap,
8
8
  addLineLayout,
9
9
  addStyleToBlock,
10
10
  isMultilineMarkdownType,
11
+ setRibbonEdge,
11
12
  } from "./blockUtils"
12
- import { layoutBlocks } from "./blockLayout"
13
- import type { LineLayout } from "./blockLayout"
13
+ import { createMarkdownElement, isBlockLevelType } from "./elementUtils"
14
+ import { layoutBlocks, SHOWN_MARKERS } from "./blockLayout"
15
+ import type { LineLayout, MarkerRendering } from "./blockLayout"
14
16
  import { createTextMeasurer } from "./measureUtils"
15
17
  import type { TextMeasurer } from "./measureUtils"
16
18
  import type { MarkdownRange, MarkdownType } from "../../commonTypes"
@@ -77,7 +79,7 @@ function splitRangeIntoSeparateLines(
77
79
  ) {
78
80
  const mainLineRangeLength = currentLine.start + currentLine.length - range.start
79
81
  // A range starting exactly at the newline has nothing on this line. Pushing the empty portion
80
- // anyway made the builder render an empty span, and an empty span is given a `<br>` to keep the
82
+ // anyway made the builder render an empty element, and an empty one is given a `<br>` to keep the
81
83
  // line height -- a line break in the text that the user never typed.
82
84
  if (mainLineRangeLength > 0) {
83
85
  currentLine.markdownRanges.push({
@@ -164,8 +166,7 @@ function appendNode(
164
166
  }
165
167
 
166
168
  function addBrElement(node: TreeNode) {
167
- const span = document.createElement("span") as HTMLMarkdownElement
168
- span.setAttribute("data-type", "br")
169
+ const span = createMarkdownElement("br")
169
170
  appendValueToElement(span, node, "\n")
170
171
  const spanNode = appendNode(span, node, "br", 1)
171
172
  appendNode(document.createElement("br") as unknown as HTMLMarkdownElement, spanNode, "br", 1)
@@ -176,9 +177,8 @@ function addTextToElement(node: TreeNode, text: string, isMultiline = true) {
176
177
  const lines = text.split("\n")
177
178
  lines.forEach((line, index) => {
178
179
  if (line !== "") {
179
- const span = document.createElement("span") as HTMLMarkdownElement
180
+ const span = createMarkdownElement("text")
180
181
  appendValueToElement(span, node, line)
181
- span.setAttribute("data-type", "text")
182
182
  span.appendChild(document.createTextNode(line))
183
183
  appendNode(span, node, "text", line.length)
184
184
 
@@ -186,7 +186,7 @@ function addTextToElement(node: TreeNode, text: string, isMultiline = true) {
186
186
  if (
187
187
  !isMultiline &&
188
188
  parentType &&
189
- ["pre", "code", "mention-here", "mention-user", "mention-report"].includes(parentType)
189
+ ["pre", "code", "mention"].includes(parentType)
190
190
  ) {
191
191
  // this is a fix to background colors being shifted downwards in a singleline input
192
192
  addStyleToBlock(span, "text", {}, false)
@@ -200,16 +200,34 @@ function addTextToElement(node: TreeNode, text: string, isMultiline = true) {
200
200
  })
201
201
  }
202
202
 
203
+ /**
204
+ * Builds the element one line of the document is rendered into.
205
+ *
206
+ * A line of prose is a paragraph and is built as one. A line carrying a block -- a quote, a list
207
+ * item, a heading, a fenced block -- is not: `<p>` holds phrasing content only, and the elements
208
+ * those types are built as are flow content, so a `<p>` around them would be markup no browser
209
+ * would have parsed and no serializer will round-trip. Such a line gets a `<div>`, which says
210
+ * nothing and is allowed to hold anything -- the elements inside it are where the meaning is.
211
+ *
212
+ * `dir="auto"` makes the line its own bidi paragraph, taking its direction from the first strong
213
+ * character in it. That is what the two native platforms already do -- `NSWritingDirectionNatural`
214
+ * is UIKit's default and `firstStrong` is Android's -- so a quote in Arabic inside an otherwise
215
+ * English document opens its gutter on the right on all three rather than on two of them. It is
216
+ * also what `setRibbonEdge` asks the browser about, since the direction a line resolved to is
217
+ * readable through `:dir()` and not through anything the `direction` property leaves behind.
218
+ */
203
219
  function addParagraph(
204
220
  node: TreeNode,
205
221
  text: string | null,
206
222
  length: number,
207
223
  layout: LineLayout | undefined,
208
- markdownStyle: PartialMarkdownStyle,
224
+ markdownStyle: ResolvedMarkdownStyle,
209
225
  disableInlineStyles = false,
226
+ tag: "p" | "div" = "p",
210
227
  ) {
211
- const p = document.createElement("p")
228
+ const p = document.createElement(tag)
212
229
  p.setAttribute("data-type", "line")
230
+ p.setAttribute("dir", "auto")
213
231
  if (!disableInlineStyles) {
214
232
  addLineLayout(p, layout, markdownStyle)
215
233
  }
@@ -266,7 +284,34 @@ function reportAmbiguousNesting(ranges: MarkdownRange[]) {
266
284
  }
267
285
 
268
286
  /**
269
- * Builds one `<p data-type="line">` under `rootNode`.
287
+ * The heading level this range is, or 0 if it is one of the nested copies inside one.
288
+ *
289
+ * A heading arrives as one range per level -- `ungroupRanges` expands `depth` into the nesting the
290
+ * `em` sizing compounds down -- so the level is how many of them there are, and only the outermost
291
+ * can be the `<hN>`. The copies are identical objects, and a stable sort leaves them adjacent, so
292
+ * counting the ones still to come is counting the levels.
293
+ */
294
+ function headingLevel(parent: TreeNode, range: MarkdownRange, remaining: MarkdownRange[]) {
295
+ for (let node: TreeNode | null = parent; node !== null; node = node.parentNode) {
296
+ if (node.type === "heading") {
297
+ return 0
298
+ }
299
+ }
300
+
301
+ let level = 1
302
+ while (
303
+ remaining[level - 1]?.type === "heading" &&
304
+ remaining[level - 1]?.start === range.start &&
305
+ remaining[level - 1]?.length === range.length
306
+ ) {
307
+ level += 1
308
+ }
309
+
310
+ return level
311
+ }
312
+
313
+ /**
314
+ * Builds one `data-type="line"` element under `rootNode`.
270
315
  *
271
316
  * Lines are independent: nothing carries across from the previous one, which is what lets an update
272
317
  * rebuild a single line and leave the rest of the document alone.
@@ -277,11 +322,12 @@ function addLine(
277
322
  textLength: number,
278
323
  hasRanges: boolean,
279
324
  isMultiline: boolean,
280
- markdownStyle: PartialMarkdownStyle,
325
+ markdownStyle: ResolvedMarkdownStyle,
281
326
  disableInlineStyles: boolean,
327
+ rendering: MarkerRendering,
282
328
  ) {
283
329
  if (!hasRanges) {
284
- return addParagraph(
330
+ const plainNode = addParagraph(
285
331
  rootNode,
286
332
  line.text,
287
333
  line.length,
@@ -289,8 +335,15 @@ function addLine(
289
335
  markdownStyle,
290
336
  disableInlineStyles,
291
337
  )
338
+
339
+ if (!disableInlineStyles) {
340
+ setRibbonEdge(plainNode.element, line.layout)
341
+ }
342
+
343
+ return plainNode
292
344
  }
293
345
 
346
+ const tag = line.markdownRanges.some((range) => isBlockLevelType(range.type)) ? "div" : "p"
294
347
  const lineNode = addParagraph(
295
348
  rootNode,
296
349
  null,
@@ -298,6 +351,7 @@ function addLine(
298
351
  line.layout,
299
352
  markdownStyle,
300
353
  disableInlineStyles,
354
+ tag,
301
355
  )
302
356
  let currentParentNode: TreeNode = lineNode
303
357
 
@@ -330,34 +384,57 @@ function addLine(
330
384
  addTextToElement(currentParentNode, textBeforeRange, isMultiline)
331
385
  }
332
386
 
333
- // create markdown span element
334
- const span = document.createElement("span") as HTMLMarkdownElement
335
- span.setAttribute("data-type", range.type)
387
+ // create the markdown element
388
+ const element = createMarkdownElement(
389
+ range.type,
390
+ range.type === "heading" ? headingLevel(currentParentNode, range, lineMarkdownRanges) : 0,
391
+ )
336
392
 
337
- const spanNode = appendNode(span, currentParentNode, range.type, range.length, range.start)
393
+ const rangeNode = appendNode(element, currentParentNode, range.type, range.length, range.start)
338
394
 
339
395
  // Styled once it is in the tree, not before: a heading's size depends on how many heading
340
396
  // levels enclose it, and an element with no parent looks like the outermost one.
341
397
  if (!disableInlineStyles) {
342
- addStyleToBlock(span, range.type, markdownStyle, isMultiline)
398
+ addStyleToBlock(element, range.type, markdownStyle, isMultiline, rendering)
343
399
  if (range.type === "block-prefix") {
344
- addBlockPrefixGap(span, line.layout?.gaps.get(range.start))
400
+ addBlockPrefixGap(element, line.layout?.gaps.get(range.start))
345
401
  }
346
402
  }
347
403
 
404
+ // A list container may hold nothing but items, so everything it contains goes into one. The
405
+ // item covers exactly what the container does -- a line of a list is an item of it -- and from
406
+ // here on it is what the walk fills and unwinds through.
407
+ const contentNode =
408
+ range.type === "list-ordered" || range.type === "list-unordered"
409
+ ? appendNode(
410
+ createMarkdownElement("list-item"),
411
+ rangeNode,
412
+ "list-item",
413
+ range.length,
414
+ range.start,
415
+ )
416
+ : rangeNode
417
+
348
418
  if (
349
419
  lineMarkdownRanges.length > 0 &&
350
420
  nextRangeStartIndex < endOfCurrentRange &&
351
421
  range.type !== "syntax"
352
422
  ) {
353
423
  // tag nesting
354
- currentParentNode = spanNode
424
+ currentParentNode = contentNode
355
425
  lastRangeEndIndex = range.start
356
426
  } else {
357
427
  // adding markdown tag
358
- addTextToElement(spanNode, line.text.substring(range.start - line.start, endOfCurrentRange - line.start), isMultiline)
428
+ addTextToElement(
429
+ contentNode,
430
+ line.text.substring(range.start - line.start, endOfCurrentRange - line.start),
431
+ isMultiline,
432
+ )
433
+ if (contentNode !== rangeNode) {
434
+ rangeNode.element.value = contentNode.element.value
435
+ }
359
436
  currentParentNode.element.value =
360
- (currentParentNode.element.value || "") + (spanNode.element.value || "")
437
+ (currentParentNode.element.value || "") + (rangeNode.element.value || "")
361
438
  lastRangeEndIndex = endOfCurrentRange
362
439
  // tag unnesting and adding text after the tag
363
440
  while (
@@ -392,6 +469,12 @@ function addLine(
392
469
  }
393
470
  }
394
471
 
472
+ // Last, once the line holds all its text: a line's own direction is read from what is in it, and
473
+ // it is what says which edge a quote's ribbons hang from.
474
+ if (!disableInlineStyles) {
475
+ setRibbonEdge(lineNode.element, line.layout)
476
+ }
477
+
395
478
  return lineNode
396
479
  }
397
480
 
@@ -399,8 +482,9 @@ function addLine(
399
482
  function prepareLines(
400
483
  text: string,
401
484
  ranges: MarkdownRange[],
402
- markdownStyle: PartialMarkdownStyle,
485
+ markdownStyle: ResolvedMarkdownStyle,
403
486
  measure: TextMeasurer,
487
+ rendering: MarkerRendering = SHOWN_MARKERS,
404
488
  ) {
405
489
  const lines = splitTextIntoLines(text)
406
490
 
@@ -411,7 +495,7 @@ function prepareLines(
411
495
  // Before anything reorders them: the block walk reads the ranges in the order the parser emits
412
496
  // them -- each marker immediately before the container it belongs to -- and `sortRanges` sorts
413
497
  // that order away in place.
414
- const layouts = layoutBlocks(text, ranges, markdownStyle, measure)
498
+ const layouts = layoutBlocks(text, ranges, markdownStyle, measure, rendering)
415
499
 
416
500
  // Sort all ranges by start position, length, and by tag hierarchy so the styles and text are applied in correct order
417
501
  const sortedRanges = sortRanges(ranges)
@@ -441,9 +525,10 @@ function parseRangesToHTMLNodes(
441
525
  text: string,
442
526
  ranges: MarkdownRange[],
443
527
  isMultiline = true,
444
- markdownStyle: PartialMarkdownStyle = {},
528
+ markdownStyle: ResolvedMarkdownStyle = {},
445
529
  disableInlineStyles = false,
446
530
  measure: TextMeasurer = createTextMeasurer(null),
531
+ rendering: MarkerRendering = SHOWN_MARKERS,
447
532
  ) {
448
533
  const rootElement: HTMLMarkdownElement = document.createElement("span") as HTMLMarkdownElement
449
534
  const textLength = text.length
@@ -452,7 +537,7 @@ function parseRangesToHTMLNodes(
452
537
  // Built line by line, exactly as an update builds the lines it has to replace, so the two agree
453
538
  // by construction and each line sits at the offset the text gives it rather than at wherever the
454
539
  // line before it happened to end.
455
- prepareLines(text, ranges, markdownStyle, measure).forEach((line, index) => {
540
+ prepareLines(text, ranges, markdownStyle, measure, rendering).forEach((line, index) => {
456
541
  const node = buildLine(
457
542
  line,
458
543
  index,
@@ -461,6 +546,7 @@ function parseRangesToHTMLNodes(
461
546
  isMultiline,
462
547
  markdownStyle,
463
548
  disableInlineStyles,
549
+ rendering,
464
550
  )
465
551
  node.parentNode = rootNode
466
552
  rootNode.childNodes.push(node)
@@ -480,7 +566,7 @@ type CachedLine = {
480
566
  }
481
567
 
482
568
  type LineCache = {
483
- markdownStyle: PartialMarkdownStyle
569
+ markdownStyle: ResolvedMarkdownStyle
484
570
  isMultiline: boolean
485
571
  lines: CachedLine[]
486
572
  }
@@ -563,8 +649,9 @@ function buildLine(
563
649
  textLength: number,
564
650
  hasRanges: boolean,
565
651
  isMultiline: boolean,
566
- markdownStyle: PartialMarkdownStyle,
652
+ markdownStyle: ResolvedMarkdownStyle,
567
653
  disableInlineStyles = false,
654
+ rendering: MarkerRendering = SHOWN_MARKERS,
568
655
  ) {
569
656
  // The scratch root carries the line's offset, so the subtree comes out with the absolute `start`
570
657
  // values the builder compares against range offsets -- the same ones it would get if the whole
@@ -582,6 +669,7 @@ function buildLine(
582
669
  isMultiline,
583
670
  markdownStyle,
584
671
  disableInlineStyles,
672
+ rendering,
585
673
  )
586
674
 
587
675
  coverChildren(node)
@@ -628,7 +716,7 @@ function reconcileLines(
628
716
  textLength: number,
629
717
  hasRanges: boolean,
630
718
  isMultiline: boolean,
631
- markdownStyle: PartialMarkdownStyle,
719
+ markdownStyle: ResolvedMarkdownStyle,
632
720
  shouldForceDOMUpdate: boolean,
633
721
  ) {
634
722
  const signatures = lines.map((line) => signatureOf(line, hasRanges))
@@ -755,7 +843,7 @@ function updateInputStructure(
755
843
  text: string,
756
844
  cursorPositionIndex: number | null,
757
845
  isMultiline = true,
758
- markdownStyle: PartialMarkdownStyle = {},
846
+ markdownStyle: ResolvedMarkdownStyle = {},
759
847
  alwaysMoveCursorToTheEnd = false,
760
848
  shouldForceDOMUpdate = false,
761
849
  shouldScrollIntoView = false,
@@ -1,7 +1,12 @@
1
1
  import type { HTMLMarkdownElement } from "../../MarkdownTextInput.web"
2
2
  import type { MarkdownRange, MarkdownType } from "../../commonTypes"
3
3
 
4
- type NodeType = MarkdownType | "line" | "text" | "br" | "root"
4
+ /**
5
+ * `list-item` is the one node with no range behind it: `<ul>` and `<ol>` may hold nothing but
6
+ * `<li>`, so the builder puts one inside each list container and everything the container holds
7
+ * goes in there. It covers exactly what its container does.
8
+ */
9
+ type NodeType = MarkdownType | "line" | "text" | "br" | "root" | "list-item"
5
10
 
6
11
  type TreeNode = Omit<MarkdownRange, "type"> & {
7
12
  element: HTMLMarkdownElement
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import type { TextStyle } from "react-native"
3
3
  import type { MarkdownStyle } from "../../MarcusTextInputDecoratorViewNativeComponent"
4
+ import type { PartialMarkdownStyle, ResolvedMarkdownStyle } from "../../styleUtils"
4
5
  import { mergeMarkdownStyleWithDefault } from "../../styleUtils"
5
6
 
6
7
  let createReactDOMStyle: (style: any) => any
@@ -36,20 +37,43 @@ try {
36
37
  )
37
38
  }
38
39
 
39
- function processUnitsInMarkdownStyle(input: MarkdownStyle): MarkdownStyle {
40
+ // The three shadow properties are left as they were written. An offset is an object rather than a
41
+ // length, and a radius that carried its unit here could not be composed with an offset that did
42
+ // not: `blockUtils` builds the one `text-shadow` declaration out of all three instead.
43
+ const RAW_PROPS = new Set(["textShadowOffset", "textShadowRadius"])
44
+
45
+ /**
46
+ * Gives every length in the style its CSS unit.
47
+ *
48
+ * Walks the whole tree rather than its top two levels, because a list's `marker` puts style values
49
+ * one level further down than the entries around it.
50
+ */
51
+ function processUnitsInMarkdownStyle(input: MarkdownStyle): ResolvedMarkdownStyle {
40
52
  const output = JSON.parse(JSON.stringify(input))
41
53
 
42
- Object.keys(output).forEach((key) => {
43
- const obj = output[key]
44
- Object.keys(obj).forEach((prop) => {
45
- obj[prop] = dangerousStyleValue(prop, obj[prop], false)
54
+ const walk = (node: any) => {
55
+ Object.keys(node).forEach((prop) => {
56
+ const value = node[prop]
57
+
58
+ if (RAW_PROPS.has(prop)) {
59
+ return
60
+ }
61
+
62
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
63
+ walk(value)
64
+ return
65
+ }
66
+
67
+ node[prop] = dangerousStyleValue(prop, value, false)
46
68
  })
47
- })
69
+ }
70
+
71
+ walk(output)
48
72
 
49
- return output as MarkdownStyle
73
+ return output as ResolvedMarkdownStyle
50
74
  }
51
75
 
52
- function processMarkdownStyle(input: MarkdownStyle | undefined): MarkdownStyle {
76
+ function processMarkdownStyle(input: PartialMarkdownStyle | undefined): ResolvedMarkdownStyle {
53
77
  return processUnitsInMarkdownStyle(mergeMarkdownStyleWithDefault(input))
54
78
  }
55
79
 
@@ -1,6 +0,0 @@
1
- package app.getbullet.marcus.spans
2
-
3
- import android.text.style.BackgroundColorSpan
4
- import androidx.annotation.ColorInt
5
-
6
- class MarkdownBackgroundColorSpan(@ColorInt color: Int) : BackgroundColorSpan(color), MarkdownSpan
@@ -1,6 +0,0 @@
1
- package app.getbullet.marcus.spans
2
-
3
- import android.graphics.Typeface
4
- import android.text.style.StyleSpan
5
-
6
- class MarkdownBoldSpan : StyleSpan(Typeface.BOLD), MarkdownSpan
@@ -1,6 +0,0 @@
1
- package app.getbullet.marcus.spans
2
-
3
- import android.graphics.Typeface
4
- import android.text.style.StyleSpan
5
-
6
- class MarkdownItalicSpan : StyleSpan(Typeface.ITALIC), MarkdownSpan
@@ -1,64 +0,0 @@
1
- #import <RNMarcus/RCTMarcusStyle+Codegen.h>
2
-
3
- #import <React/RCTConversions.h>
4
-
5
- @implementation RCTMarcusStyle (Codegen)
6
-
7
- - (instancetype)initWithStruct:
8
- (const facebook::react::MarcusTextInputDecoratorViewMarkdownStyleStruct &)style {
9
- if (self = [super init]) {
10
- self.syntaxColor = RCTUIColorFromSharedColor(style.syntax.color);
11
-
12
- self.linkColor = RCTUIColorFromSharedColor(style.link.color);
13
-
14
- self.headingFontSize = style.heading.fontSize;
15
- self.headingScale = style.heading.scale;
16
-
17
- self.emojiFontSize = style.emoji.fontSize;
18
- self.emojiFontFamily = RCTNSStringFromString(style.emoji.fontFamily);
19
-
20
- self.blockquoteBorderColor =
21
- RCTUIColorFromSharedColor(style.blockquote.borderColor);
22
- self.blockquoteBorderWidth = style.blockquote.borderWidth;
23
- self.blockquoteMarginLeft = style.blockquote.marginLeft;
24
- self.blockquotePaddingLeft = style.blockquote.paddingLeft;
25
-
26
- self.orderedListMarginLeft = style.orderedList.marginLeft;
27
- self.orderedListPaddingLeft = style.orderedList.paddingLeft;
28
-
29
- self.unorderedListMarginLeft = style.unorderedList.marginLeft;
30
- self.unorderedListPaddingLeft = style.unorderedList.paddingLeft;
31
-
32
- self.codeFontFamily = RCTNSStringFromString(style.code.fontFamily);
33
- self.codeFontSize = style.code.fontSize;
34
- self.codeColor = RCTUIColorFromSharedColor(style.code.color);
35
- self.codeBackgroundColor =
36
- RCTUIColorFromSharedColor(style.code.backgroundColor);
37
-
38
- self.preFontFamily = RCTNSStringFromString(style.pre.fontFamily);
39
- self.preFontSize = style.pre.fontSize;
40
- self.preColor = RCTUIColorFromSharedColor(style.pre.color);
41
- self.preBackgroundColor =
42
- RCTUIColorFromSharedColor(style.pre.backgroundColor);
43
-
44
- self.mentionHereColor = RCTUIColorFromSharedColor(style.mentionHere.color);
45
- self.mentionHereBackgroundColor =
46
- RCTUIColorFromSharedColor(style.mentionHere.backgroundColor);
47
- self.mentionHereBorderRadius = style.mentionHere.borderRadius;
48
-
49
- self.mentionUserColor = RCTUIColorFromSharedColor(style.mentionUser.color);
50
- self.mentionUserBackgroundColor =
51
- RCTUIColorFromSharedColor(style.mentionUser.backgroundColor);
52
- self.mentionUserBorderRadius = style.mentionUser.borderRadius;
53
-
54
- self.mentionReportColor =
55
- RCTUIColorFromSharedColor(style.mentionReport.color);
56
- self.mentionReportBackgroundColor =
57
- RCTUIColorFromSharedColor(style.mentionReport.backgroundColor);
58
- self.mentionReportBorderRadius = style.mentionReport.borderRadius;
59
- }
60
-
61
- return self;
62
- }
63
-
64
- @end
@@ -1,26 +0,0 @@
1
- #import <RNMarcus/RCTMarcusStyle.h>
2
- #import <UIKit/UIKit.h>
3
-
4
- NS_ASSUME_NONNULL_BEGIN
5
-
6
- // Parses and formats in one step for the view layer.
7
- //
8
- // Parsing is stateful (it owns the parser's memo cache) so it stays here rather
9
- // than moving to Swift; formatting itself is a stateless Swift call. One
10
- // instance is owned per text input and only ever touched on the main thread.
11
- @interface RCTMarcusUtils : NSObject
12
-
13
- // Nullable: both are assigned after init (props arrive after the view
14
- // hierarchy is built), and applyMarkdownFormatting: bails out when either is
15
- // still nil.
16
- @property(nonatomic, nullable) RCTMarcusStyle *markdownStyle;
17
- @property(nonatomic, nullable) NSNumber *parserId;
18
-
19
- - (void)applyMarkdownFormatting:
20
- (nonnull NSMutableAttributedString *)attributedString
21
- withDefaultTextAttributes:
22
- (nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes;
23
-
24
- @end
25
-
26
- NS_ASSUME_NONNULL_END
@@ -1,26 +0,0 @@
1
- #import <RNMarcus/MarkdownSwiftInterop.h>
2
- #import <RNMarcus/RCTMarcusUtils.h>
3
-
4
- @implementation RCTMarcusUtils
5
-
6
- - (void)applyMarkdownFormatting:
7
- (nonnull NSMutableAttributedString *)attributedString
8
- withDefaultTextAttributes:
9
- (nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes {
10
- // `markdownStyle` and `parserId` may not be set yet: props are applied after
11
- // the view hierarchy is built.
12
- if (_markdownStyle == nil || _parserId == nil) {
13
- return;
14
- }
15
-
16
- NSArray<MarcusRange *> *markdownRanges =
17
- [[MarkdownParser sharedParser] parse:attributedString.string
18
- withParserId:_parserId];
19
-
20
- [MarkdownFormatter formatAttributedString:attributedString
21
- defaultTextAttributes:defaultTextAttributes
22
- ranges:markdownRanges
23
- style:_markdownStyle];
24
- }
25
-
26
- @end