@localix-ai/flowdown 0.0.0-stage → 0.5.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 (227) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -2
  3. package/dist/browser/file-actions.js +80 -0
  4. package/dist/browser/file-actions.js.map +1 -0
  5. package/dist/core/block-facts.js +72 -0
  6. package/dist/core/block-facts.js.map +1 -0
  7. package/dist/core/blocks.d.ts +25 -0
  8. package/dist/core/blocks.js +463 -0
  9. package/dist/core/blocks.js.map +1 -0
  10. package/dist/core/bounded-cache.js +42 -0
  11. package/dist/core/bounded-cache.js.map +1 -0
  12. package/dist/core/dollars.d.ts +12 -0
  13. package/dist/core/dollars.js +88 -0
  14. package/dist/core/dollars.js.map +1 -0
  15. package/dist/core/fence-scan.js +53 -0
  16. package/dist/core/fence-scan.js.map +1 -0
  17. package/dist/core/file-tree-parse.d.ts +26 -0
  18. package/dist/core/file-tree-parse.js +51 -0
  19. package/dist/core/file-tree-parse.js.map +1 -0
  20. package/dist/core/forms-html.js +63 -0
  21. package/dist/core/forms-html.js.map +1 -0
  22. package/dist/core/forms.d.ts +28 -0
  23. package/dist/core/forms.js +23 -0
  24. package/dist/core/forms.js.map +1 -0
  25. package/dist/core/headings.d.ts +11 -0
  26. package/dist/core/headings.js +74 -0
  27. package/dist/core/headings.js.map +1 -0
  28. package/dist/core/heal.d.ts +11 -0
  29. package/dist/core/heal.js +220 -0
  30. package/dist/core/heal.js.map +1 -0
  31. package/dist/core/load-once.js +23 -0
  32. package/dist/core/load-once.js.map +1 -0
  33. package/dist/core/math-delimiters.js +33 -0
  34. package/dist/core/math-delimiters.js.map +1 -0
  35. package/dist/core/math-syntax.js +56 -0
  36. package/dist/core/math-syntax.js.map +1 -0
  37. package/dist/core/prose.d.ts +10 -0
  38. package/dist/core/prose.js +77 -0
  39. package/dist/core/prose.js.map +1 -0
  40. package/dist/core/remark-answer-blocks.d.ts +5 -0
  41. package/dist/core/remark-answer-blocks.js +172 -0
  42. package/dist/core/remark-answer-blocks.js.map +1 -0
  43. package/dist/core/remark-answer-containers.js +299 -0
  44. package/dist/core/remark-answer-containers.js.map +1 -0
  45. package/dist/core/sanitize-schema.d.ts +18 -0
  46. package/dist/core/sanitize-schema.js +62 -0
  47. package/dist/core/sanitize-schema.js.map +1 -0
  48. package/dist/core/syntax.d.ts +8 -0
  49. package/dist/core/syntax.js +32 -0
  50. package/dist/core/syntax.js.map +1 -0
  51. package/dist/dialect.d.ts +92 -0
  52. package/dist/dialect.js +176 -0
  53. package/dist/dialect.js.map +1 -0
  54. package/dist/document/fence.d.ts +25 -0
  55. package/dist/document/fence.js +101 -0
  56. package/dist/document/fence.js.map +1 -0
  57. package/dist/document/index.d.ts +46 -0
  58. package/dist/document/index.js +66 -0
  59. package/dist/document/index.js.map +1 -0
  60. package/dist/document/table.d.ts +11 -0
  61. package/dist/document/table.js +35 -0
  62. package/dist/document/table.js.map +1 -0
  63. package/dist/dom/index.d.ts +21 -0
  64. package/dist/dom/index.js +123 -0
  65. package/dist/dom/index.js.map +1 -0
  66. package/dist/dom/patch.js +104 -0
  67. package/dist/dom/patch.js.map +1 -0
  68. package/dist/element/index.d.ts +29 -0
  69. package/dist/element/index.js +64 -0
  70. package/dist/element/index.js.map +1 -0
  71. package/dist/engine/blocks.js +774 -0
  72. package/dist/engine/blocks.js.map +1 -0
  73. package/dist/engine/entities.js +83 -0
  74. package/dist/engine/entities.js.map +1 -0
  75. package/dist/engine/entity-core.js +9 -0
  76. package/dist/engine/entity-core.js.map +1 -0
  77. package/dist/engine/entity-table.js +9 -0
  78. package/dist/engine/entity-table.js.map +1 -0
  79. package/dist/engine/html.d.ts +7 -0
  80. package/dist/engine/html.js +207 -0
  81. package/dist/engine/html.js.map +1 -0
  82. package/dist/engine/index.d.ts +7 -0
  83. package/dist/engine/index.js +74 -0
  84. package/dist/engine/index.js.map +1 -0
  85. package/dist/engine/inlines.js +852 -0
  86. package/dist/engine/inlines.js.map +1 -0
  87. package/dist/engine/types.d.ts +109 -0
  88. package/dist/engine/url.d.ts +11 -0
  89. package/dist/engine/url.js +16 -0
  90. package/dist/engine/url.js.map +1 -0
  91. package/dist/engine/visit.d.ts +10 -0
  92. package/dist/engine/visit.js +29 -0
  93. package/dist/engine/visit.js.map +1 -0
  94. package/dist/highlight/highlight.d.ts +4 -0
  95. package/dist/highlight/highlight.js +144 -0
  96. package/dist/highlight/highlight.js.map +1 -0
  97. package/dist/highlight/index.d.ts +4 -0
  98. package/dist/highlight/index.js +18 -0
  99. package/dist/highlight/index.js.map +1 -0
  100. package/dist/html/index.d.ts +4 -0
  101. package/dist/html/index.js +544 -0
  102. package/dist/html/index.js.map +1 -0
  103. package/dist/index.d.ts +27 -0
  104. package/dist/index.js +13 -0
  105. package/dist/math/index.d.ts +17 -0
  106. package/dist/math/index.js +20 -0
  107. package/dist/math/index.js.map +1 -0
  108. package/dist/math/typeset.d.ts +12 -0
  109. package/dist/math/typeset.js +74 -0
  110. package/dist/math/typeset.js.map +1 -0
  111. package/dist/mermaid/diagram.d.ts +8 -0
  112. package/dist/mermaid/diagram.js +114 -0
  113. package/dist/mermaid/diagram.js.map +1 -0
  114. package/dist/mermaid/drawing.js +139 -0
  115. package/dist/mermaid/drawing.js.map +1 -0
  116. package/dist/mermaid/icons.js +16 -0
  117. package/dist/mermaid/icons.js.map +1 -0
  118. package/dist/mermaid/index.d.ts +13 -0
  119. package/dist/mermaid/index.js +3 -0
  120. package/dist/mermaid/loader.d.ts +5 -0
  121. package/dist/mermaid/loader.js +18 -0
  122. package/dist/mermaid/loader.js.map +1 -0
  123. package/dist/mermaid/look.d.ts +16 -0
  124. package/dist/mermaid/look.js +167 -0
  125. package/dist/mermaid/look.js.map +1 -0
  126. package/dist/mermaid/normalize-svg.js +44 -0
  127. package/dist/mermaid/normalize-svg.js.map +1 -0
  128. package/dist/mermaid/renderer.d.ts +22 -0
  129. package/dist/mermaid/renderer.js +132 -0
  130. package/dist/mermaid/renderer.js.map +1 -0
  131. package/dist/mermaid/viewer.js +309 -0
  132. package/dist/mermaid/viewer.js.map +1 -0
  133. package/dist/prompt/index.d.ts +19 -0
  134. package/dist/prompt/index.js +54 -0
  135. package/dist/prompt/index.js.map +1 -0
  136. package/dist/react/callout.d.ts +9 -0
  137. package/dist/react/callout.js +12 -0
  138. package/dist/react/callout.js.map +1 -0
  139. package/dist/react/code-block.d.ts +18 -0
  140. package/dist/react/code-block.js +81 -0
  141. package/dist/react/code-block.js.map +1 -0
  142. package/dist/react/context.d.ts +18 -0
  143. package/dist/react/context.js +17 -0
  144. package/dist/react/context.js.map +1 -0
  145. package/dist/react/draw.d.ts +2 -0
  146. package/dist/react/draw.js +16 -0
  147. package/dist/react/draw.js.map +1 -0
  148. package/dist/react/file-tree.d.ts +16 -0
  149. package/dist/react/file-tree.js +69 -0
  150. package/dist/react/file-tree.js.map +1 -0
  151. package/dist/react/growing-code.js +36 -0
  152. package/dist/react/growing-code.js.map +1 -0
  153. package/dist/react/helpers.d.ts +6 -0
  154. package/dist/react/helpers.js +17 -0
  155. package/dist/react/helpers.js.map +1 -0
  156. package/dist/react/icons.js +23 -0
  157. package/dist/react/icons.js.map +1 -0
  158. package/dist/react/labels.js +9 -0
  159. package/dist/react/labels.js.map +1 -0
  160. package/dist/react/markdown.d.ts +78 -0
  161. package/dist/react/markdown.js +204 -0
  162. package/dist/react/markdown.js.map +1 -0
  163. package/dist/react/render.d.ts +8 -0
  164. package/dist/react/render.js +41 -0
  165. package/dist/react/render.js.map +1 -0
  166. package/dist/react/table-rows.js +66 -0
  167. package/dist/react/table-rows.js.map +1 -0
  168. package/dist/react/table.js +36 -0
  169. package/dist/react/table.js.map +1 -0
  170. package/dist/react/tabs.d.ts +25 -0
  171. package/dist/react/tabs.js +58 -0
  172. package/dist/react/tabs.js.map +1 -0
  173. package/dist/react/use-smooth-text.d.ts +6 -0
  174. package/dist/react/use-smooth-text.js +156 -0
  175. package/dist/react/use-smooth-text.js.map +1 -0
  176. package/dist/react/use-stage.d.ts +9 -0
  177. package/dist/react/use-stage.js +57 -0
  178. package/dist/react/use-stage.js.map +1 -0
  179. package/dist/remark.d.ts +20 -0
  180. package/dist/remark.js +10 -0
  181. package/dist/render/factory.d.ts +15 -0
  182. package/dist/render/labels.d.ts +41 -0
  183. package/dist/render/labels.js +43 -0
  184. package/dist/render/labels.js.map +1 -0
  185. package/dist/render/tree.js +312 -0
  186. package/dist/render/tree.js.map +1 -0
  187. package/dist/render/view.d.ts +55 -0
  188. package/dist/render/view.js +302 -0
  189. package/dist/render/view.js.map +1 -0
  190. package/dist/render/views.d.ts +16 -0
  191. package/dist/render/views.js +261 -0
  192. package/dist/render/views.js.map +1 -0
  193. package/dist/render/vnode.d.ts +21 -0
  194. package/dist/render/vnode.js +194 -0
  195. package/dist/render/vnode.js.map +1 -0
  196. package/dist/static/index.d.ts +28 -0
  197. package/dist/static/index.js +27 -0
  198. package/dist/static/index.js.map +1 -0
  199. package/dist/stream.d.ts +12 -0
  200. package/dist/stream.js +3 -0
  201. package/dist/styles.css +1351 -0
  202. package/dist/tui/code.d.ts +5 -0
  203. package/dist/tui/code.js +240 -0
  204. package/dist/tui/code.js.map +1 -0
  205. package/dist/tui/index.d.ts +54 -0
  206. package/dist/tui/index.js +99 -0
  207. package/dist/tui/index.js.map +1 -0
  208. package/dist/tui/math.js +242 -0
  209. package/dist/tui/math.js.map +1 -0
  210. package/dist/tui/printable.d.ts +12 -0
  211. package/dist/tui/printable.js +31 -0
  212. package/dist/tui/printable.js.map +1 -0
  213. package/dist/tui/render.d.ts +12 -0
  214. package/dist/tui/render.js +524 -0
  215. package/dist/tui/render.js.map +1 -0
  216. package/dist/tui/style.d.ts +35 -0
  217. package/dist/tui/style.js +77 -0
  218. package/dist/tui/style.js.map +1 -0
  219. package/dist/tui/table.js +73 -0
  220. package/dist/tui/table.js.map +1 -0
  221. package/dist/tui/width.d.ts +2 -0
  222. package/dist/tui/width.js +133 -0
  223. package/dist/tui/width.js.map +1 -0
  224. package/dist/tui/wrap.d.ts +8 -0
  225. package/dist/tui/wrap.js +190 -0
  226. package/dist/tui/wrap.js.map +1 -0
  227. package/package.json +127 -4
