@agentshouse/mdmodel 0.1.0-alpha.8 → 0.1.0-c68e2039f1ca8

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 (323) hide show
  1. package/API.md +300 -0
  2. package/README.md +34 -175
  3. package/dist/blocks.d.ts +11 -0
  4. package/dist/blocks.d.ts.map +1 -0
  5. package/dist/blocks.js +62 -0
  6. package/dist/condition.d.ts +137 -0
  7. package/dist/condition.d.ts.map +1 -0
  8. package/dist/condition.js +394 -0
  9. package/dist/definition.d.ts +42 -25
  10. package/dist/definition.d.ts.map +1 -1
  11. package/dist/definition.js +473 -146
  12. package/dist/divide.d.ts +3 -0
  13. package/dist/divide.d.ts.map +1 -0
  14. package/dist/divide.js +310 -0
  15. package/dist/document.d.ts +2 -0
  16. package/dist/document.d.ts.map +1 -1
  17. package/dist/document.js +89 -120
  18. package/dist/fields.d.ts +4 -0
  19. package/dist/fields.d.ts.map +1 -0
  20. package/dist/fields.js +3 -0
  21. package/dist/index.d.ts +9 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +6 -3
  24. package/dist/links.d.ts +1 -0
  25. package/dist/links.d.ts.map +1 -1
  26. package/dist/links.js +618 -224
  27. package/dist/paths.d.ts +2 -3
  28. package/dist/paths.d.ts.map +1 -1
  29. package/dist/paths.js +27 -37
  30. package/dist/profile.js +1 -3
  31. package/dist/project.d.ts +19 -1
  32. package/dist/project.d.ts.map +1 -1
  33. package/dist/project.js +82 -73
  34. package/dist/refuse.d.ts.map +1 -1
  35. package/dist/refuse.js +2 -10
  36. package/dist/schema.d.ts +7 -5
  37. package/dist/schema.d.ts.map +1 -1
  38. package/dist/schema.js +156 -41
  39. package/dist/sections.d.ts +2 -1
  40. package/dist/sections.d.ts.map +1 -1
  41. package/dist/sections.js +45 -67
  42. package/dist/types.d.ts +30 -2
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js +1 -3
  45. package/dist/validate.d.ts +3 -2
  46. package/dist/validate.d.ts.map +1 -1
  47. package/dist/validate.js +138 -136
  48. package/dist/version.d.ts +1 -1
  49. package/dist/version.d.ts.map +1 -1
  50. package/dist/version.js +1 -3
  51. package/dist/yaml.d.ts +2 -0
  52. package/dist/yaml.d.ts.map +1 -1
  53. package/dist/yaml.js +255 -191
  54. package/fixtures/README.md +85 -55
  55. package/fixtures/cases/absent-optional-field/library/companies/acme.md +4 -0
  56. package/fixtures/cases/absent-optional-field/library/deals/lead.md +6 -0
  57. package/fixtures/cases/absent-optional-field/schema.yaml +56 -0
  58. package/fixtures/cases/binary-any-reference/expected.json +1 -2
  59. package/fixtures/cases/binary-any-reference/schema.yaml +4 -0
  60. package/fixtures/cases/binary-document-collision/expected.json +1 -2
  61. package/fixtures/cases/binary-document-collision/schema.yaml +1 -0
  62. package/fixtures/cases/binary-link-outside-collection/expected.json +1 -2
  63. package/fixtures/cases/binary-link-outside-collection/schema.yaml +1 -0
  64. package/fixtures/cases/binary-prototype-reference/expected.json +1 -2
  65. package/fixtures/cases/binary-prototype-reference/schema.yaml +4 -0
  66. package/fixtures/cases/binary-typed-reference/expected.json +1 -2
  67. package/fixtures/cases/binary-typed-reference/schema.yaml +5 -0
  68. package/fixtures/cases/boolean-field/context.json +1 -0
  69. package/fixtures/cases/boolean-field/expected.json +6 -0
  70. package/fixtures/cases/boolean-field/library/companies/acme.md +4 -0
  71. package/fixtures/cases/boolean-field/library/deals/renewal.md +31 -0
  72. package/fixtures/cases/boolean-field/schema.yaml +56 -0
  73. package/fixtures/cases/bracketed-link-definition/schema.yaml +6 -0
  74. package/fixtures/cases/closed-nested-object/context.json +1 -0
  75. package/fixtures/cases/closed-nested-object/expected.json +6 -0
  76. package/fixtures/cases/closed-nested-object/library/companies/acme.md +4 -0
  77. package/fixtures/cases/closed-nested-object/library/deals/renewal.md +32 -0
  78. package/fixtures/cases/closed-nested-object/schema.yaml +56 -0
  79. package/fixtures/cases/composed-root-reference/context.json +1 -0
  80. package/fixtures/cases/composed-root-reference/expected.json +6 -0
  81. package/fixtures/cases/composed-root-reference/library/a.md +5 -0
  82. package/fixtures/cases/composed-root-reference/schema.yaml +13 -0
  83. package/fixtures/cases/date-time-format/context.json +1 -0
  84. package/fixtures/cases/date-time-format/expected.json +6 -0
  85. package/fixtures/cases/date-time-format/library/companies/acme.md +4 -0
  86. package/fixtures/cases/date-time-format/library/deals/renewal.md +31 -0
  87. package/fixtures/cases/date-time-format/schema.yaml +56 -0
  88. package/fixtures/cases/declared-binary-links/schema.yaml +1 -0
  89. package/fixtures/cases/default-unfilled/context.json +1 -0
  90. package/fixtures/cases/default-unfilled/expected.json +6 -0
  91. package/fixtures/cases/default-unfilled/library/companies/acme.md +4 -0
  92. package/fixtures/cases/default-unfilled/library/deals/renewal.md +29 -0
  93. package/fixtures/cases/default-unfilled/schema.yaml +56 -0
  94. package/fixtures/cases/defs-pattern/context.json +1 -0
  95. package/fixtures/cases/defs-pattern/expected.json +6 -0
  96. package/fixtures/cases/defs-pattern/library/companies/acme.md +4 -0
  97. package/fixtures/cases/defs-pattern/library/deals/renewal.md +31 -0
  98. package/fixtures/cases/defs-pattern/schema.yaml +56 -0
  99. package/fixtures/cases/dependent-rule/context.json +1 -0
  100. package/fixtures/cases/dependent-rule/expected.json +6 -0
  101. package/fixtures/cases/dependent-rule/library/companies/acme.md +4 -0
  102. package/fixtures/cases/dependent-rule/library/deals/renewal.md +30 -0
  103. package/fixtures/cases/dependent-rule/schema.yaml +56 -0
  104. package/fixtures/cases/duplicate-link-definition/schema.yaml +6 -0
  105. package/fixtures/cases/email-format/context.json +1 -0
  106. package/fixtures/cases/email-format/expected.json +6 -0
  107. package/fixtures/cases/email-format/library/companies/acme.md +4 -0
  108. package/fixtures/cases/email-format/library/deals/renewal.md +31 -0
  109. package/fixtures/cases/email-format/schema.yaml +56 -0
  110. package/fixtures/cases/fenced-link-definition/schema.yaml +6 -0
  111. package/fixtures/cases/field-enum/expected.json +2 -3
  112. package/fixtures/cases/field-enum/schema.yaml +7 -0
  113. package/fixtures/cases/frontmatter-schema/context.json +1 -0
  114. package/fixtures/cases/frontmatter-schema/expected.json +5 -0
  115. package/fixtures/cases/frontmatter-schema/schema.yaml +5 -0
  116. package/fixtures/cases/integer-field/context.json +1 -0
  117. package/fixtures/cases/integer-field/expected.json +6 -0
  118. package/fixtures/cases/integer-field/library/companies/acme.md +4 -0
  119. package/fixtures/cases/integer-field/library/deals/renewal.md +31 -0
  120. package/fixtures/cases/integer-field/schema.yaml +56 -0
  121. package/fixtures/cases/interrupted-link-definition/schema.yaml +1 -0
  122. package/fixtures/cases/json-schema-constructs/context.json +1 -0
  123. package/fixtures/cases/json-schema-constructs/expected.json +1 -0
  124. package/fixtures/cases/json-schema-constructs/library/companies/acme.md +4 -0
  125. package/fixtures/cases/json-schema-constructs/library/deals/renewal.md +31 -0
  126. package/fixtures/cases/json-schema-constructs/schema.yaml +56 -0
  127. package/fixtures/cases/list-of-objects-closed/context.json +1 -0
  128. package/fixtures/cases/list-of-objects-closed/expected.json +6 -0
  129. package/fixtures/cases/list-of-objects-closed/library/companies/acme.md +4 -0
  130. package/fixtures/cases/list-of-objects-closed/library/deals/renewal.md +32 -0
  131. package/fixtures/cases/list-of-objects-closed/schema.yaml +56 -0
  132. package/fixtures/cases/list-of-objects-item/context.json +1 -0
  133. package/fixtures/cases/list-of-objects-item/expected.json +6 -0
  134. package/fixtures/cases/list-of-objects-item/library/companies/acme.md +4 -0
  135. package/fixtures/cases/list-of-objects-item/library/deals/renewal.md +31 -0
  136. package/fixtures/cases/list-of-objects-item/schema.yaml +56 -0
  137. package/fixtures/cases/list-size/context.json +1 -0
  138. package/fixtures/cases/list-size/expected.json +6 -0
  139. package/fixtures/cases/list-size/library/companies/acme.md +4 -0
  140. package/fixtures/cases/list-size/library/deals/renewal.md +31 -0
  141. package/fixtures/cases/list-size/schema.yaml +56 -0
  142. package/fixtures/cases/long-fence-link-definition/schema.yaml +1 -0
  143. package/fixtures/cases/malformed-definition/expected.json +2 -4
  144. package/fixtures/cases/malformed-definition/schema.yaml +3 -0
  145. package/fixtures/cases/member-document/context.json +1 -0
  146. package/fixtures/cases/member-document/expected.json +1 -0
  147. package/fixtures/cases/member-document/library/people/ana.md +5 -0
  148. package/fixtures/cases/member-document/schema.yaml +5 -0
  149. package/fixtures/cases/missing-binary-image/expected.json +1 -2
  150. package/fixtures/cases/missing-binary-image/schema.yaml +1 -0
  151. package/fixtures/cases/missing-binary-link/expected.json +1 -2
  152. package/fixtures/cases/missing-binary-link/schema.yaml +1 -0
  153. package/fixtures/cases/missing-required-field/expected.json +2 -3
  154. package/fixtures/cases/missing-required-field/schema.yaml +7 -0
  155. package/fixtures/cases/missing-section-item-kind/context.json +1 -0
  156. package/fixtures/cases/missing-section-item-kind/expected.json +5 -0
  157. package/fixtures/cases/missing-section-item-kind/schema.yaml +6 -0
  158. package/fixtures/cases/misspelled-key/context.json +1 -0
  159. package/fixtures/cases/misspelled-key/expected.json +6 -0
  160. package/fixtures/cases/misspelled-key/library/companies/acme.md +4 -0
  161. package/fixtures/cases/misspelled-key/library/deals/renewal.md +32 -0
  162. package/fixtures/cases/misspelled-key/schema.yaml +56 -0
  163. package/fixtures/cases/nested-defs/context.json +1 -0
  164. package/fixtures/cases/nested-defs/expected.json +6 -0
  165. package/fixtures/cases/nested-defs/library/deal.md +6 -0
  166. package/fixtures/cases/nested-defs/schema.yaml +11 -0
  167. package/fixtures/cases/nested-required-field/context.json +1 -0
  168. package/fixtures/cases/nested-required-field/expected.json +6 -0
  169. package/fixtures/cases/nested-required-field/library/companies/acme.md +4 -0
  170. package/fixtures/cases/nested-required-field/library/deals/renewal.md +30 -0
  171. package/fixtures/cases/nested-required-field/schema.yaml +56 -0
  172. package/fixtures/cases/null-refused/context.json +1 -0
  173. package/fixtures/cases/null-refused/expected.json +6 -0
  174. package/fixtures/cases/null-refused/library/companies/acme.md +4 -0
  175. package/fixtures/cases/null-refused/library/deals/renewal.md +31 -0
  176. package/fixtures/cases/null-refused/schema.yaml +56 -0
  177. package/fixtures/cases/numeric-range/context.json +1 -0
  178. package/fixtures/cases/numeric-range/expected.json +6 -0
  179. package/fixtures/cases/numeric-range/library/companies/acme.md +4 -0
  180. package/fixtures/cases/numeric-range/library/deals/renewal.md +31 -0
  181. package/fixtures/cases/numeric-range/schema.yaml +56 -0
  182. package/fixtures/cases/one-of-variant/context.json +1 -0
  183. package/fixtures/cases/one-of-variant/expected.json +6 -0
  184. package/fixtures/cases/one-of-variant/library/companies/acme.md +4 -0
  185. package/fixtures/cases/one-of-variant/library/deals/renewal.md +31 -0
  186. package/fixtures/cases/one-of-variant/schema.yaml +56 -0
  187. package/fixtures/cases/open-map-value/context.json +1 -0
  188. package/fixtures/cases/open-map-value/expected.json +6 -0
  189. package/fixtures/cases/open-map-value/library/companies/acme.md +4 -0
  190. package/fixtures/cases/open-map-value/library/deals/renewal.md +31 -0
  191. package/fixtures/cases/open-map-value/schema.yaml +56 -0
  192. package/fixtures/cases/paragraph-link-definition/schema.yaml +1 -0
  193. package/fixtures/cases/prototype-field/context.json +1 -0
  194. package/fixtures/cases/prototype-field/expected.json +6 -0
  195. package/fixtures/cases/prototype-field/library/item.md +9 -0
  196. package/fixtures/cases/prototype-field/schema.yaml +6 -0
  197. package/fixtures/cases/quoted-link-definition/expected.json +1 -2
  198. package/fixtures/cases/quoted-link-definition/schema.yaml +1 -0
  199. package/fixtures/cases/referenced-missing-file/expected.json +0 -1
  200. package/fixtures/cases/referenced-missing-file/schema.yaml +11 -0
  201. package/fixtures/cases/remote-ref/context.json +1 -0
  202. package/fixtures/cases/remote-ref/expected.json +5 -0
  203. package/fixtures/cases/remote-ref/schema.yaml +3 -0
  204. package/fixtures/cases/second-member-document/context.json +1 -0
  205. package/fixtures/cases/second-member-document/expected.json +5 -0
  206. package/fixtures/cases/second-member-document/schema.yaml +4 -0
  207. package/fixtures/cases/section-item-enum/context.json +1 -0
  208. package/fixtures/cases/section-item-enum/expected.json +6 -0
  209. package/fixtures/cases/section-item-enum/library/task.md +8 -0
  210. package/fixtures/cases/section-item-enum/schema.yaml +3 -0
  211. package/fixtures/cases/section-item-kind/context.json +1 -0
  212. package/fixtures/cases/section-item-kind/expected.json +6 -0
  213. package/fixtures/cases/section-item-kind/library/task.md +8 -0
  214. package/fixtures/cases/section-item-kind/schema.yaml +3 -0
  215. package/fixtures/cases/section-items/context.json +1 -0
  216. package/fixtures/cases/section-items/expected.json +1 -0
  217. package/fixtures/cases/section-items/library/other.md +3 -0
  218. package/fixtures/cases/section-items/library/page.md +42 -0
  219. package/fixtures/cases/section-items/schema.yaml +10 -0
  220. package/fixtures/cases/section-reference-path/context.json +1 -0
  221. package/fixtures/cases/section-reference-path/expected.json +6 -0
  222. package/fixtures/cases/section-reference-path/library/other.md +3 -0
  223. package/fixtures/cases/section-reference-path/library/page.md +7 -0
  224. package/fixtures/cases/section-reference-path/schema.yaml +3 -0
  225. package/fixtures/cases/section-reference-type/context.json +1 -0
  226. package/fixtures/cases/section-reference-type/expected.json +6 -0
  227. package/fixtures/cases/section-reference-type/library/note.md +1 -0
  228. package/fixtures/cases/section-reference-type/library/page.md +7 -0
  229. package/fixtures/cases/section-reference-type/schema.yaml +3 -0
  230. package/fixtures/cases/shortcut-reference-link/context.json +1 -0
  231. package/fixtures/cases/shortcut-reference-link/expected.json +5 -0
  232. package/fixtures/cases/shortcut-reference-link/library/item.md +10 -0
  233. package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -0
  234. package/fixtures/cases/string-length/context.json +1 -0
  235. package/fixtures/cases/string-length/expected.json +6 -0
  236. package/fixtures/cases/string-length/library/companies/acme.md +4 -0
  237. package/fixtures/cases/string-length/library/deals/renewal.md +31 -0
  238. package/fixtures/cases/string-length/schema.yaml +56 -0
  239. package/fixtures/cases/structured-section/expected.json +1 -2
  240. package/fixtures/cases/structured-section/schema.yaml +7 -0
  241. package/fixtures/cases/submission-keys/context.json +1 -0
  242. package/fixtures/cases/submission-keys/expected.json +1 -0
  243. package/fixtures/cases/submission-keys/library/notes/visitor.md +8 -0
  244. package/fixtures/cases/submission-keys/schema.yaml +4 -0
  245. package/fixtures/cases/text-field-kind/context.json +1 -0
  246. package/fixtures/cases/text-field-kind/expected.json +6 -0
  247. package/fixtures/cases/text-field-kind/library/page.md +4 -0
  248. package/fixtures/cases/text-field-kind/schema.yaml +4 -0
  249. package/fixtures/cases/truncated-link-definition/expected.json +1 -2
  250. package/fixtures/cases/truncated-link-definition/schema.yaml +1 -0
  251. package/fixtures/cases/types-folder-content/context.json +1 -0
  252. package/fixtures/cases/types-folder-content/expected.json +1 -0
  253. package/fixtures/cases/types-folder-content/library/types/task.md +4 -0
  254. package/fixtures/cases/types-folder-content/schema.yaml +4 -0
  255. package/fixtures/cases/unclosed-frontmatter/expected.json +1 -2
  256. package/fixtures/cases/undeclared-field/context.json +1 -0
  257. package/fixtures/cases/undeclared-field/expected.json +6 -0
  258. package/fixtures/cases/undeclared-field/library/item.md +9 -0
  259. package/fixtures/cases/undeclared-field/schema.yaml +6 -0
  260. package/fixtures/cases/unevaluated-items-closed/context.json +1 -0
  261. package/fixtures/cases/unevaluated-items-closed/expected.json +6 -0
  262. package/fixtures/cases/unevaluated-items-closed/library/trip.md +6 -0
  263. package/fixtures/cases/unevaluated-items-closed/schema.yaml +10 -0
  264. package/fixtures/cases/unknown-type/context.json +1 -0
  265. package/fixtures/cases/unknown-type/expected.json +6 -0
  266. package/fixtures/cases/unknown-type/library/item.md +3 -0
  267. package/fixtures/cases/unknown-type/schema.yaml +3 -0
  268. package/fixtures/cases/unlisted-reference-type/context.json +1 -0
  269. package/fixtures/cases/unlisted-reference-type/expected.json +5 -0
  270. package/fixtures/cases/unlisted-reference-type/schema.yaml +3 -0
  271. package/fixtures/cases/unresolved-link/expected.json +1 -2
  272. package/fixtures/cases/unresolved-link/schema.yaml +6 -0
  273. package/fixtures/cases/valid-typed-document/library/tasks/one.md +1 -0
  274. package/fixtures/cases/valid-typed-document/schema.yaml +16 -0
  275. package/fixtures/cases/wide-item-fence-link/schema.yaml +1 -0
  276. package/fixtures/division.json +409 -0
  277. package/fixtures/projection.json +109 -28
  278. package/package.json +3 -12
  279. package/dist/definition.js.map +0 -1
  280. package/dist/document.js.map +0 -1
  281. package/dist/index.js.map +0 -1
  282. package/dist/links.js.map +0 -1
  283. package/dist/paths.js.map +0 -1
  284. package/dist/profile.js.map +0 -1
  285. package/dist/project.js.map +0 -1
  286. package/dist/refuse.js.map +0 -1
  287. package/dist/schema.js.map +0 -1
  288. package/dist/sections.js.map +0 -1
  289. package/dist/types.js.map +0 -1
  290. package/dist/validate.js.map +0 -1
  291. package/dist/version.js.map +0 -1
  292. package/dist/yaml.js.map +0 -1
  293. package/fixtures/cases/binary-any-reference/library/types/note.md +0 -5
  294. package/fixtures/cases/binary-document-collision/library/types/note.md +0 -3
  295. package/fixtures/cases/binary-link-outside-collection/library/types/note.md +0 -3
  296. package/fixtures/cases/binary-prototype-reference/library/types/note.md +0 -5
  297. package/fixtures/cases/binary-typed-reference/library/types/note.md +0 -5
  298. package/fixtures/cases/binary-typed-reference/library/types/person.md +0 -3
  299. package/fixtures/cases/bracketed-link-definition/library/types/task.md +0 -7
  300. package/fixtures/cases/declared-binary-links/library/types/note.md +0 -3
  301. package/fixtures/cases/duplicate-link-definition/library/types/task.md +0 -7
  302. package/fixtures/cases/fenced-link-definition/library/types/task.md +0 -7
  303. package/fixtures/cases/field-enum/library/types/task.md +0 -8
  304. package/fixtures/cases/interrupted-link-definition/library/types/note.md +0 -3
  305. package/fixtures/cases/long-fence-link-definition/library/types/note.md +0 -3
  306. package/fixtures/cases/malformed-definition/library/types/task.md +0 -5
  307. package/fixtures/cases/missing-binary-image/library/types/note.md +0 -3
  308. package/fixtures/cases/missing-binary-link/library/types/note.md +0 -3
  309. package/fixtures/cases/missing-required-field/library/types/task.md +0 -8
  310. package/fixtures/cases/paragraph-link-definition/library/types/note.md +0 -3
  311. package/fixtures/cases/prd-definition/library/types/task.md +0 -15
  312. package/fixtures/cases/quoted-link-definition/library/types/note.md +0 -3
  313. package/fixtures/cases/referenced-missing-file/library/types/person.md +0 -5
  314. package/fixtures/cases/referenced-missing-file/library/types/task.md +0 -8
  315. package/fixtures/cases/structured-section/library/types/task.md +0 -8
  316. package/fixtures/cases/truncated-link-definition/library/types/note.md +0 -3
  317. package/fixtures/cases/unresolved-link/library/types/task.md +0 -7
  318. package/fixtures/cases/valid-typed-document/library/types/person.md +0 -5
  319. package/fixtures/cases/valid-typed-document/library/types/task.md +0 -12
  320. package/fixtures/cases/wide-item-fence-link/library/types/note.md +0 -3
  321. package/markdown-syntax-profile.md +0 -9
  322. /package/fixtures/cases/{prd-definition → absent-optional-field}/context.json +0 -0
  323. /package/fixtures/cases/{prd-definition → absent-optional-field}/expected.json +0 -0
