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
@@ -0,0 +1,743 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.OBJECT_REPLACEMENT = void 0;
7
+ exports.stripSyntax = stripSyntax;
8
+ // Removing the markdown syntax from the string before it reaches the platform
9
+ // is what separates the display component from the input one: the input shows
10
+ // what you typed, the display shows what it meant. Everything downstream --
11
+ // measurement, drawing, selection, VoiceOver -- then sees only the text that is
12
+ // meant to be read, without any of the hiding tricks that a formatter would
13
+ // otherwise have to play on characters that are still there.
14
+ //
15
+ // The parser's offsets are into the original string, so cutting characters out
16
+ // invalidates every range it emitted. Both halves happen here, in one pass, so
17
+ // there is never a moment where a range and the string it indexes disagree.
18
+
19
+ /** What an image stood for, for a caller that has something to show instead. */
20
+
21
+ /** A maths span, for a caller that has something to draw it with. */
22
+
23
+ /** A link the display can hand to whatever is going to act on a press. */
24
+
25
+ /**
26
+ * The character standing in for an embed, matching what the platforms use for
27
+ * an attachment so that the stripped text and the string that reaches the
28
+ * formatters are the same length.
29
+ */
30
+ const OBJECT_REPLACEMENT = exports.OBJECT_REPLACEMENT = "\uFFFC";
31
+
32
+ /** Shared so that the common case of a document with no embeds allocates nothing. */
33
+ const NO_EMBEDS = [];
34
+
35
+ /** Shared for the same reason. */
36
+ const NO_MATHS = [];
37
+
38
+ /** Shared for the same reason. */
39
+ const NO_LINKS = [];
40
+ const TAB = 9;
41
+ const LINE_FEED = 10;
42
+ const CARRIAGE_RETURN = 13;
43
+ const SPACE = 32;
44
+ const GREATER_THAN = 62;
45
+ const LEFT_PAREN = 40;
46
+ const RIGHT_PAREN = 41;
47
+ function isBlank(code) {
48
+ return code === SPACE || code === TAB;
49
+ }
50
+ function isLineBreak(code) {
51
+ return code === LINE_FEED || code === CARRIAGE_RETURN;
52
+ }
53
+
54
+ /**
55
+ * Spans of the block markers that survive stripping, in original offsets.
56
+ *
57
+ * A list's marker is the only syntax that carries meaning of its own -- `1.`
58
+ * numbers the item and `-` stands in for a bullet -- so it stays in the string
59
+ * and is laid out the way the input lays it out. A blockquote's `>` says
60
+ * nothing the ribbon beside it does not already say, so it goes.
61
+ *
62
+ * `flushLine` emits a `block-prefix` immediately before the container that owns
63
+ * it, which is the same pairing the native formatters read, so the container is
64
+ * simply the range that follows.
65
+ */
66
+ function listMarkers(ranges) {
67
+ const markers = [];
68
+ for (let i = 0; i < ranges.length; i++) {
69
+ const range = ranges[i];
70
+ if (range.type !== "block-prefix") {
71
+ continue;
72
+ }
73
+ const container = ranges[i + 1];
74
+ if (container && (container.type === "list-ordered" || container.type === "list-unordered")) {
75
+ markers.push({
76
+ start: range.start,
77
+ end: range.start + range.length
78
+ });
79
+ }
80
+ }
81
+ return markers;
82
+ }
83
+
84
+ /**
85
+ * Whether a syntax range is a quote marker sitting inside a list's prefix.
86
+ *
87
+ * A prefix is measured from wherever the previous container's marker ended, so
88
+ * the ordered list in `- > 1. ` is handed the whole run `> 1. ` -- quote marker
89
+ * included. Containment alone would therefore keep a `>` that belongs to
90
+ * something else, and `>` is the only block marker that can appear there.
91
+ */
92
+ function isQuoteMarker(text, start, end) {
93
+ for (let i = start; i < end; i++) {
94
+ if (text.charCodeAt(i) !== GREATER_THAN) {
95
+ return false;
96
+ }
97
+ }
98
+ return true;
99
+ }
100
+
101
+ /** The `( ... )` an inline link or image carries, and what it carries in it. */
102
+
103
+ /**
104
+ * The resources in `text`, in the order they are written.
105
+ *
106
+ * The parser reports the brackets and parentheses as syntax but the destination
107
+ * itself as a `link`, which is right for an input -- the URL is text you can
108
+ * edit -- and wrong for a display, where cutting only the punctuation out of
109
+ * `[text](url)` leaves `texturl`. So the whole run between the markers goes,
110
+ * and reading it on the way past is what leaves something to hand a press
111
+ * handler afterwards.
112
+ *
113
+ * `(` is emitted as syntax only by `resourceMarker`, so there is nothing else
114
+ * this can match, and one resource cannot hold another: the inner parentheses
115
+ * of `[a](b(c))` are part of the destination rather than markers of their own.
116
+ * Reference links and their definitions are not covered: their label is
117
+ * punctuation around prose the way emphasis is, and telling `[text]` a
118
+ * reference from `[text]` a label needs more than the ranges carry.
119
+ */
120
+ function resourceSpans(text, ranges) {
121
+ const spans = [];
122
+ let current = null;
123
+ for (const range of ranges) {
124
+ if (range.type === "syntax" && range.length === 1) {
125
+ const code = text.charCodeAt(range.start);
126
+ if (code === LEFT_PAREN) {
127
+ current = {
128
+ open: range.start,
129
+ close: -1,
130
+ uri: "",
131
+ title: ""
132
+ };
133
+ } else if (code === RIGHT_PAREN && current !== null) {
134
+ current.close = range.start;
135
+ spans.push(current);
136
+ current = null;
137
+ }
138
+ continue;
139
+ }
140
+
141
+ // A destination and a title are emitted between the two markers, so
142
+ // whichever resource is open is the one they belong to. Anything else that
143
+ // arrives in between -- a container flushed at a line break inside a title
144
+ // -- is neither and is passed over.
145
+ if (current === null) {
146
+ continue;
147
+ }
148
+ if (range.type === "link") {
149
+ current.uri = text.slice(range.start, range.start + range.length);
150
+ } else if (range.type === "title") {
151
+ current.title = text.slice(range.start, range.start + range.length);
152
+ }
153
+ }
154
+ return spans;
155
+ }
156
+
157
+ /** Marks every resource for removal, markers and all. */
158
+ function cutResources(resources, cut) {
159
+ let cutSomething = false;
160
+ for (const resource of resources) {
161
+ for (let i = resource.open; i <= resource.close; i++) {
162
+ cut[i] = 1;
163
+ cutSomething = true;
164
+ }
165
+ }
166
+ return cutSomething;
167
+ }
168
+
169
+ /**
170
+ * Whether anything but block markers shares a line with the character at
171
+ * `index`.
172
+ *
173
+ * Read off the stripped text, which is the text that will be laid out: by this
174
+ * point a quote's marker is gone entirely and a list's is a `block-prefix`
175
+ * range over characters that were kept to be laid out rather than read.
176
+ */
177
+ function sharesItsLine(text, prefixes, index) {
178
+ let start = index;
179
+ while (start > 0 && !isLineBreak(text.charCodeAt(start - 1))) {
180
+ start--;
181
+ }
182
+ let end = index;
183
+ while (end < text.length && !isLineBreak(text.charCodeAt(end))) {
184
+ end++;
185
+ }
186
+ for (let i = start; i < end; i++) {
187
+ if (i === index || isBlank(text.charCodeAt(i))) {
188
+ continue;
189
+ }
190
+ if (prefixes.some(prefix => i >= prefix.start && i < prefix.start + prefix.length)) {
191
+ continue;
192
+ }
193
+ return true;
194
+ }
195
+ return false;
196
+ }
197
+
198
+ /** The characters of a span that survive the cut, which is CommonMark's `alt`. */
199
+ function flatten(text, cut, start, end) {
200
+ let flattened = "";
201
+ let segmentStart = start;
202
+ for (let i = start; i < end; i++) {
203
+ if (cut[i] === 1) {
204
+ if (segmentStart < i) {
205
+ flattened += text.slice(segmentStart, i);
206
+ }
207
+ segmentStart = i + 1;
208
+ }
209
+ }
210
+ return segmentStart < end ? flattened + text.slice(segmentStart, end) : flattened;
211
+ }
212
+ /** Shared for the same reason `NO_EMBEDS` is. */
213
+ const NO_IMAGES = [];
214
+
215
+ /**
216
+ * The images in `text`, with the three things a renderer needs to show one.
217
+ *
218
+ * Read straight off the ranges, because the parser has already made an image
219
+ * flat: inside a label it emits nothing but the `syntax` the markup is spelled
220
+ * with and one `alt` range over the lot. So there is exactly one `link`
221
+ * range in a span -- the destination -- and no image nested in another, and
222
+ * neither case needs guarding here.
223
+ *
224
+ * `alt` still has to be flattened, since a single range cannot skip the `**` in
225
+ * `![**a**](b)`. `cut` is what does it: it already marks every character the
226
+ * strip is removing, so reading the label through it gives exactly the string
227
+ * CommonMark would have put in the attribute.
228
+ */
229
+ function imageSpans(text, ranges, cut) {
230
+ const spans = [];
231
+ for (let i = 0; i < ranges.length; i++) {
232
+ const image = ranges[i];
233
+ if (image.type !== "image") {
234
+ continue;
235
+ }
236
+ const start = image.start;
237
+ const end = Math.min(start + image.length, text.length);
238
+ const span = {
239
+ start,
240
+ end,
241
+ uri: "",
242
+ alt: "",
243
+ title: ""
244
+ };
245
+ for (let j = i + 1; j < ranges.length; j++) {
246
+ const inner = ranges[j];
247
+ const innerEnd = inner.start + inner.length;
248
+
249
+ // Ranges are not sorted -- a container is emitted after the content of
250
+ // the line it encloses -- so anything reaching past the image is one of
251
+ // those and is skipped rather than ending the walk.
252
+ if (inner.start >= end) {
253
+ break;
254
+ }
255
+ if (innerEnd > end) {
256
+ continue;
257
+ }
258
+ if (inner.type === "alt") {
259
+ span.alt = flatten(text, cut, inner.start, innerEnd);
260
+ } else if (inner.type === "link") {
261
+ span.uri = text.slice(inner.start, innerEnd);
262
+ } else if (inner.type === "title") {
263
+ span.title = text.slice(inner.start, innerEnd);
264
+ }
265
+ }
266
+ spans.push(span);
267
+ }
268
+ return spans;
269
+ }
270
+
271
+ /**
272
+ * The bounds of every maths span, whether or not the caller means to render one.
273
+ *
274
+ * A display with nothing to draw maths with keeps `$x^2$` exactly as it was
275
+ * written: cutting only the dollars would leave `x^2`, which is neither the
276
+ * markdown nor the maths, and TeX read as prose is worse than TeX read as TeX.
277
+ * So the delimiters inside these bounds are spared the syntax cut.
278
+ */
279
+ function mathBounds(ranges) {
280
+ const bounds = [];
281
+ for (const range of ranges) {
282
+ if (range.type === "math" || range.type === "math-block") {
283
+ bounds.push({
284
+ start: range.start,
285
+ end: range.start + range.length
286
+ });
287
+ }
288
+ }
289
+ return bounds;
290
+ }
291
+
292
+ /** A maths span as the strip sees it, before the offsets move. */
293
+
294
+ /** Shared for the same reason `NO_EMBEDS` is. */
295
+ const NO_MATH_SPANS = [];
296
+
297
+ /**
298
+ * The maths spans in `text`, with the TeX each one carries.
299
+ *
300
+ * Nothing has to be walked for the content: the parser makes a maths span
301
+ * opaque -- one range over the lot and `syntax` over the delimiters, and
302
+ * nothing at all for what is between them -- so the TeX is simply the
303
+ * characters the strip is not already removing. `cut` is what says which those
304
+ * are, which is why this runs at the same moment `imageSpans` does: after the
305
+ * syntax has been marked and before the spans themselves are.
306
+ *
307
+ * A `$$` block is trimmed because its delimiters sit on lines of their own, so
308
+ * what survives between them opens and closes with a line break.
309
+ */
310
+ function mathSpans(text, ranges, cut) {
311
+ const spans = [];
312
+ for (const range of ranges) {
313
+ if (range.type !== "math" && range.type !== "math-block") {
314
+ continue;
315
+ }
316
+ const start = range.start;
317
+ const end = Math.min(start + range.length, text.length);
318
+ const tex = flatten(text, cut, start, end).trim();
319
+
320
+ // `$$` with nothing in it is punctuation, not maths. Left as it was
321
+ // written rather than turned into a placeholder standing for nothing.
322
+ if (tex === "") {
323
+ continue;
324
+ }
325
+ spans.push({
326
+ start,
327
+ end,
328
+ tex,
329
+ display: range.type === "math-block"
330
+ });
331
+ }
332
+ return spans;
333
+ }
334
+ /** Shared for the same reason `NO_EMBEDS` is. */
335
+ const NO_LINK_SPANS = [];
336
+
337
+ /**
338
+ * The links in `text`, as the text that will be left of each and where it
339
+ * points.
340
+ *
341
+ * A written link is a label followed immediately by a resource, so the label is
342
+ * the one that opens at `](`. A label with no resource after it is a reference
343
+ * or a shortcut, and nothing here can resolve one: it is still styled as a link
344
+ * -- that much the ranges say -- but there is no destination to press it to.
345
+ *
346
+ * An autolink has no label at all and is its own text, so any `link` left over
347
+ * is one. Left over means outside every resource: the destinations are `link`
348
+ * ranges too, and each has already been taken by the label in front of it or
349
+ * belongs to an image, which has no label to press. The exception is a
350
+ * definition's destination -- `[ref]: https://example.com` -- which is written
351
+ * plainly, is shown as written, and is treated as what it looks like.
352
+ */
353
+ function linkSpans(text, ranges, resources) {
354
+ const spans = [];
355
+ for (const range of ranges) {
356
+ const end = range.start + range.length;
357
+ let span = null;
358
+ if (range.type === "label") {
359
+ const resource = resources.find(candidate => candidate.open === end + 1);
360
+ if (resource !== undefined) {
361
+ span = {
362
+ start: range.start,
363
+ end,
364
+ uri: resource.uri,
365
+ title: resource.title
366
+ };
367
+ }
368
+ } else if (range.type === "link" && !resources.some(resource => range.start > resource.open && range.start < resource.close)) {
369
+ span = {
370
+ start: range.start,
371
+ end,
372
+ uri: text.slice(range.start, end),
373
+ title: ""
374
+ };
375
+ }
376
+ if (span === null) {
377
+ continue;
378
+ }
379
+
380
+ // A link cannot hold another one, but micromark still reports the construct
381
+ // it finds inside a label: `[see <https://x.com>](y)` arrives as a label
382
+ // with an autolink in it. A label is emitted before its own content, so the
383
+ // one that encloses the other is the one already here -- and it is the one
384
+ // to keep, being the whole of what the reader is shown. Two of them would
385
+ // be worse than a wrong choice: the caller splices the text at these, and
386
+ // spans that overlap would splice the run they share in twice.
387
+ if (spans.length > 0 && span.start < spans[spans.length - 1].end) {
388
+ continue;
389
+ }
390
+ spans.push(span);
391
+ }
392
+ return spans;
393
+ }
394
+
395
+ /**
396
+ * The spans as offsets into the stripped text, carrying the label they now
397
+ * cover. `offsets` is null when nothing was cut and the two texts are the same.
398
+ */
399
+ function toLinks(text, spans, offsets) {
400
+ if (spans.length === 0) {
401
+ return NO_LINKS;
402
+ }
403
+ const links = [];
404
+ for (const span of spans) {
405
+ const start = offsets === null ? span.start : offsets[span.start];
406
+ const end = offsets === null ? span.end : offsets[span.end];
407
+
408
+ // A label that was nothing but markup -- `[**](x)` -- has nothing left to
409
+ // press.
410
+ if (end <= start) {
411
+ continue;
412
+ }
413
+ links.push({
414
+ start,
415
+ length: end - start,
416
+ uri: span.uri,
417
+ label: text.slice(start, end),
418
+ title: span.title
419
+ });
420
+ }
421
+ return links;
422
+ }
423
+
424
+ /**
425
+ * A span that collapses to a single placeholder character, of either kind.
426
+ *
427
+ * Images and maths are the same problem -- a run of markdown that the display
428
+ * does not read but draws, and that costs the platform exactly one character --
429
+ * so they go through one set of machinery. Sorting by offset is enough to put
430
+ * them back in emission order: both are emitted from the parser as they are
431
+ * met, and neither can contain the other.
432
+ */
433
+
434
+ /** Shared for the same reason `NO_EMBEDS` is. */
435
+ const NO_ATOMS = [];
436
+ function atomsOf(images, maths) {
437
+ if (images.length === 0) {
438
+ return maths.length === 0 ? NO_ATOMS : maths;
439
+ }
440
+ if (maths.length === 0) {
441
+ return images;
442
+ }
443
+ return [...images, ...maths].sort((a, b) => a.start - b.start);
444
+ }
445
+
446
+ /** Whether a range is one that stands for an atom rather than describing text. */
447
+ function isAtomType(type) {
448
+ return type === "image" || type === "math" || type === "math-block";
449
+ }
450
+
451
+ /**
452
+ * Widens the cuts already marked on a line to cover the whitespace that only
453
+ * existed to separate a marker from what it marked.
454
+ *
455
+ * A line opens with a run of block markers and the blanks between them. Walking
456
+ * that run, a blank goes only if the marker in front of it went: `# Title` and
457
+ * `> - item` lose their spacing, `- item` keeps the one its bullet needs.
458
+ *
459
+ * A line that turns out to be nothing but removed markers takes its own line
460
+ * break with it, so a setext underline or a thematic break does not leave a
461
+ * blank line behind.
462
+ */
463
+ function absorbMarkerSpacing(text, cut, marker) {
464
+ let lineStart = 0;
465
+ while (lineStart <= text.length) {
466
+ let lineEnd = lineStart;
467
+ while (lineEnd < text.length) {
468
+ const code = text.charCodeAt(lineEnd);
469
+ if (code === LINE_FEED || code === CARRIAGE_RETURN) {
470
+ break;
471
+ }
472
+ lineEnd++;
473
+ }
474
+ let cursor = lineStart;
475
+ let cutSomething = false;
476
+ let keptMarker = false;
477
+ let afterCut = false;
478
+ while (cursor < lineEnd) {
479
+ const blank = isBlank(text.charCodeAt(cursor));
480
+ if (cut[cursor] === 1) {
481
+ cutSomething = true;
482
+ afterCut = true;
483
+ } else if (blank) {
484
+ if (afterCut) {
485
+ cut[cursor] = 1;
486
+ }
487
+ } else if (marker[cursor] === 1) {
488
+ keptMarker = true;
489
+ afterCut = false;
490
+ } else {
491
+ break;
492
+ }
493
+ cursor++;
494
+ }
495
+
496
+ // Nothing readable left on the line, and no marker worth keeping either.
497
+ if (cursor >= lineEnd && cutSomething && !keptMarker) {
498
+ for (let i = lineStart; i < lineEnd; i++) {
499
+ cut[i] = 1;
500
+ }
501
+
502
+ // The break in front, for any line but the first, which has none and
503
+ // takes the one behind instead.
504
+ if (lineStart > 0) {
505
+ let index = lineStart - 1;
506
+ if (text.charCodeAt(index) === LINE_FEED) {
507
+ cut[index] = 1;
508
+ index--;
509
+ }
510
+ if (index >= 0 && text.charCodeAt(index) === CARRIAGE_RETURN) {
511
+ cut[index] = 1;
512
+ }
513
+ } else {
514
+ let index = lineEnd;
515
+ if (text.charCodeAt(index) === CARRIAGE_RETURN) {
516
+ cut[index] = 1;
517
+ index++;
518
+ }
519
+ if (text.charCodeAt(index) === LINE_FEED) {
520
+ cut[index] = 1;
521
+ }
522
+ }
523
+ }
524
+ if (lineEnd >= text.length) {
525
+ break;
526
+ }
527
+ lineStart = lineEnd;
528
+ if (text.charCodeAt(lineStart) === CARRIAGE_RETURN) {
529
+ lineStart++;
530
+ }
531
+ if (text.charCodeAt(lineStart) === LINE_FEED) {
532
+ lineStart++;
533
+ }
534
+ }
535
+ }
536
+
537
+ /**
538
+ * What a type means once the markup around it is gone.
539
+ *
540
+ * A link's label is the one type that changes. While it is being edited it is
541
+ * text between two brackets and is left alone; once the brackets have been
542
+ * removed it is the only thing left standing for the link, so it takes the
543
+ * link's styling -- the destination it was pointing at having been removed too.
544
+ */
545
+ function displayType(type) {
546
+ return type === "label" ? "link" : type;
547
+ }
548
+
549
+ /**
550
+ * Removes the markdown syntax from `text` and rewrites `ranges` to index what
551
+ * is left.
552
+ *
553
+ * Ranges are only ever dropped or shortened, never reordered, so the emission
554
+ * order the native formatters depend on survives -- a `block-prefix` still
555
+ * arrives immediately before its container, and a container that lost its
556
+ * marker entirely arrives with none, which is exactly the gutter-without-marker
557
+ * case the block layout already handles.
558
+ */
559
+ function stripSyntax(text, ranges, options = {}) {
560
+ if (text.length === 0 || ranges.length === 0) {
561
+ return {
562
+ text,
563
+ ranges,
564
+ embeds: NO_EMBEDS,
565
+ maths: NO_MATHS,
566
+ links: NO_LINKS
567
+ };
568
+ }
569
+ const markers = listMarkers(ranges);
570
+ // Only when there is nothing to draw maths with: otherwise the spans are cut
571
+ // whole a few lines down and sparing their dollars would be pointless work.
572
+ const spared = options.math ? [] : mathBounds(ranges);
573
+ const cut = new Uint8Array(text.length);
574
+ const kept = new Uint8Array(text.length);
575
+ let cutSomething = false;
576
+ for (const range of ranges) {
577
+ // A fenced block's language is metadata about the block, not part of it, so
578
+ // it goes the same way the fence itself does.
579
+ if (range.type !== "syntax" && range.type !== "language") {
580
+ continue;
581
+ }
582
+ const start = range.start;
583
+ const end = Math.min(start + range.length, text.length);
584
+ if (spared.some(span => start >= span.start && end <= span.end)) {
585
+ continue;
586
+ }
587
+ const inListMarker = range.type === "syntax" && markers.some(marker => start >= marker.start && end <= marker.end) && !isQuoteMarker(text, start, end);
588
+ for (let i = start; i < end; i++) {
589
+ if (inListMarker) {
590
+ kept[i] = 1;
591
+ } else {
592
+ cut[i] = 1;
593
+ cutSomething = true;
594
+ }
595
+ }
596
+ }
597
+ const resources = resourceSpans(text, ranges);
598
+ const links = options.links ? linkSpans(text, ranges, resources) : NO_LINK_SPANS;
599
+ cutSomething = cutResources(resources, cut) || cutSomething;
600
+
601
+ // An image goes whole -- markup, alt text and destination alike -- and leaves
602
+ // one character behind. Keeping one of its own characters rather than
603
+ // splicing a new one in is what lets the offsets below stay as they are: a
604
+ // range is still only ever shortened, never moved.
605
+ // After the cuts above and before the images are cut themselves, which is the
606
+ // one moment `cut` describes the markup inside a label without describing the
607
+ // label's own removal -- exactly what flattening the alt text needs.
608
+ const images = options.embeds ? imageSpans(text, ranges, cut) : NO_IMAGES;
609
+ const maths = options.math ? mathSpans(text, ranges, cut) : NO_MATH_SPANS;
610
+ const atoms = atomsOf(images, maths);
611
+ const placeholder = atoms.length > 0 ? new Uint8Array(text.length) : null;
612
+ for (const atom of atoms) {
613
+ for (let i = atom.start; i < atom.end; i++) {
614
+ cut[i] = 1;
615
+ // 1 for a character the atom swallowed, 2 for the one it left behind.
616
+ placeholder[i] = 1;
617
+ }
618
+ cut[atom.start] = 0;
619
+ placeholder[atom.start] = 2;
620
+ cutSomething = true;
621
+ }
622
+ if (!cutSomething) {
623
+ // Nothing moved, so the spans already index the text as it stands. A bare
624
+ // URL gets here: it is a link written with no syntax at all.
625
+ return {
626
+ text,
627
+ ranges,
628
+ embeds: NO_EMBEDS,
629
+ maths: NO_MATHS,
630
+ links: toLinks(text, links, null)
631
+ };
632
+ }
633
+ absorbMarkerSpacing(text, cut, kept);
634
+
635
+ // Kept characters before each offset, which is where that offset lands once
636
+ // the cuts are gone. One extra entry so a range's end can be mapped the same
637
+ // way as its start.
638
+ const offsets = new Int32Array(text.length + 1);
639
+ let stripped = "";
640
+ let segmentStart = 0;
641
+ let survivors = 0;
642
+ for (let i = 0; i < text.length; i++) {
643
+ offsets[i] = survivors;
644
+ if (placeholder !== null && placeholder[i] === 2) {
645
+ if (segmentStart < i) {
646
+ stripped += text.slice(segmentStart, i);
647
+ }
648
+ stripped += OBJECT_REPLACEMENT;
649
+ segmentStart = i + 1;
650
+ survivors++;
651
+ } else if (cut[i] === 1) {
652
+ if (segmentStart < i) {
653
+ stripped += text.slice(segmentStart, i);
654
+ }
655
+ segmentStart = i + 1;
656
+ } else {
657
+ survivors++;
658
+ }
659
+ }
660
+ offsets[text.length] = survivors;
661
+ if (segmentStart < text.length) {
662
+ stripped += text.slice(segmentStart);
663
+ }
664
+ const remapped = [];
665
+ // The atom being walked past, if any: everything it swallowed goes with it,
666
+ // save its own range, which shrinks onto the character left behind. Without
667
+ // this the `syntax` over the `!` of an image or the opening `$` of a maths
668
+ // span -- the very character kept as the placeholder -- would survive to
669
+ // style what stands there as markup.
670
+ //
671
+ // Swallowed means emitted after the atom opened and ending inside it, which
672
+ // is what tells the alt text apart from the two kinds of range that reach
673
+ // over an atom and have to survive: the label of a link written around an
674
+ // image, which is emitted before it, and the container of the line it sits
675
+ // on, which is emitted after and runs past its end.
676
+ let atom = 0;
677
+ let insideStart = -1;
678
+ let insideEnd = -1;
679
+ for (const range of ranges) {
680
+ // One span per atom range, in the order they were emitted, so the two walks
681
+ // stay in step. Matched on the offset as well as the type, because a kind
682
+ // of atom the caller did not ask for is not one: an `image` range with no
683
+ // `renderEmbed` behind it is still just a range.
684
+ if (atom < atoms.length && isAtomType(range.type) && range.start === atoms[atom].start) {
685
+ insideStart = atoms[atom].start;
686
+ insideEnd = atoms[atom].end;
687
+ atom++;
688
+ } else if (range.start >= insideStart && range.start + range.length <= insideEnd) {
689
+ continue;
690
+ }
691
+ let start = offsets[Math.min(range.start, text.length)];
692
+ const end = offsets[Math.min(range.start + range.length, text.length)];
693
+
694
+ // A fenced block opens with a line of its own, and cutting that line leaves
695
+ // the break that ended it at the front of the block. What is left then
696
+ // starts on the line above the code, which is a blank first line in
697
+ // whatever draws the block as a box.
698
+ if (range.type === "codeblock") {
699
+ while (start < end && isLineBreak(stripped.charCodeAt(start))) {
700
+ start++;
701
+ }
702
+ }
703
+ if (end <= start) {
704
+ continue;
705
+ }
706
+ const next = {
707
+ type: displayType(range.type),
708
+ start,
709
+ length: end - start
710
+ };
711
+ if (range.depth !== undefined) {
712
+ next.depth = range.depth;
713
+ }
714
+ remapped.push(next);
715
+ }
716
+ const prefixes = atoms.length > 0 ? remapped.filter(range => range.type === "block-prefix") : [];
717
+ const embeds = images.length > 0 ? images.map(image => {
718
+ const index = offsets[image.start];
719
+ return {
720
+ index,
721
+ uri: image.uri,
722
+ alt: image.alt,
723
+ title: image.title,
724
+ inline: sharesItsLine(stripped, prefixes, index)
725
+ };
726
+ }) : NO_EMBEDS;
727
+ const mathsOut = maths.length > 0 ? maths.map(span => {
728
+ const index = offsets[span.start];
729
+ return {
730
+ index,
731
+ tex: span.tex,
732
+ display: span.display
733
+ };
734
+ }) : NO_MATHS;
735
+ return {
736
+ text: stripped,
737
+ ranges: remapped,
738
+ embeds,
739
+ maths: mathsOut,
740
+ links: toLinks(stripped, links, offsets)
741
+ };
742
+ }
743
+ //# sourceMappingURL=stripUtils.js.map