@@ -0,0 +1,852 @@
1
+ import { ENTITY, decodeEntity, isEscapable, normalizeUri, unescapeString } from "./entities.js";
2
+ // src/engine/inlines.ts
3
+ /**
4
+ * The inline pass: the text of one block read into emphasis, links, code spans and the rest, by
5
+ * the algorithm in the CommonMark spec (a delimiter stack for emphasis, a bracket stack for
6
+ * links). One pass over the text; the parser's state lives in the module, since a block's text
7
+ * is read from start to end before the next one begins.
8
+ */
9
+ const C_NEWLINE = 10;
10
+ const C_SPACE = 32;
11
+ const C_BANG = 33;
12
+ const C_AMPERSAND = 38;
13
+ const C_OPEN_PAREN = 40;
14
+ const C_CLOSE_PAREN = 41;
15
+ const C_ASTERISK = 42;
16
+ const C_COLON = 58;
17
+ const C_LESSTHAN = 60;
18
+ const C_OPEN_BRACKET = 91;
19
+ const C_BACKSLASH = 92;
20
+ const C_CLOSE_BRACKET = 93;
21
+ const C_CARET = 94;
22
+ const C_UNDERSCORE = 95;
23
+ const C_BACKTICK = 96;
24
+ const C_TILDE = 126;
25
+ const TAGNAME = "[A-Za-z][A-Za-z0-9-]*";
26
+ const OPENTAG = `<${TAGNAME}(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^"'=<>\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*/?>`;
27
+ const CLOSETAG = `</${TAGNAME}\\s*[>]`;
28
+ const HTMLTAG = `(?:${OPENTAG}|${CLOSETAG}|<!-->|<!--->|<!--[\\s\\S]*?-->|[<][?][\\s\\S]*?[?][>]|<![A-Za-z]+[^>]*>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>)`;
29
+ const reHtmlTag = new RegExp(HTMLTAG, "y");
30
+ const reEntity = new RegExp(ENTITY, "iy");
31
+ const reAutolink = /<([A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*)>/y;
32
+ const reEmailAutolink = /<([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])?)*)>/y;
33
+ const reLinkLabel = /\[(?:[^\\[\]]|\\[\s\S]){0,1000}\]/y;
34
+ const reLinkDestinationBraces = /<(?:[^<>\n\\\x00]|\\.)*>/y;
35
+ const reLinkTitle = /"(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'|\((?:\\[\s\S]|[^()\\])*\)/y;
36
+ const reSpaceAtEndOfLine = /[ \t]*(?:\n|$)/y;
37
+ const reFootnoteReference = /\[\^([^\]\s]+)\]/y;
38
+ const reUnicodeSpace = /\p{Zs}/u;
39
+ const reUnicodePunctuation = /[\p{P}\p{S}]/u;
40
+ /** Bare addresses: a URL with a scheme, one that starts `www.`, or an email address. */
41
+ const reBareLink = /(?:(?:https?|ftp):\/\/|www\.)[^\s<]*|(mailto:|xmpp:)?[A-Za-z0-9._+-]+@[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)+(\/[A-Za-z0-9@.]+)?/g;
42
+ /** Whether the text may hold a bare address: three searches for a few characters, no regex. */
43
+ const mayHoldBareLink = (text) => text.indexOf("@") !== -1 || text.indexOf("://") !== -1 || text.indexOf("www.") !== -1;
44
+ let subject = "";
45
+ let pos = 0;
46
+ let end = 0;
47
+ let ctx;
48
+ let root;
49
+ let delimiters = null;
50
+ let brackets = null;
51
+ /** Whether the text may hold a bare address (`www.`, `://`, `@`) to turn into a link. */
52
+ let bareLinks = false;
53
+ /** Lengths of backtick runs known to have no closing run in the rest of the text. */
54
+ let noBacktickCloser = null;
55
+ const inl = (type, value = "") => ({
56
+ type,
57
+ value,
58
+ parent: null,
59
+ prev: null,
60
+ next: null,
61
+ first: null,
62
+ last: null,
63
+ url: "",
64
+ title: "",
65
+ node: null
66
+ });
67
+ const append = (parent, child) => {
68
+ child.parent = parent;
69
+ child.prev = parent.last;
70
+ child.next = null;
71
+ if (parent.last) parent.last.next = child;
72
+ else parent.first = child;
73
+ parent.last = child;
74
+ };
75
+ const unlink = (node) => {
76
+ if (node.prev) node.prev.next = node.next;
77
+ else if (node.parent) node.parent.first = node.next;
78
+ if (node.next) node.next.prev = node.prev;
79
+ else if (node.parent) node.parent.last = node.prev;
80
+ node.parent = node.prev = node.next = null;
81
+ };
82
+ const insertAfter = (node, sibling) => {
83
+ sibling.parent = node.parent;
84
+ sibling.prev = node;
85
+ sibling.next = node.next;
86
+ if (node.next) node.next.prev = sibling;
87
+ else if (node.parent) node.parent.last = sibling;
88
+ node.next = sibling;
89
+ };
90
+ const text = (value) => {
91
+ const node = inl("text", value);
92
+ append(root, node);
93
+ return node;
94
+ };
95
+ /** Runs a sticky expression at the current place; the match, with the place moved past it. */
96
+ const match = (re) => {
97
+ re.lastIndex = pos;
98
+ const found = re.exec(subject);
99
+ if (found === null) return null;
100
+ pos = re.lastIndex;
101
+ return found[0];
102
+ };
103
+ /** Skips spaces, tabs and at most one line ending. */
104
+ const spnl = () => {
105
+ let code = subject.charCodeAt(pos);
106
+ while (code === C_SPACE || code === 9) code = subject.charCodeAt(++pos);
107
+ if (code === C_NEWLINE) {
108
+ code = subject.charCodeAt(++pos);
109
+ while (code === C_SPACE || code === 9) code = subject.charCodeAt(++pos);
110
+ }
111
+ };
112
+ const isWhitespace = (code) => code === 32 || code === 10 || code === 9 || code === 13 || code === 12 || code >= 128 && reUnicodeSpace.test(String.fromCodePoint(code));
113
+ const isPunctuation = (code) => code < 128 ? isEscapable(code) : reUnicodePunctuation.test(String.fromCodePoint(code));
114
+ const parseNewline = () => {
115
+ pos++;
116
+ const last = root.last;
117
+ if (last !== null && last.type === "text" && last.value.charCodeAt(last.value.length - 1) === 32) {
118
+ const hard = last.value.charCodeAt(last.value.length - 2) === 32;
119
+ last.value = last.value.replace(/ +$/, "");
120
+ append(root, inl(hard ? "break" : "softbreak"));
121
+ } else append(root, inl("softbreak"));
122
+ while (subject.charCodeAt(pos) === C_SPACE) pos++;
123
+ };
124
+ const parseBackslash = () => {
125
+ pos++;
126
+ const code = subject.charCodeAt(pos);
127
+ if (code === C_NEWLINE) {
128
+ pos++;
129
+ append(root, inl("break"));
130
+ while (subject.charCodeAt(pos) === C_SPACE) pos++;
131
+ } else if (isEscapable(code)) {
132
+ text(subject.charAt(pos));
133
+ pos++;
134
+ } else text("\\");
135
+ };
136
+ const parseBackticks = () => {
137
+ const start = pos;
138
+ while (subject.charCodeAt(pos) === C_BACKTICK) pos++;
139
+ const length = pos - start;
140
+ const after = pos;
141
+ if (noBacktickCloser === null || !noBacktickCloser.has(length)) {
142
+ let from = after;
143
+ for (;;) {
144
+ const open = subject.indexOf("`", from);
145
+ if (open === -1) break;
146
+ let close = open + 1;
147
+ while (subject.charCodeAt(close) === C_BACKTICK) close++;
148
+ if (close - open === length) {
149
+ let content = subject.slice(after, open);
150
+ if (content.indexOf("\n") !== -1) content = content.replace(/\n/g, " ");
151
+ if (content.charCodeAt(0) === 32 && content.charCodeAt(content.length - 1) === 32 && /[^ ]/.test(content)) content = content.slice(1, -1);
152
+ append(root, inl("inlineCode", content));
153
+ pos = close;
154
+ return;
155
+ }
156
+ from = close;
157
+ }
158
+ (noBacktickCloser ??= /* @__PURE__ */ new Set()).add(length);
159
+ }
160
+ pos = after;
161
+ text(subject.slice(start, after));
162
+ };
163
+ const parseDelimiters = (cc) => {
164
+ const start = pos;
165
+ while (subject.charCodeAt(pos) === cc) pos++;
166
+ const num = pos - start;
167
+ if (cc === C_TILDE && num > 2) {
168
+ text(subject.slice(start, pos));
169
+ return;
170
+ }
171
+ let before = C_NEWLINE;
172
+ if (start > 0) {
173
+ before = subject.charCodeAt(start - 1);
174
+ if (before >= 56320 && before <= 57343 && start > 1) before = subject.codePointAt(start - 2) ?? before;
175
+ }
176
+ const after = pos < end ? subject.codePointAt(pos) ?? C_NEWLINE : C_NEWLINE;
177
+ const afterIsWhitespace = isWhitespace(after);
178
+ const afterIsPunctuation = isPunctuation(after);
179
+ const beforeIsWhitespace = isWhitespace(before);
180
+ const beforeIsPunctuation = isPunctuation(before);
181
+ const leftFlanking = !afterIsWhitespace && (!afterIsPunctuation || beforeIsWhitespace || beforeIsPunctuation);
182
+ const rightFlanking = !beforeIsWhitespace && (!beforeIsPunctuation || afterIsWhitespace || afterIsPunctuation);
183
+ const canOpen = cc === C_UNDERSCORE ? leftFlanking && (!rightFlanking || beforeIsPunctuation) : leftFlanking;
184
+ const canClose = cc === C_UNDERSCORE ? rightFlanking && (!leftFlanking || afterIsPunctuation) : rightFlanking;
185
+ const node = text(subject.slice(start, pos));
186
+ if (!canOpen && !canClose) return;
187
+ const delimiter = {
188
+ cc,
189
+ num,
190
+ orig: num,
191
+ node,
192
+ prev: delimiters,
193
+ next: null,
194
+ canOpen,
195
+ canClose
196
+ };
197
+ if (delimiters !== null) delimiters.next = delimiter;
198
+ delimiters = delimiter;
199
+ };
200
+ const removeDelimiter = (delimiter) => {
201
+ if (delimiter.prev !== null) delimiter.prev.next = delimiter.next;
202
+ if (delimiter.next === null) delimiters = delimiter.prev;
203
+ else delimiter.next.prev = delimiter.prev;
204
+ };
205
+ /** Turns matching delimiter runs above `bottom` into emphasis, strong and strikethrough. */
206
+ const processEmphasis = (bottom) => {
207
+ const bottoms = [
208
+ bottom,
209
+ bottom,
210
+ bottom,
211
+ bottom,
212
+ bottom,
213
+ bottom,
214
+ bottom,
215
+ bottom,
216
+ bottom,
217
+ bottom,
218
+ bottom,
219
+ bottom,
220
+ bottom,
221
+ bottom
222
+ ];
223
+ let closer = delimiters;
224
+ while (closer !== null && closer.prev !== bottom) closer = closer.prev;
225
+ while (closer !== null) {
226
+ if (!closer.canClose) {
227
+ closer = closer.next;
228
+ continue;
229
+ }
230
+ const cc = closer.cc;
231
+ const key = cc === C_TILDE ? 11 + closer.orig : (cc === C_UNDERSCORE ? 0 : 6) + (closer.canOpen ? 3 : 0) + closer.orig % 3;
232
+ let opener = closer.prev;
233
+ let found = false;
234
+ while (opener !== null && opener !== bottom && opener !== bottoms[key]) {
235
+ if (opener.cc === cc && opener.canOpen) {
236
+ if (cc === C_TILDE) found = opener.orig === closer.orig;
237
+ else found = !((closer.canOpen || opener.canClose) && closer.orig % 3 !== 0 && (opener.orig + closer.orig) % 3 === 0);
238
+ if (found) break;
239
+ }
240
+ opener = opener.prev;
241
+ }
242
+ const old = closer;
243
+ if (found && opener !== null) {
244
+ const use = cc === C_TILDE ? closer.num : closer.num >= 2 && opener.num >= 2 ? 2 : 1;
245
+ opener.num -= use;
246
+ closer.num -= use;
247
+ opener.node.value = opener.node.value.slice(use);
248
+ closer.node.value = closer.node.value.slice(use);
249
+ const wrapper = inl(cc === C_TILDE ? "delete" : use === 1 ? "emphasis" : "strong");
250
+ let between = opener.node.next;
251
+ while (between !== null && between !== closer.node) {
252
+ const next = between.next;
253
+ unlink(between);
254
+ append(wrapper, between);
255
+ between = next;
256
+ }
257
+ insertAfter(opener.node, wrapper);
258
+ if (opener.next !== closer) {
259
+ opener.next = closer;
260
+ closer.prev = opener;
261
+ }
262
+ if (opener.num === 0) {
263
+ unlink(opener.node);
264
+ removeDelimiter(opener);
265
+ }
266
+ if (closer.num === 0) {
267
+ unlink(closer.node);
268
+ const next = closer.next;
269
+ removeDelimiter(closer);
270
+ closer = next;
271
+ }
272
+ } else {
273
+ closer = old.next;
274
+ bottoms[key] = old.prev;
275
+ if (!old.canOpen) removeDelimiter(old);
276
+ }
277
+ }
278
+ while (delimiters !== null && delimiters !== bottom) removeDelimiter(delimiters);
279
+ };
280
+ const addBracket = (node, index, image) => {
281
+ if (brackets !== null) brackets.bracketAfter = true;
282
+ brackets = {
283
+ node,
284
+ prev: brackets,
285
+ prevDelimiter: delimiters,
286
+ index,
287
+ image,
288
+ active: true,
289
+ bracketAfter: false
290
+ };
291
+ };
292
+ /** A link destination at the current place, or null. */
293
+ const parseLinkDestination = () => {
294
+ const braced = match(reLinkDestinationBraces);
295
+ if (braced !== null) return normalizeUri(unescapeString(braced.slice(1, -1)));
296
+ if (subject.charCodeAt(pos) === C_LESSTHAN) return null;
297
+ const start = pos;
298
+ let depth = 0;
299
+ let code = 0;
300
+ while (pos < end) {
301
+ code = subject.charCodeAt(pos);
302
+ if (code === C_BACKSLASH && isEscapable(subject.charCodeAt(pos + 1))) pos += 2;
303
+ else if (code === C_OPEN_PAREN) {
304
+ pos++;
305
+ depth++;
306
+ } else if (code === C_CLOSE_PAREN) {
307
+ if (depth < 1) break;
308
+ pos++;
309
+ depth--;
310
+ } else if (code <= 32 || code === 127) break;
311
+ else pos++;
312
+ }
313
+ if (pos === start && code !== C_CLOSE_PAREN) return null;
314
+ if (depth !== 0) return null;
315
+ return normalizeUri(unescapeString(subject.slice(start, pos)));
316
+ };
317
+ const parseLinkTitle = () => {
318
+ const title = match(reLinkTitle);
319
+ return title === null ? null : unescapeString(title.slice(1, -1));
320
+ };
321
+ /** The length of a link label (`[…]`) at the current place, with the place moved past it; or 0. */
322
+ const parseLinkLabel = () => {
323
+ const label = match(reLinkLabel);
324
+ return label === null || label.length > 1001 ? 0 : label.length;
325
+ };
326
+ /** A reference label as it is matched: without case, with its whitespace collapsed. */
327
+ const normalizeLabel = (label) => label.slice(1, -1).trim().replace(/[ \t\r\n]+/g, " ").toLowerCase().toUpperCase();
328
+ const parseCloseBracket = () => {
329
+ const start = pos;
330
+ pos++;
331
+ const opener = brackets;
332
+ if (opener === null) {
333
+ text("]");
334
+ return;
335
+ }
336
+ if (!opener.active) {
337
+ text("]");
338
+ brackets = opener.prev;
339
+ return;
340
+ }
341
+ const image = opener.image;
342
+ const savepos = pos;
343
+ let url = "";
344
+ let title = "";
345
+ let matched = false;
346
+ if (subject.charCodeAt(pos) === C_OPEN_PAREN) {
347
+ pos++;
348
+ spnl();
349
+ const destination = parseLinkDestination();
350
+ if (destination !== null) {
351
+ const beforeTitle = pos;
352
+ spnl();
353
+ let found = null;
354
+ if (pos !== beforeTitle) found = parseLinkTitle();
355
+ spnl();
356
+ if (subject.charCodeAt(pos) === C_CLOSE_PAREN) {
357
+ pos++;
358
+ url = destination;
359
+ title = found ?? "";
360
+ matched = true;
361
+ }
362
+ }
363
+ if (!matched) pos = savepos;
364
+ }
365
+ if (!matched) {
366
+ const beforeLabel = pos;
367
+ const length = parseLinkLabel();
368
+ let label = "";
369
+ if (length > 2) label = subject.slice(beforeLabel, beforeLabel + length);
370
+ else if (!opener.bracketAfter) label = subject.slice(opener.index, start + 1);
371
+ if (length === 0) pos = savepos;
372
+ if (label !== "") {
373
+ const reference = ctx.refs.get(normalizeLabel(label));
374
+ if (reference !== void 0) {
375
+ url = reference.url;
376
+ title = reference.title;
377
+ matched = true;
378
+ }
379
+ }
380
+ }
381
+ if (!matched) {
382
+ brackets = opener.prev;
383
+ pos = start + 1;
384
+ text("]");
385
+ return;
386
+ }
387
+ const node = inl(image ? "image" : "link");
388
+ node.url = url;
389
+ node.title = title;
390
+ let inside = opener.node.next;
391
+ while (inside !== null) {
392
+ const next = inside.next;
393
+ unlink(inside);
394
+ append(node, inside);
395
+ inside = next;
396
+ }
397
+ append(root, node);
398
+ processEmphasis(opener.prevDelimiter);
399
+ brackets = opener.prev;
400
+ unlink(opener.node);
401
+ if (!image) {
402
+ for (let bracket = brackets; bracket !== null; bracket = bracket.prev) if (!bracket.image) bracket.active = false;
403
+ }
404
+ };
405
+ const parseOpenBracket = () => {
406
+ if (ctx.footnotes.size > 0 && subject.charCodeAt(pos + 1) === C_CARET) {
407
+ reFootnoteReference.lastIndex = pos;
408
+ const found = reFootnoteReference.exec(subject);
409
+ const key = found === null ? "" : normalizeLabel(`[${found[1]}]`);
410
+ const label = ctx.footnotes.get(key);
411
+ if (label !== void 0) {
412
+ const uses = (ctx.footnoteUses.get(key) ?? 0) + 1;
413
+ ctx.footnoteUses.set(key, uses);
414
+ let index = 0;
415
+ for (const used of ctx.footnoteUses.keys()) {
416
+ index++;
417
+ if (used === key) break;
418
+ }
419
+ state.push({
420
+ type: "footnoteReference",
421
+ identifier: key.toLowerCase(),
422
+ label,
423
+ index,
424
+ occurrence: uses
425
+ });
426
+ pos = reFootnoteReference.lastIndex;
427
+ return;
428
+ }
429
+ }
430
+ const start = pos;
431
+ pos++;
432
+ addBracket(text("["), start, false);
433
+ };
434
+ const parseBang = () => {
435
+ const start = pos;
436
+ pos++;
437
+ if (subject.charCodeAt(pos) === C_OPEN_BRACKET && !(ctx.footnotes.size > 0 && subject.charCodeAt(pos + 1) === C_CARET)) {
438
+ pos++;
439
+ addBracket(text("!["), start + 1, true);
440
+ } else text("!");
441
+ };
442
+ const parseLessThan = () => {
443
+ reEmailAutolink.lastIndex = pos;
444
+ let found = reEmailAutolink.exec(subject);
445
+ if (found !== null) {
446
+ const address = found[1] ?? "";
447
+ const node = inl("link");
448
+ node.url = normalizeUri(`mailto:${address}`);
449
+ append(node, inl("text", address));
450
+ append(root, node);
451
+ pos = reEmailAutolink.lastIndex;
452
+ return;
453
+ }
454
+ reAutolink.lastIndex = pos;
455
+ found = reAutolink.exec(subject);
456
+ if (found !== null) {
457
+ const address = found[1] ?? "";
458
+ const node = inl("link");
459
+ node.url = normalizeUri(address);
460
+ append(node, inl("text", address));
461
+ append(root, node);
462
+ pos = reAutolink.lastIndex;
463
+ return;
464
+ }
465
+ const tag = match(reHtmlTag);
466
+ if (tag !== null) append(root, inl("html", tag));
467
+ else {
468
+ pos++;
469
+ text("<");
470
+ }
471
+ };
472
+ const parseEntity = () => {
473
+ reEntity.lastIndex = pos;
474
+ const found = reEntity.exec(subject);
475
+ const decoded = found === null ? null : decodeEntity(found[0]);
476
+ if (decoded === null) {
477
+ pos++;
478
+ text("&");
479
+ } else {
480
+ pos = reEntity.lastIndex;
481
+ text(decoded);
482
+ }
483
+ };
484
+ const isAlphanumeric = (code) => code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
485
+ /** Where a bare URL ends, by GitHub's rules for what trails a link without being part of it. */
486
+ const trimBareLink = (link) => {
487
+ let length = link.length;
488
+ for (;;) {
489
+ const last = link.charCodeAt(length - 1);
490
+ if ("?!.,:*_~'\"".indexOf(link.charAt(length - 1)) !== -1 && length > 0) length--;
491
+ else if (last === C_CLOSE_PAREN) {
492
+ let balance = 0;
493
+ for (let index = 0; index < length; index++) {
494
+ const code = link.charCodeAt(index);
495
+ if (code === C_OPEN_PAREN) balance++;
496
+ else if (code === C_CLOSE_PAREN) balance--;
497
+ }
498
+ if (balance >= 0) break;
499
+ length--;
500
+ } else if (last === 59) {
501
+ let start = length - 2;
502
+ while (start >= 0 && isAlphanumeric(link.charCodeAt(start))) start--;
503
+ if (start >= 0 && start < length - 2 && link.charCodeAt(start) === C_AMPERSAND) length = start;
504
+ else length--;
505
+ } else break;
506
+ }
507
+ return link.slice(0, length);
508
+ };
509
+ /** The bare addresses in a run of text, in order. */
510
+ const findBareLinks = (run) => {
511
+ const found = [];
512
+ reBareLink.lastIndex = 0;
513
+ for (let hit = reBareLink.exec(run); hit !== null; hit = reBareLink.exec(run)) {
514
+ let start = hit.index;
515
+ let link = hit[0];
516
+ const first = link.charCodeAt(0);
517
+ if (link.indexOf("@") !== -1 && !/^(?:https?:|ftp:|www\.)/.test(link)) {
518
+ let scheme = hit[1] ?? "";
519
+ if (scheme !== "" && start > 0 && isAlphanumeric(run.charCodeAt(start - 1))) {
520
+ start += scheme.length;
521
+ link = link.slice(scheme.length);
522
+ scheme = "";
523
+ }
524
+ if (hit[2] !== void 0 && scheme !== "xmpp:") link = link.slice(0, -hit[2].length);
525
+ while (link.charCodeAt(link.length - 1) === 46) link = link.slice(0, -1);
526
+ if (!isAlphanumeric(link.charCodeAt(link.length - 1))) {
527
+ reBareLink.lastIndex = start + link.length;
528
+ continue;
529
+ }
530
+ found.push({
531
+ start,
532
+ end: start + link.length,
533
+ url: scheme === "" ? `mailto:${link}` : link
534
+ });
535
+ reBareLink.lastIndex = start + link.length;
536
+ continue;
537
+ }
538
+ const www = first === 119;
539
+ if (start > 0) {
540
+ const before = run.charCodeAt(start - 1);
541
+ if (www ? !isWhitespace(before) && before !== C_ASTERISK && before !== C_UNDERSCORE && before !== C_TILDE && before !== C_OPEN_PAREN : before >= 65 && before <= 90 || before >= 97 && before <= 122 || before === 60) continue;
542
+ }
543
+ const host = www ? 0 : link.indexOf("://") + 3;
544
+ let hostEnd = host;
545
+ while (hostEnd < link.length) {
546
+ const code = link.charCodeAt(hostEnd);
547
+ if (code < 128 && !isAlphanumeric(code) && code !== 45 && code !== 46 && code !== C_UNDERSCORE) break;
548
+ hostEnd++;
549
+ }
550
+ const segments = link.slice(host, hostEnd).split(".");
551
+ if (hostEnd === host || www && (segments.length < 2 || link.length < 5)) continue;
552
+ if (segments.slice(-2).some((segment) => segment.indexOf("_") !== -1)) continue;
553
+ link = trimBareLink(link);
554
+ if (link.length <= host) continue;
555
+ found.push({
556
+ start,
557
+ end: start + link.length,
558
+ url: www ? `http://${link}` : link
559
+ });
560
+ reBareLink.lastIndex = start + link.length;
561
+ }
562
+ return found;
563
+ };
564
+ /** The plain text of a run of nodes: what an image's `alt` holds. */
565
+ const plainText = (nodes) => {
566
+ let out = "";
567
+ for (const node of nodes) if (node.type === "image") out += node.alt ?? "";
568
+ else if (node.children) out += plainText(node.children);
569
+ else if (node.type === "break") out += "\n";
570
+ else out += node.value ?? "";
571
+ return out;
572
+ };
573
+ /** A run of finished nodes with the bare addresses in its text made into links. */
574
+ const linkify = (nodes) => {
575
+ let out = null;
576
+ for (let index = 0; index < nodes.length; index++) {
577
+ const node = nodes[index];
578
+ const value = node.type === "text" ? node.value ?? "" : "";
579
+ const found = value !== "" && mayHoldBareLink(value) ? findBareLinks(value) : null;
580
+ if (found === null || found.length === 0) {
581
+ if (out !== null) out.push(node);
582
+ continue;
583
+ }
584
+ out ??= nodes.slice(0, index);
585
+ let from = 0;
586
+ for (const span of found) {
587
+ if (span.start > from) out.push({
588
+ type: "text",
589
+ value: value.slice(from, span.start)
590
+ });
591
+ out.push({
592
+ type: "link",
593
+ url: normalizeUri(span.url),
594
+ title: "",
595
+ children: [{
596
+ type: "text",
597
+ value: value.slice(span.start, span.end)
598
+ }]
599
+ });
600
+ from = span.end;
601
+ }
602
+ if (from < value.length) out.push({
603
+ type: "text",
604
+ value: value.slice(from)
605
+ });
606
+ }
607
+ return out ?? nodes;
608
+ };
609
+ /**
610
+ * The finished nodes under a parent, with text that ended up side by side joined. `links` is
611
+ * whether bare addresses in the text become links: not inside a link, which cannot hold another.
612
+ */
613
+ const finish = (parent, links) => {
614
+ const out = [];
615
+ let last;
616
+ for (let node = parent.first; node !== null; node = node.next) {
617
+ let made;
618
+ switch (node.type) {
619
+ case "text":
620
+ if (node.value === "") continue;
621
+ if (last !== void 0 && last.type === "text") {
622
+ last.value += node.value;
623
+ continue;
624
+ }
625
+ made = {
626
+ type: "text",
627
+ value: node.value
628
+ };
629
+ break;
630
+ case "link":
631
+ made = {
632
+ type: "link",
633
+ url: node.url,
634
+ title: node.title,
635
+ children: finish(node, false)
636
+ };
637
+ break;
638
+ case "image": {
639
+ const children = finish(node, false);
640
+ made = {
641
+ type: "image",
642
+ url: node.url,
643
+ title: node.title,
644
+ alt: plainText(children)
645
+ };
646
+ break;
647
+ }
648
+ case "emphasis":
649
+ case "strong":
650
+ case "delete":
651
+ made = {
652
+ type: node.type,
653
+ children: finish(node, links)
654
+ };
655
+ break;
656
+ case "softbreak":
657
+ if (last !== void 0 && last.type === "text") {
658
+ last.value += "\n";
659
+ continue;
660
+ }
661
+ made = {
662
+ type: "text",
663
+ value: "\n"
664
+ };
665
+ break;
666
+ case "break":
667
+ made = { type: "break" };
668
+ break;
669
+ case "node":
670
+ if (node.node === null) continue;
671
+ made = node.node;
672
+ break;
673
+ default: made = {
674
+ type: node.type,
675
+ value: node.value
676
+ };
677
+ }
678
+ out.push(made);
679
+ last = made;
680
+ }
681
+ return links ? linkify(out) : out;
682
+ };
683
+ /**
684
+ * Runs one parse of a document and puts back what the inline parser was reading before it. The
685
+ * parser keeps its place in this module, which is what makes it fast; an extension's rule that
686
+ * parses a text of its own (a caption, a cell) starts a second parse in the middle of the first,
687
+ * and the first one goes on from where it was.
688
+ */
689
+ const isolated = (run) => {
690
+ const held = [
691
+ subject,
692
+ pos,
693
+ end,
694
+ ctx,
695
+ root,
696
+ delimiters,
697
+ brackets,
698
+ bareLinks,
699
+ noBacktickCloser
700
+ ];
701
+ const heldText = state.text;
702
+ const heldPos = state.pos;
703
+ try {
704
+ return run();
705
+ } finally {
706
+ [subject, pos, end, ctx, root, delimiters, brackets, bareLinks, noBacktickCloser] = held;
707
+ state.text = heldText;
708
+ state.pos = heldPos;
709
+ }
710
+ };
711
+ const state = {
712
+ text: "",
713
+ pos: 0,
714
+ push: (node) => {
715
+ const wrapper = inl("node");
716
+ wrapper.node = node;
717
+ append(root, wrapper);
718
+ }
719
+ };
720
+ /** Reads the inline text of one block into nodes. */
721
+ const parseInlines = (source, context) => {
722
+ let length = source.length;
723
+ while (length > 0) {
724
+ const code = source.charCodeAt(length - 1);
725
+ if (code !== 32 && code !== 10 && code !== 9) break;
726
+ length--;
727
+ }
728
+ subject = length === source.length ? source : source.slice(0, length);
729
+ pos = 0;
730
+ end = length;
731
+ ctx = context;
732
+ root = inl("root");
733
+ delimiters = null;
734
+ brackets = null;
735
+ noBacktickCloser = null;
736
+ bareLinks = context.gfm && mayHoldBareLink(subject);
737
+ const special = context.special;
738
+ const rules = context.rules;
739
+ while (pos < end) {
740
+ const code = subject.charCodeAt(pos);
741
+ const own = code < 128 ? rules[code] : void 0;
742
+ if (own !== void 0) {
743
+ state.text = subject;
744
+ state.pos = pos;
745
+ let handled = false;
746
+ for (const rule of own) if (rule(state)) {
747
+ handled = true;
748
+ break;
749
+ }
750
+ if (handled) {
751
+ pos = state.pos;
752
+ continue;
753
+ }
754
+ }
755
+ switch (code) {
756
+ case C_NEWLINE:
757
+ parseNewline();
758
+ break;
759
+ case C_BACKSLASH:
760
+ parseBackslash();
761
+ break;
762
+ case C_BACKTICK:
763
+ parseBackticks();
764
+ break;
765
+ case C_ASTERISK:
766
+ case C_UNDERSCORE:
767
+ parseDelimiters(code);
768
+ break;
769
+ case C_TILDE:
770
+ if (context.gfm) parseDelimiters(code);
771
+ else {
772
+ pos++;
773
+ text("~");
774
+ }
775
+ break;
776
+ case C_OPEN_BRACKET:
777
+ parseOpenBracket();
778
+ break;
779
+ case C_BANG:
780
+ parseBang();
781
+ break;
782
+ case C_CLOSE_BRACKET:
783
+ parseCloseBracket();
784
+ break;
785
+ case C_LESSTHAN:
786
+ parseLessThan();
787
+ break;
788
+ case C_AMPERSAND:
789
+ parseEntity();
790
+ break;
791
+ default: {
792
+ const start = pos;
793
+ pos++;
794
+ while (pos < end) {
795
+ const next = subject.charCodeAt(pos);
796
+ if (next < 128 && special[next] === 1) break;
797
+ pos++;
798
+ }
799
+ text(subject.slice(start, pos));
800
+ }
801
+ }
802
+ }
803
+ processEmphasis(null);
804
+ const nodes = finish(root, bareLinks);
805
+ subject = "";
806
+ return nodes;
807
+ };
808
+ /**
809
+ * Reads one link reference definition from the start of a paragraph's text into `refs`. Returns
810
+ * how many characters it took, or 0 when the text does not start with a definition.
811
+ */
812
+ const parseReference = (source, refs) => {
813
+ subject = source;
814
+ pos = 0;
815
+ end = source.length;
816
+ const labelLength = parseLinkLabel();
817
+ if (labelLength === 0) return 0;
818
+ const label = source.slice(0, labelLength);
819
+ if (source.charCodeAt(pos) !== C_COLON) return 0;
820
+ pos++;
821
+ spnl();
822
+ const destination = parseLinkDestination();
823
+ if (destination === null) return 0;
824
+ const beforeTitle = pos;
825
+ spnl();
826
+ let title = null;
827
+ if (pos !== beforeTitle) title = parseLinkTitle();
828
+ if (title === null) pos = beforeTitle;
829
+ let atLineEnd = match(reSpaceAtEndOfLine) !== null;
830
+ if (!atLineEnd && title !== null) {
831
+ title = null;
832
+ pos = beforeTitle;
833
+ atLineEnd = match(reSpaceAtEndOfLine) !== null;
834
+ }
835
+ if (!atLineEnd) return 0;
836
+ const normalized = normalizeLabel(label);
837
+ if (normalized === "") return 0;
838
+ if (!refs.has(normalized)) refs.set(normalized, {
839
+ url: destination,
840
+ title: title ?? ""
841
+ });
842
+ return pos;
843
+ };
844
+ /** The characters that start an inline construct, as a table by ASCII code. */
845
+ const specialCharacters = (extra) => {
846
+ const table = /* @__PURE__ */ new Uint8Array(128);
847
+ for (const char of `\n\\\`*_~[]!<&${extra}`) table[char.charCodeAt(0)] = 1;
848
+ return table;
849
+ };
850
+ export { CLOSETAG, OPENTAG, isolated, normalizeLabel, parseInlines, parseReference, specialCharacters };
851
+
852
+ //# sourceMappingURL=inlines.js.map