package/dist/links.js CHANGED
@@ -1,11 +1,34 @@
1
1
  const TAB_STOP = 4;
2
2
  const CLOSING_FENCE_INDENT = 3;
3
+ const CODE_INDENT = 4;
3
4
  const HEADING = /^#{1,6}(?:[ \t]|$)/;
4
5
  const BREAK = /^(?:(?:\*[ \t]*){3,}|(?:-[ \t]*){3,}|(?:_[ \t]*){3,})$/;
5
6
  const SETEXT = /^(?:=+|-+)[ \t]*$/;
6
- const LABEL = /^\[((?:[^\\\]\n]|\\.)+)\]:[ \t]*/;
7
- const DESTINATION = /^(?:(<[^<>\n\r]*>)|([^\s<][^\s]*))/d;
8
- const TITLE = /^(?:"[^"\n]*"|'[^'\n]*'|\([^()\n]*\))[ \t]*$/;
7
+ const BLANK = /^[ \t\v\f]*\r?$/;
8
+ const HTML_CLOSED = [
9
+ [/^<(?:script|pre|style)(?:[ \t\v\f>]|$)/i, /<\/(?:script|pre|style)>/i],
10
+ [/^<!--/, /-->/],
11
+ [/^<\?/, /\?>/],
12
+ [/^<![A-Z]/, />/],
13
+ [/^<!\[CDATA\[/, /\]\]>/],
14
+ ];
15
+ const HTML_BLOCK_TAG = /^<\/?(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)(?:[ \t\v\f>]|\/>|$)/i;
16
+ const HTML_TAG_LINE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\v\f]+[A-Za-z_:][A-Za-z0-9_.:-]*(?:[ \t\v\f]*=[ \t\v\f]*(?:[^ \t\v\f\r\n"'=<>`]+|'[^']*'|"[^"]*"))?)*[ \t\v\f]*\/?>|<\/[A-Za-z][A-Za-z0-9-]*[ \t\v\f]*>)[ \t\v\f]*$/;
17
+ const ORDERED = /^(\d{1,9})[.)]/;
18
+ const LABEL_LENGTH = 999;
19
+ const PUNCTUATION = /^[!-/:-@[-`{-~]$/;
20
+ const INLINE_RAW = new RegExp([
21
+ '<[A-Za-z][A-Za-z0-9-]*(?:[ \\t\\n\\v\\f\\r]+[A-Za-z_:][A-Za-z0-9_.:-]*(?:[ \\t\\n\\v\\f\\r]*=[ \\t\\n\\v\\f\\r]*(?:[^ \\t\\n\\v\\f\\r"\'=<>`]+|\'[^\']*\'|"[^"]*"))?)*[ \\t\\n\\v\\f\\r]*\\/?>',
22
+ '<\\/[A-Za-z][A-Za-z0-9-]*[ \\t\\n\\v\\f\\r]*>',
23
+ '<!--(?!-?>)(?:-?[^-])*-->',
24
+ '<\\?[\\s\\S]*?\\?>',
25
+ '<![A-Z]+[ \\t\\n\\v\\f\\r]+[^>]*>',
26
+ '<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
27
+ '<[A-Za-z][A-Za-z0-9+.-]{1,31}:[^\\x00-\\x20<>]*>',
28
+ "<[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*>",
29
+ ].join('|'), 'y');
30
+ const DELIMITER_ROW = /^\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
31
+ const GAP = /^[ \t\v\f]+/;
9
32
  function endOfLine(text, from) {
10
33
  const nl = text.indexOf('\n', from);
11
34
  return nl === -1 ? text.length : nl;
@@ -16,16 +39,21 @@ function afterLine(text, end) {
16
39
  function itemMarker(text, index, end) {
17
40
  let i = index;
18
41
  const bullet = text[i];
19
- if (bullet === '-' || bullet === '*' || bullet === '+') i += 1;
42
+ if (bullet === '-' || bullet === '*' || bullet === '+')
43
+ i += 1;
20
44
  else {
21
45
  let digits = 0;
22
- while(digits < 9 && i + digits < end && text[i + digits] >= '0' && text[i + digits] <= '9')digits += 1;
46
+ while (digits < 9 && i + digits < end && text[i + digits] >= '0' && text[i + digits] <= '9')
47
+ digits += 1;
23
48
  const delimiter = text[i + digits];
24
- if (digits === 0 || delimiter !== '.' && delimiter !== ')') return null;
49
+ if (digits === 0 || (delimiter !== '.' && delimiter !== ')'))
50
+ return null;
25
51
  i += digits + 1;
26
52
  }
27
- if (i >= end) return i;
28
- if (text[i] !== ' ' && text[i] !== '\t') return null;
53
+ if (i >= end)
54
+ return i;
55
+ if (text[i] !== ' ' && text[i] !== '\t')
56
+ return null;
29
57
  return i + 1;
30
58
  }
31
59
  function readLine(text, start, end) {
@@ -33,41 +61,38 @@ function readLine(text, start, end) {
33
61
  let depth = 0;
34
62
  let item = false;
35
63
  let inner = start;
36
- for(;;){
64
+ for (;;) {
37
65
  let spaces = 0;
38
- while(spaces < 3 && i < end && text[i] === ' '){
66
+ while (spaces < 3 && i < end && text[i] === ' ') {
39
67
  i += 1;
40
68
  spaces += 1;
41
69
  }
42
70
  if (i < end && text[i] === '>') {
43
71
  depth += 1;
44
72
  i += 1;
45
- if (i < end && text[i] === ' ') i += 1;
73
+ if (i < end && text[i] === ' ')
74
+ i += 1;
46
75
  inner = i;
47
76
  continue;
48
77
  }
49
78
  const after = i < end ? itemMarker(text, i, end) : null;
50
- if (after === null) break;
79
+ if (after === null)
80
+ break;
51
81
  item = true;
52
82
  i = after;
53
83
  }
54
- return {
55
- start,
56
- end,
57
- content: i,
58
- depth,
59
- item,
60
- inner
61
- };
84
+ return { start, end, content: i, depth, item, inner };
62
85
  }
63
86
  function widthOf(text, from, to) {
64
87
  let width = 0;
65
- for(let i = from; i < to; i += 1)width += text[i] === '\t' ? TAB_STOP - width % TAB_STOP : 1;
88
+ for (let i = from; i < to; i += 1)
89
+ width += text[i] === '\t' ? TAB_STOP - (width % TAB_STOP) : 1;
66
90
  return width;
67
91
  }
68
92
  function afterIndent(text, line) {
69
93
  let i = line.inner;
70
- while(i < line.end && (text[i] === ' ' || text[i] === '\t'))i += 1;
94
+ while (i < line.end && (text[i] === ' ' || text[i] === '\t'))
95
+ i += 1;
71
96
  return i;
72
97
  }
73
98
  function indentWidth(text, line) {
@@ -79,302 +104,671 @@ function lineText(text, line) {
79
104
  }
80
105
  function fenceRun(text, at, end) {
81
106
  const char = text[at];
82
- if (char !== '`' && char !== '~') return null;
107
+ if (char !== '`' && char !== '~')
108
+ return null;
83
109
  let length = 0;
84
- while(at + length < end && text[at + length] === char)length += 1;
85
- return length < 3 ? null : {
86
- char,
87
- length
88
- };
110
+ while (at + length < end && text[at + length] === char)
111
+ length += 1;
112
+ return length < 3 ? null : { char, length };
89
113
  }
90
114
  function fenceAt(text, line) {
91
115
  const run = fenceRun(text, line.content, line.end);
92
- if (run === null) return null;
116
+ if (run === null)
117
+ return null;
93
118
  return {
94
119
  char: run.char,
95
120
  length: run.length,
96
121
  depth: line.depth,
97
122
  column: line.item ? widthOf(text, line.inner, line.content) : 0,
98
- item: line.item
123
+ item: line.item,
99
124
  };
100
125
  }
101
126
  function closesFence(text, line, open) {
102
- if (line.depth !== open.depth || line.item) return false;
127
+ if (line.depth !== open.depth || line.item)
128
+ return false;
103
129
  const indent = indentWidth(text, line);
104
- if (indent < open.column || indent > open.column + CLOSING_FENCE_INDENT) return false;
130
+ if (indent < open.column || indent > open.column + CLOSING_FENCE_INDENT)
131
+ return false;
105
132
  const at = afterIndent(text, line);
106
133
  const run = fenceRun(text, at, line.end);
107
- if (run === null || run.char !== open.char || run.length < open.length) return false;
134
+ if (run === null || run.char !== open.char || run.length < open.length)
135
+ return false;
108
136
  return text.slice(at + run.length, line.end).trim() === '';
109
137
  }
110
138
  function leavesContainer(text, line, open) {
111
- if (line.depth < open.depth) return true;
112
- if (!open.item || lineText(text, line).trim() === '') return false;
139
+ if (line.depth < open.depth)
140
+ return true;
141
+ if (!open.item || lineText(text, line).trim() === '')
142
+ return false;
113
143
  return indentWidth(text, line) < open.column;
114
144
  }
115
145
  function fenceSpan(text, line, open) {
116
146
  let cursor = afterLine(text, line.end);
117
- while(cursor < text.length){
147
+ while (cursor < text.length) {
118
148
  const end = endOfLine(text, cursor);
119
149
  const next = readLine(text, cursor, end);
120
- if (leavesContainer(text, next, open)) return cursor;
121
- if (closesFence(text, next, open)) return afterLine(text, end);
150
+ if (leavesContainer(text, next, open))
151
+ return cursor;
152
+ if (closesFence(text, next, open))
153
+ return afterLine(text, end);
122
154
  cursor = afterLine(text, end);
123
155
  }
124
156
  return text.length;
125
157
  }
126
- function skipInlineCode(text, index) {
158
+ function skipInlineCode(text, index, joins) {
127
159
  let ticks = 0;
128
- while(text[index + ticks] === '`')ticks += 1;
129
- const close = text.indexOf('`'.repeat(ticks), index + ticks);
130
- if (close === -1) return text.length;
131
- return close + ticks;
160
+ while (text[index + ticks] === '`')
161
+ ticks += 1;
162
+ let i = index + ticks;
163
+ while (i < text.length) {
164
+ const ch = text[i];
165
+ if (ch === '`') {
166
+ let run = 0;
167
+ while (text[i + run] === '`')
168
+ run += 1;
169
+ if (run === ticks)
170
+ return i + run;
171
+ i += run;
172
+ continue;
173
+ }
174
+ if (ch === '\r' && text[i + 1] !== '\n')
175
+ break;
176
+ if (ch === '\n' && !joins.has(i))
177
+ break;
178
+ i += 1;
179
+ }
180
+ return index + ticks;
132
181
  }
133
182
  function skipLinkSpace(text, start) {
134
183
  let i = start;
135
- while(text[i] === ' ' || text[i] === '\t')i += 1;
184
+ while (text[i] === ' ' || text[i] === '\t')
185
+ i += 1;
136
186
  return i;
137
187
  }
138
- function skipTitle(text, start) {
139
- const open = text[start];
140
- if (open !== '"' && open !== "'" && open !== '(') return start;
188
+ function skipInlineSpace(text, start, joins) {
189
+ let i = skipLinkSpace(text, start);
190
+ if (text[i] === '\r' && text[i + 1] === '\n')
191
+ i += 1;
192
+ if (text[i] !== '\n' || !joins.has(i))
193
+ return i;
194
+ return afterIndent(text, readLine(text, i + 1, endOfLine(text, i + 1)));
195
+ }
196
+ function closeEnd(text, start, open, joins) {
141
197
  const close = open === '(' ? ')' : open;
142
- let i = start + 1;
143
- while(i < text.length){
198
+ let i = start;
199
+ while (i < text.length) {
144
200
  const ch = text[i];
145
- if (ch === close) return i + 1;
146
- if (ch === '\n' || ch === '\r') return null;
201
+ if (escapes(text, i)) {
202
+ i += 2;
203
+ continue;
204
+ }
205
+ if (ch === close)
206
+ return i + 1;
207
+ if (open === '(' && ch === '(')
208
+ return null;
209
+ if (ch === '\r' && text[i + 1] !== '\n')
210
+ return null;
211
+ if (ch === '\n' && !joins.has(i))
212
+ return null;
147
213
  i += 1;
148
214
  }
149
215
  return null;
150
216
  }
151
- function destination(text, start) {
152
- let i = skipLinkSpace(text, start + 1);
153
- let occurrence;
154
- if (text[i] === '<') {
155
- const close = text.indexOf('>', i + 1);
156
- if (close === -1) return null;
157
- occurrence = {
158
- href: text.slice(i + 1, close),
159
- start: i,
160
- end: close + 1,
161
- bracketed: true
162
- };
163
- i = close + 1;
164
- } else {
165
- const from = i;
166
- let depth = 0;
167
- while(i < text.length){
168
- const ch = text[i];
169
- if (ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r') break;
170
- if (ch === '(') depth += 1;
171
- else if (ch === ')') {
172
- if (depth === 0) break;
173
- depth -= 1;
174
- }
217
+ function skipTitle(text, start, joins) {
218
+ const open = text[start];
219
+ if (open !== '"' && open !== "'" && open !== '(')
220
+ return start;
221
+ return closeEnd(text, start + 1, open, joins);
222
+ }
223
+ function destinationAt(text, at, end) {
224
+ if (text[at] === '<') {
225
+ let close = at + 1;
226
+ while (close < end && text[close] !== '>') {
227
+ if (text[close] === '<')
228
+ return null;
229
+ close += escapes(text, close) ? 2 : 1;
230
+ }
231
+ if (close >= end)
232
+ return null;
233
+ return { href: text.slice(at + 1, close), start: at, end: close + 1, bracketed: true };
234
+ }
235
+ let i = at;
236
+ let depth = 0;
237
+ while (i < end) {
238
+ if (escapes(text, i)) {
239
+ i += 2;
240
+ continue;
241
+ }
242
+ const ch = text[i];
243
+ if (ch <= ' ' || ch === '\x7f')
244
+ break;
245
+ if (ch === '(')
246
+ depth += 1;
247
+ else if (ch === ')') {
248
+ if (depth === 0)
249
+ break;
250
+ depth -= 1;
251
+ }
252
+ i += 1;
253
+ }
254
+ if (depth !== 0)
255
+ return null;
256
+ return { href: text.slice(at, i), start: at, end: i, bracketed: false };
257
+ }
258
+ function destination(text, start, joins) {
259
+ let i = skipInlineSpace(text, start + 1, joins);
260
+ const occurrence = destinationAt(text, i, endOfLine(text, i));
261
+ if (occurrence === null)
262
+ return null;
263
+ i = occurrence.end;
264
+ const spaced = skipInlineSpace(text, i, joins);
265
+ if (spaced === i && text[i] !== ')')
266
+ return null;
267
+ i = spaced;
268
+ const afterTitle = skipTitle(text, i, joins);
269
+ if (afterTitle === null)
270
+ return null;
271
+ i = skipInlineSpace(text, afterTitle, joins);
272
+ if (text[i] !== ')')
273
+ return null;
274
+ return { occurrence, end: i + 1 };
275
+ }
276
+ function cellCount(row) {
277
+ return row
278
+ .trim()
279
+ .replace(/^\|/, '')
280
+ .replace(/(?<!\\)\|$/, '')
281
+ .split(/(?<!\\)\|/).length;
282
+ }
283
+ function headsTable(text, header, end) {
284
+ if (end >= text.length)
285
+ return false;
286
+ const row = lineText(text, readLine(text, end + 1, endOfLine(text, end + 1)));
287
+ return row.includes('|') && DELIMITER_ROW.test(row) && cellCount(row) === cellCount(header);
288
+ }
289
+ function blockText(text, line) {
290
+ if (!line.item)
291
+ return lineText(text, line);
292
+ const raw = text.slice(afterIndent(text, line), line.end);
293
+ return raw.endsWith('\r') ? raw.slice(0, -1) : raw;
294
+ }
295
+ function interruptsWithHtml(head) {
296
+ return HTML_CLOSED.some(([open]) => open.test(head)) || HTML_BLOCK_TAG.test(head);
297
+ }
298
+ function markerColumn(text, line) {
299
+ return widthOf(text, line.inner, afterIndent(text, line));
300
+ }
301
+ function markerEnd(text, at, end) {
302
+ const after = itemMarker(text, at, end);
303
+ if (after === null)
304
+ return null;
305
+ return after > at && (text[after - 1] === ' ' || text[after - 1] === '\t') ? after - 1 : after;
306
+ }
307
+ function itemContent(text, line) {
308
+ let marker = markerEnd(text, afterIndent(text, line), line.end);
309
+ for (;;) {
310
+ let next = marker + 1;
311
+ let spaces = 0;
312
+ while (spaces < 3 && text[next] === ' ') {
313
+ next += 1;
314
+ spaces += 1;
315
+ }
316
+ const nested = next < line.end ? markerEnd(text, next, line.end) : null;
317
+ if (nested === null)
318
+ break;
319
+ marker = nested;
320
+ }
321
+ const at = skipLinkSpace(text, marker);
322
+ const rest = text.slice(at, line.end).trim();
323
+ const column = widthOf(text, line.inner, at);
324
+ const start = widthOf(text, line.inner, marker);
325
+ if (rest !== '' && column - start <= CODE_INDENT)
326
+ return { column, code: null };
327
+ return { column: start + 1, code: rest === '' ? null : marker + 1 };
328
+ }
329
+ function joinsParagraph(text, line, depth, item) {
330
+ if (line.depth > depth)
331
+ return false;
332
+ const head = blockText(text, line);
333
+ if (head.trim() === '' || endsBlock(head) || interruptsWithHtml(head))
334
+ return false;
335
+ if (fenceAt(text, line) !== null)
336
+ return false;
337
+ if (!line.item)
338
+ return true;
339
+ if (item !== undefined && markerColumn(text, line) < item)
340
+ return false;
341
+ if (lineText(text, line).trim() === '')
342
+ return true;
343
+ const ordered = ORDERED.exec(head);
344
+ return ordered !== null && Number(ordered[1]) !== 1;
345
+ }
346
+ function startsParagraph(text, line) {
347
+ return lineText(text, line).trim() !== '' && !endsBlock(blockText(text, line));
348
+ }
349
+ function lineColumn(text, line) {
350
+ return line.item ? markerColumn(text, line) : indentWidth(text, line);
351
+ }
352
+ function endsTable(text, line, depth) {
353
+ const head = blockText(text, line);
354
+ return (head.trim() === '' ||
355
+ line.depth !== depth ||
356
+ line.item ||
357
+ endsBlock(head) ||
358
+ interruptsWithHtml(head) ||
359
+ fenceAt(text, line) !== null);
360
+ }
361
+ function quoteInner(text, start, end, depth) {
362
+ let i = start;
363
+ for (let level = 0; level < depth; level += 1) {
364
+ let spaces = 0;
365
+ while (spaces < 3 && i < end && text[i] === ' ') {
175
366
  i += 1;
367
+ spaces += 1;
176
368
  }
177
- occurrence = {
178
- href: text.slice(from, i),
179
- start: from,
180
- end: i,
181
- bracketed: false
182
- };
369
+ if (text[i] !== '>')
370
+ return null;
371
+ i += 1;
372
+ if (text[i] === ' ')
373
+ i += 1;
183
374
  }
184
- i = skipLinkSpace(text, i);
185
- const afterTitle = skipTitle(text, i);
186
- if (afterTitle === null) return null;
187
- i = skipLinkSpace(text, afterTitle);
188
- if (text[i] !== ')') return null;
189
- return {
190
- occurrence,
191
- end: i + 1
192
- };
375
+ return i;
376
+ }
377
+ function htmlEnd(text, line, item) {
378
+ const head = lineText(text, line);
379
+ const closed = HTML_CLOSED.find(([open]) => open.test(head));
380
+ if (closed === undefined && !HTML_BLOCK_TAG.test(head) && !HTML_TAG_LINE.test(head))
381
+ return null;
382
+ if (closed !== undefined && closed[1].test(head))
383
+ return afterLine(text, line.end);
384
+ let cursor = afterLine(text, line.end);
385
+ while (cursor < text.length) {
386
+ const end = endOfLine(text, cursor);
387
+ const inner = quoteInner(text, cursor, end, line.depth);
388
+ if (inner === null)
389
+ return cursor;
390
+ const at = skipLinkSpace(text, inner);
391
+ const body = text.slice(inner, end);
392
+ const blank = BLANK.test(text.slice(at, end));
393
+ if (item !== undefined && !blank && widthOf(text, inner, at) < item)
394
+ return cursor;
395
+ if (closed === undefined && blank)
396
+ return cursor;
397
+ if (closed !== undefined && closed[1].test(body))
398
+ return afterLine(text, end);
399
+ cursor = afterLine(text, end);
400
+ if (cursor === end)
401
+ break;
402
+ }
403
+ return text.length;
404
+ }
405
+ function codeEnd(text, line, base) {
406
+ let stop = afterLine(text, line.end);
407
+ let cursor = stop;
408
+ while (cursor < text.length) {
409
+ const end = endOfLine(text, cursor);
410
+ const current = readLine(text, cursor, end);
411
+ if (current.depth !== line.depth)
412
+ break;
413
+ const blank = lineText(text, current).trim() === '' && !current.item;
414
+ if (!blank && (current.item || indentWidth(text, current) < base + CODE_INDENT))
415
+ break;
416
+ cursor = afterLine(text, end);
417
+ if (!blank)
418
+ stop = cursor;
419
+ if (cursor === end)
420
+ break;
421
+ }
422
+ return stop;
193
423
  }
194
- function labelEnd(text, start) {
424
+ function structure(text) {
425
+ const joins = new Set();
426
+ const raw = [];
427
+ const items = [];
428
+ let paragraph = null;
429
+ let table = null;
430
+ let depth = 0;
431
+ let cursor = 0;
432
+ while (cursor < text.length) {
433
+ const end = endOfLine(text, cursor);
434
+ const line = readLine(text, cursor, end);
435
+ const content = lineText(text, line);
436
+ const blank = content.trim() === '' && !line.item;
437
+ if (table !== null && endsTable(text, line, table))
438
+ table = null;
439
+ if (table !== null) {
440
+ cursor = afterLine(text, end);
441
+ if (cursor === end)
442
+ break;
443
+ continue;
444
+ }
445
+ if (paragraph !== null && joinsParagraph(text, line, paragraph, items.at(-1))) {
446
+ if (headsTable(text, content, end)) {
447
+ table = line.depth;
448
+ paragraph = null;
449
+ }
450
+ else
451
+ joins.add(cursor - 1);
452
+ cursor = afterLine(text, end);
453
+ if (cursor === end)
454
+ break;
455
+ continue;
456
+ }
457
+ paragraph = null;
458
+ if (line.depth !== depth)
459
+ items.length = 0;
460
+ depth = line.depth;
461
+ if (!blank) {
462
+ while (items.length > 0 && items.at(-1) > lineColumn(text, line))
463
+ items.pop();
464
+ }
465
+ if (line.item && !BREAK.test(blockText(text, line))) {
466
+ const opened = itemContent(text, line);
467
+ items.push(opened.column);
468
+ if (opened.code !== null) {
469
+ const stop = codeEnd(text, line, opened.column);
470
+ raw.push([opened.code, stop]);
471
+ cursor = stop;
472
+ continue;
473
+ }
474
+ }
475
+ const open = fenceAt(text, line);
476
+ if (open !== null) {
477
+ const stop = fenceSpan(text, line, open);
478
+ raw.push([cursor, stop]);
479
+ cursor = stop;
480
+ continue;
481
+ }
482
+ const base = items.at(-1) ?? 0;
483
+ if (!blank && !line.item && indentWidth(text, line) >= base + CODE_INDENT) {
484
+ const stop = codeEnd(text, line, base);
485
+ raw.push([cursor, stop]);
486
+ cursor = stop;
487
+ continue;
488
+ }
489
+ const html = htmlEnd(text, line, items.at(-1));
490
+ if (html !== null) {
491
+ raw.push([cursor, html]);
492
+ cursor = html;
493
+ continue;
494
+ }
495
+ if (startsParagraph(text, line)) {
496
+ if (headsTable(text, content, end))
497
+ table = line.depth;
498
+ else
499
+ paragraph = line.depth;
500
+ }
501
+ cursor = afterLine(text, end);
502
+ if (cursor === end)
503
+ break;
504
+ }
505
+ return { joins, raw };
506
+ }
507
+ function escapes(text, index) {
508
+ return text[index] === '\\' && PUNCTUATION.test(text[index + 1] ?? '');
509
+ }
510
+ function referenceEnd(text, start, joins) {
195
511
  let i = start;
196
- let depth = 1;
197
- while(i < text.length && depth > 0){
512
+ while (i < text.length) {
198
513
  const ch = text[i];
199
- if (ch === '\\') {
514
+ if (escapes(text, i)) {
200
515
  i += 2;
201
516
  continue;
202
517
  }
203
- if (ch === '[') depth += 1;
204
- else if (ch === ']') depth -= 1;
205
- else if (ch === '\n' || ch === '\r') return -1;
518
+ if (ch === ']')
519
+ return i + 1;
520
+ if (ch === '[')
521
+ return -1;
522
+ if (ch === '\r' && text[i + 1] !== '\n')
523
+ return -1;
524
+ if (ch === '\n' && !joins.has(i))
525
+ return -1;
206
526
  i += 1;
207
527
  }
208
- return depth === 0 ? i : -1;
209
- }
210
- function takeLink(text, index, start, found, defs) {
211
- const end = labelEnd(text, index + 1);
212
- if (end === -1) return index + 1;
213
- const label = text.slice(index + 1, end - 1);
214
- let i = end;
215
- if (text[i] === '(') {
216
- const dest = destination(text, i);
217
- if (dest === null) return index + 1;
218
- found.push({
219
- start,
220
- end: dest.end,
221
- labelStart: index + 1,
222
- labelEnd: end - 1,
223
- destination: dest.occurrence
224
- });
225
- return dest.end;
528
+ return -1;
529
+ }
530
+ function labelText(text, from, to) {
531
+ let label = '';
532
+ let cursor = from;
533
+ let newline = text.indexOf('\n', cursor);
534
+ while (newline !== -1 && newline < to) {
535
+ label += `${text.slice(cursor, newline)}\n`;
536
+ cursor = afterIndent(text, readLine(text, newline + 1, endOfLine(text, newline + 1)));
537
+ newline = text.indexOf('\n', cursor);
538
+ }
539
+ return label + text.slice(cursor, to);
540
+ }
541
+ function labelKey(label) {
542
+ return label
543
+ .replace(/[ \t\n\v\f\r]+/g, ' ')
544
+ .replace(/^ | $/g, '')
545
+ .toLowerCase()
546
+ .split('\u0131')
547
+ .map((part) => part.toUpperCase())
548
+ .join('\u0131');
549
+ }
550
+ function labelKeyAt(text, from, to) {
551
+ const label = labelText(text, from, to);
552
+ if (label.length > LABEL_LENGTH && [...label].length > LABEL_LENGTH)
553
+ return '';
554
+ return labelKey(label);
555
+ }
556
+ function closeLink(text, opener, close, defs, joins) {
557
+ const end = close + 1;
558
+ const use = (destination, to) => ({
559
+ start: opener.start,
560
+ end: to,
561
+ labelStart: opener.at + 1,
562
+ labelEnd: close,
563
+ destination,
564
+ });
565
+ if (text[end] === '(') {
566
+ const dest = destination(text, end, joins);
567
+ if (dest !== null)
568
+ return use(dest.occurrence, dest.end);
226
569
  }
227
- if (text[i] === '[') {
228
- const close = labelEnd(text, i + 1);
229
- if (close === -1) return index + 1;
230
- const id = (text.slice(i + 1, close - 1) || label).trim().toLowerCase();
231
- const defined = defs.get(id);
232
- if (defined !== undefined) {
233
- found.push({
234
- start,
235
- end: close,
236
- labelStart: index + 1,
237
- labelEnd: end - 1,
238
- destination: defined
239
- });
570
+ if (text[end] === '[') {
571
+ const second = referenceEnd(text, end + 1, joins);
572
+ const collapsed = second === end + 2;
573
+ const named = collapsed
574
+ ? opener.bracketAfter
575
+ ? ''
576
+ : labelKeyAt(text, opener.at + 1, close)
577
+ : labelKeyAt(text, end + 1, second - 1);
578
+ if (second !== -1 && (named !== '' || collapsed)) {
579
+ const defined = defs.get(named);
580
+ return defined === undefined ? null : use(defined, second);
240
581
  }
241
- return close;
242
582
  }
243
- return i;
583
+ if (opener.bracketAfter)
584
+ return null;
585
+ const shortcut = defs.get(labelKeyAt(text, opener.at + 1, close));
586
+ return shortcut === undefined ? null : use(shortcut, end);
244
587
  }
245
588
  function definitionDestination(text, from, to) {
246
- let i = from;
247
- while(i < to && (text[i] === ' ' || text[i] === '\t'))i += 1;
248
- const match = DESTINATION.exec(text.slice(i, to));
249
- if (match === null) return null;
250
- const bracketed = match[1];
251
- const span = match.indices?.[1] ?? match.indices?.[2];
252
- const href = bracketed === undefined ? match[2] : bracketed.slice(1, -1);
253
- if (href === undefined || span === undefined) return null;
254
- return {
255
- href,
256
- start: i + span[0],
257
- end: i + span[1],
258
- bracketed: bracketed !== undefined
259
- };
589
+ const occurrence = destinationAt(text, skipLinkSpace(text, from), to);
590
+ return occurrence === null || (occurrence.href === '' && !occurrence.bracketed)
591
+ ? null
592
+ : occurrence;
593
+ }
594
+ function titleEnd(text, at, joins) {
595
+ const open = text[at];
596
+ if (open !== '"' && open !== "'" && open !== '(')
597
+ return null;
598
+ const closed = closeEnd(text, at + 1, open, joins);
599
+ if (closed === null)
600
+ return null;
601
+ const end = endOfLine(text, closed);
602
+ return BLANK.test(text.slice(closed, end)) ? afterLine(text, end) : null;
260
603
  }
261
- function definitionAt(text, line) {
262
- const head = LABEL.exec(lineText(text, line));
263
- if (head === null) return null;
264
- const id = head[1]?.trim().toLowerCase();
265
- if (id === undefined || id === '') return null;
266
- const from = line.content + head[0].length;
267
- let occurrence = definitionDestination(text, from, line.end);
268
- let next = afterLine(text, line.end);
604
+ function definitionAt(text, line, joins) {
605
+ if (text[line.content] !== '[')
606
+ return null;
607
+ const close = referenceEnd(text, line.content + 1, joins);
608
+ if (close === -1 || text[close] !== ':')
609
+ return null;
610
+ const id = labelKeyAt(text, line.content + 1, close - 1);
611
+ if (id === '')
612
+ return null;
613
+ const from = close + 1;
614
+ let end = endOfLine(text, from);
615
+ let occurrence = definitionDestination(text, from, end);
269
616
  if (occurrence === null) {
270
- if (text.slice(from, line.end).trim() !== '' || next >= text.length) return null;
271
- const end = endOfLine(text, next);
272
- occurrence = definitionDestination(text, readLine(text, next, end).content, end);
273
- if (occurrence === null) return null;
274
- next = afterLine(text, end);
617
+ if (text.slice(from, end).trim() !== '' || !joins.has(end))
618
+ return null;
619
+ const start = end + 1;
620
+ end = endOfLine(text, start);
621
+ occurrence = definitionDestination(text, afterIndent(text, readLine(text, start, end)), end);
622
+ if (occurrence === null)
623
+ return null;
275
624
  }
276
- if (next < text.length) {
277
- const end = endOfLine(text, next);
278
- if (TITLE.test(lineText(text, readLine(text, next, end)))) next = afterLine(text, end);
625
+ const rest = text.slice(occurrence.end, end);
626
+ if (!BLANK.test(rest)) {
627
+ const gap = GAP.exec(rest);
628
+ const titled = gap === null ? null : titleEnd(text, occurrence.end + gap[0].length, joins);
629
+ return titled === null ? null : { id, occurrence, next: titled };
279
630
  }
280
- return {
281
- id,
282
- occurrence,
283
- next
284
- };
631
+ const next = afterLine(text, end);
632
+ if (joins.has(end)) {
633
+ const titled = titleEnd(text, afterIndent(text, readLine(text, next, endOfLine(text, next))), joins);
634
+ if (titled !== null)
635
+ return { id, occurrence, next: titled };
636
+ }
637
+ return { id, occurrence, next };
285
638
  }
286
639
  function endsBlock(content) {
287
640
  return HEADING.test(content) || BREAK.test(content) || SETEXT.test(content);
288
641
  }
289
642
  function scanBlocks(text) {
290
- const fences = [];
643
+ const { joins, raw } = structure(text);
291
644
  const definitions = new Map();
292
645
  const blocks = [];
293
- let paragraph = false;
294
- let depth = 0;
646
+ let fresh = 0;
295
647
  let i = 0;
296
- while(i < text.length){
297
- const line = readLine(text, i, endOfLine(text, i));
298
- if (line.depth !== depth || line.item) paragraph = false;
299
- depth = line.depth;
300
- const open = fenceAt(text, line);
301
- if (open !== null) {
302
- const stop = fenceSpan(text, line, open);
303
- fences.push([
304
- i,
305
- stop
306
- ]);
307
- paragraph = false;
308
- i = stop;
309
- continue;
310
- }
311
- const content = lineText(text, line);
312
- if (content.trim() === '') {
313
- paragraph = false;
314
- i = afterLine(text, line.end);
648
+ while (i < text.length) {
649
+ const skip = spanEndAt(raw, i);
650
+ if (skip !== undefined) {
651
+ i = skip;
315
652
  continue;
316
653
  }
317
- const definition = paragraph ? null : definitionAt(text, line);
654
+ const line = readLine(text, i, endOfLine(text, i));
655
+ const definition = lineText(text, line).trim() === '' || (i !== fresh && joins.has(i - 1))
656
+ ? null
657
+ : definitionAt(text, line, joins);
318
658
  if (definition !== null) {
319
- if (!definitions.has(definition.id)) definitions.set(definition.id, definition.occurrence);
320
- blocks.push({
321
- start: line.start,
322
- end: definition.next,
323
- destination: definition.occurrence
324
- });
659
+ if (!definitions.has(definition.id))
660
+ definitions.set(definition.id, definition.occurrence);
661
+ blocks.push({ start: line.start, end: definition.next, destination: definition.occurrence });
325
662
  i = definition.next;
663
+ fresh = i;
326
664
  continue;
327
665
  }
328
- paragraph = !endsBlock(content);
329
666
  i = afterLine(text, line.end);
330
667
  }
331
- return {
332
- fences,
333
- definitions,
334
- blocks
335
- };
668
+ return { raw, definitions, blocks, joins };
336
669
  }
337
- function fenceEndAt(spans, index) {
338
- for (const [start, end] of spans){
339
- if (index >= start && index < end) return end;
670
+ function spanEndAt(spans, index) {
671
+ for (const [start, end] of spans) {
672
+ if (index >= start && index < end)
673
+ return end;
340
674
  }
341
675
  return undefined;
342
676
  }
677
+ export function fenceSpans(text) {
678
+ const fences = [];
679
+ let i = 0;
680
+ while (i < text.length) {
681
+ const line = readLine(text, i, endOfLine(text, i));
682
+ const open = fenceAt(text, line);
683
+ if (open === null) {
684
+ i = afterLine(text, line.end);
685
+ continue;
686
+ }
687
+ const stop = fenceSpan(text, line, open);
688
+ fences.push([i, stop]);
689
+ i = stop;
690
+ }
691
+ return fences;
692
+ }
693
+ function paragraphEnd(text, from, joins) {
694
+ let i = from;
695
+ while (i < text.length) {
696
+ if (text[i] === '\n' && !joins.has(i))
697
+ return i;
698
+ if (text[i] === '\r' && text[i + 1] !== '\n')
699
+ return i;
700
+ i += 1;
701
+ }
702
+ return i;
703
+ }
343
704
  export function linkInventory(body) {
344
- const { fences, definitions, blocks } = scanBlocks(body);
705
+ const { raw, definitions, blocks, joins } = scanBlocks(body);
706
+ const skipped = [...raw, ...blocks.map((block) => [block.start, block.end])];
345
707
  const uses = [];
708
+ const openers = [];
709
+ let paragraph = { start: 0, end: -1, text: '' };
346
710
  let i = 0;
347
- while(i < body.length){
348
- const fenceEnd = fenceEndAt(fences, i);
349
- if (fenceEnd !== undefined) {
350
- i = fenceEnd;
711
+ while (i < body.length) {
712
+ const skipEnd = spanEndAt(skipped, i);
713
+ if (skipEnd !== undefined) {
714
+ openers.length = 0;
715
+ i = skipEnd;
351
716
  continue;
352
717
  }
353
- if (body[i] === '`') {
354
- i = skipInlineCode(body, i);
718
+ const ch = body[i];
719
+ if (escapes(body, i)) {
720
+ i += 2;
355
721
  continue;
356
722
  }
357
- if (body[i] === '!' && body[i + 1] === '[') {
358
- i = takeLink(body, i + 1, i, uses, definitions);
723
+ if (ch === '`') {
724
+ i = skipInlineCode(body, i, joins);
359
725
  continue;
360
726
  }
361
- if (body[i] === '[') {
362
- i = takeLink(body, i, i, uses, definitions);
727
+ if (ch === '<') {
728
+ if (i >= paragraph.end) {
729
+ const end = paragraphEnd(body, i, joins);
730
+ paragraph = { start: i, end, text: body.slice(i, end) };
731
+ }
732
+ INLINE_RAW.lastIndex = i - paragraph.start;
733
+ const raw = INLINE_RAW.exec(paragraph.text);
734
+ if (raw !== null) {
735
+ i += raw[0].length;
736
+ continue;
737
+ }
738
+ }
739
+ if ((ch === '\n' && !joins.has(i)) || (ch === '\r' && body[i + 1] !== '\n'))
740
+ openers.length = 0;
741
+ if (ch === '[' || (ch === '!' && body[i + 1] === '[')) {
742
+ const previous = openers.at(-1);
743
+ if (previous !== undefined)
744
+ previous.bracketAfter = true;
745
+ const image = ch === '!';
746
+ openers.push({ at: image ? i + 1 : i, start: i, image, active: true, bracketAfter: false });
747
+ i += image ? 2 : 1;
748
+ continue;
749
+ }
750
+ if (ch === ']') {
751
+ const opener = openers.pop();
752
+ const use = opener?.active ? closeLink(body, opener, i, definitions, joins) : null;
753
+ if (opener === undefined || use === null) {
754
+ i += 1;
755
+ continue;
756
+ }
757
+ uses.push(use);
758
+ if (!opener.image)
759
+ for (const earlier of openers)
760
+ if (!earlier.image)
761
+ earlier.active = false;
762
+ i = use.end;
363
763
  continue;
364
764
  }
365
765
  i += 1;
366
766
  }
367
- return {
368
- uses,
369
- blocks
370
- };
767
+ return { uses, blocks };
371
768
  }
372
769
  export function hrefOccurrences(body) {
373
770
  const byStart = new Map();
374
- for (const use of linkInventory(body).uses)byStart.set(use.destination.start, use.destination);
375
- return [
376
- ...byStart.values()
377
- ].sort((left, right)=>left.start - right.start);
771
+ for (const use of linkInventory(body).uses)
772
+ byStart.set(use.destination.start, use.destination);
773
+ return [...byStart.values()].sort((left, right) => left.start - right.start);
378
774
  }
379
-
380
- //# sourceMappingURL=links.js.map