@ohos-ports/markdown-exit 1.3.0-beta.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.
- package/LICENSE +22 -0
- package/README.md +127 -0
- package/dist/chunk-CzXV76rE.js +18 -0
- package/dist/index.d.ts +1133 -0
- package/dist/index.js +3950 -0
- package/package.json +52 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3950 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-CzXV76rE.js";
|
|
2
|
+
import { decodeHTML, decodeHTMLStrict } from "entities";
|
|
3
|
+
import * as mdurl from "mdurl";
|
|
4
|
+
import * as ucmicro from "uc.micro";
|
|
5
|
+
import LinkifyIt from "linkify-it";
|
|
6
|
+
import punycode from "punycode.js";
|
|
7
|
+
|
|
8
|
+
//#region src/common/utils.ts
|
|
9
|
+
var utils_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
arrayReplaceAt: () => arrayReplaceAt,
|
|
11
|
+
asciiTrim: () => asciiTrim,
|
|
12
|
+
assign: () => assign,
|
|
13
|
+
escapeHtml: () => escapeHtml,
|
|
14
|
+
escapeRE: () => escapeRE,
|
|
15
|
+
fromCodePoint: () => fromCodePoint,
|
|
16
|
+
has: () => has,
|
|
17
|
+
isMdAsciiPunct: () => isMdAsciiPunct,
|
|
18
|
+
isPromiseLike: () => isPromiseLike,
|
|
19
|
+
isPunctChar: () => isPunctChar,
|
|
20
|
+
isPunctCharCode: () => isPunctCharCode,
|
|
21
|
+
isSpace: () => isSpace,
|
|
22
|
+
isString: () => isString,
|
|
23
|
+
isValidEntityCode: () => isValidEntityCode,
|
|
24
|
+
isWhiteSpace: () => isWhiteSpace,
|
|
25
|
+
lib: () => lib,
|
|
26
|
+
normalizeReference: () => normalizeReference,
|
|
27
|
+
unescapeAll: () => unescapeAll,
|
|
28
|
+
unescapeMd: () => unescapeMd
|
|
29
|
+
});
|
|
30
|
+
function isString(obj) {
|
|
31
|
+
return typeof obj === "string";
|
|
32
|
+
}
|
|
33
|
+
const _hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
34
|
+
function has(object, key) {
|
|
35
|
+
return _hasOwnProperty.call(object, key);
|
|
36
|
+
}
|
|
37
|
+
function assign(target, ...sources) {
|
|
38
|
+
for (const s of sources) {
|
|
39
|
+
if (!s) continue;
|
|
40
|
+
if (typeof s !== "object") throw new TypeError("source must be object");
|
|
41
|
+
Object.assign(target, s);
|
|
42
|
+
}
|
|
43
|
+
return target;
|
|
44
|
+
}
|
|
45
|
+
function arrayReplaceAt(src, pos, newElements) {
|
|
46
|
+
return src.slice(0, pos).concat(newElements, src.slice(pos + 1));
|
|
47
|
+
}
|
|
48
|
+
function isValidEntityCode(c) {
|
|
49
|
+
if (c >= 55296 && c <= 57343) return false;
|
|
50
|
+
if (c >= 64976 && c <= 65007) return false;
|
|
51
|
+
if ((c & 65535) === 65535 || (c & 65535) === 65534) return false;
|
|
52
|
+
if (c >= 0 && c <= 8) return false;
|
|
53
|
+
if (c === 11) return false;
|
|
54
|
+
if (c >= 14 && c <= 31) return false;
|
|
55
|
+
if (c >= 127 && c <= 159) return false;
|
|
56
|
+
if (c > 1114111) return false;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
function fromCodePoint(c) {
|
|
60
|
+
if (c > 65535) {
|
|
61
|
+
c -= 65536;
|
|
62
|
+
const surrogate1 = 55296 + (c >> 10);
|
|
63
|
+
const surrogate2 = 56320 + (c & 1023);
|
|
64
|
+
return String.fromCharCode(surrogate1, surrogate2);
|
|
65
|
+
}
|
|
66
|
+
return String.fromCharCode(c);
|
|
67
|
+
}
|
|
68
|
+
const UNESCAPE_MD_RE = /\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g;
|
|
69
|
+
const UNESCAPE_ALL_RE = new RegExp(`${UNESCAPE_MD_RE.source}|${/&([a-z#][a-z0-9]{1,31});/gi.source}`, "gi");
|
|
70
|
+
const DIGITAL_ENTITY_TEST_RE = /^#(x[a-f0-9]{1,8}|\d{1,8})$/i;
|
|
71
|
+
function replaceEntityPattern(match, name) {
|
|
72
|
+
if (name.charCodeAt(0) === 35 && DIGITAL_ENTITY_TEST_RE.test(name)) {
|
|
73
|
+
const code$1 = name[1].toLowerCase() === "x" ? Number.parseInt(name.slice(2), 16) : Number.parseInt(name.slice(1), 10);
|
|
74
|
+
if (isValidEntityCode(code$1)) return fromCodePoint(code$1);
|
|
75
|
+
return match;
|
|
76
|
+
}
|
|
77
|
+
const decoded = decodeHTML(match);
|
|
78
|
+
if (decoded !== match) return decoded;
|
|
79
|
+
return match;
|
|
80
|
+
}
|
|
81
|
+
function unescapeMd(str) {
|
|
82
|
+
if (!str.includes("\\")) return str;
|
|
83
|
+
return str.replace(UNESCAPE_MD_RE, "$1");
|
|
84
|
+
}
|
|
85
|
+
function unescapeAll(str) {
|
|
86
|
+
if (!str.includes("\\") && !str.includes("&")) return str;
|
|
87
|
+
return str.replace(UNESCAPE_ALL_RE, (match, escaped, entity$1) => {
|
|
88
|
+
if (escaped) return escaped;
|
|
89
|
+
return replaceEntityPattern(match, entity$1);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const HTML_ESCAPE_TEST_RE = /[&<>"]/;
|
|
93
|
+
const HTML_ESCAPE_REPLACE_RE = /[&<>"]/g;
|
|
94
|
+
const HTML_REPLACEMENTS = {
|
|
95
|
+
"&": "&",
|
|
96
|
+
"<": "<",
|
|
97
|
+
">": ">",
|
|
98
|
+
"\"": """
|
|
99
|
+
};
|
|
100
|
+
function replaceUnsafeChar(ch) {
|
|
101
|
+
return HTML_REPLACEMENTS[ch];
|
|
102
|
+
}
|
|
103
|
+
function escapeHtml(str) {
|
|
104
|
+
if (HTML_ESCAPE_TEST_RE.test(str)) return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar);
|
|
105
|
+
return str;
|
|
106
|
+
}
|
|
107
|
+
const REGEXP_ESCAPE_RE = /[.?*+^$[\]\\(){}|-]/g;
|
|
108
|
+
function escapeRE(str) {
|
|
109
|
+
return str.replace(REGEXP_ESCAPE_RE, "\\$&");
|
|
110
|
+
}
|
|
111
|
+
function isSpace(code$1) {
|
|
112
|
+
switch (code$1) {
|
|
113
|
+
case 9:
|
|
114
|
+
case 32: return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function isWhiteSpace(code$1) {
|
|
119
|
+
if (code$1 >= 8192 && code$1 <= 8202) return true;
|
|
120
|
+
switch (code$1) {
|
|
121
|
+
case 9:
|
|
122
|
+
case 10:
|
|
123
|
+
case 11:
|
|
124
|
+
case 12:
|
|
125
|
+
case 13:
|
|
126
|
+
case 32:
|
|
127
|
+
case 160:
|
|
128
|
+
case 5760:
|
|
129
|
+
case 8239:
|
|
130
|
+
case 8287:
|
|
131
|
+
case 12288: return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
function isPunctChar(ch) {
|
|
136
|
+
return ucmicro.P.test(ch) || ucmicro.S.test(ch);
|
|
137
|
+
}
|
|
138
|
+
function isPunctCharCode(code$1) {
|
|
139
|
+
return isPunctChar(fromCodePoint(code$1));
|
|
140
|
+
}
|
|
141
|
+
function isMdAsciiPunct(ch) {
|
|
142
|
+
switch (ch) {
|
|
143
|
+
case 33:
|
|
144
|
+
case 34:
|
|
145
|
+
case 35:
|
|
146
|
+
case 36:
|
|
147
|
+
case 37:
|
|
148
|
+
case 38:
|
|
149
|
+
case 39:
|
|
150
|
+
case 40:
|
|
151
|
+
case 41:
|
|
152
|
+
case 42:
|
|
153
|
+
case 43:
|
|
154
|
+
case 44:
|
|
155
|
+
case 45:
|
|
156
|
+
case 46:
|
|
157
|
+
case 47:
|
|
158
|
+
case 58:
|
|
159
|
+
case 59:
|
|
160
|
+
case 60:
|
|
161
|
+
case 61:
|
|
162
|
+
case 62:
|
|
163
|
+
case 63:
|
|
164
|
+
case 64:
|
|
165
|
+
case 91:
|
|
166
|
+
case 92:
|
|
167
|
+
case 93:
|
|
168
|
+
case 94:
|
|
169
|
+
case 95:
|
|
170
|
+
case 96:
|
|
171
|
+
case 123:
|
|
172
|
+
case 124:
|
|
173
|
+
case 125:
|
|
174
|
+
case 126: return true;
|
|
175
|
+
default: return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function normalizeReference(str) {
|
|
179
|
+
str = str.trim().replace(/\s+/g, " ");
|
|
180
|
+
if ("ẞ".toLowerCase() === "Ṿ")
|
|
181
|
+
/* c8 ignore next 2 */
|
|
182
|
+
str = str.replace(/ẞ/g, "ß");
|
|
183
|
+
return str.toLowerCase().toUpperCase();
|
|
184
|
+
}
|
|
185
|
+
function isAsciiTrimmable(c) {
|
|
186
|
+
return c === 32 || c === 9 || c === 10 || c === 13;
|
|
187
|
+
}
|
|
188
|
+
function asciiTrim(str) {
|
|
189
|
+
let start = 0;
|
|
190
|
+
for (; start < str.length; start++) if (!isAsciiTrimmable(str.charCodeAt(start))) break;
|
|
191
|
+
let end = str.length - 1;
|
|
192
|
+
for (; end >= start; end--) if (!isAsciiTrimmable(str.charCodeAt(end))) break;
|
|
193
|
+
return str.slice(start, end + 1);
|
|
194
|
+
}
|
|
195
|
+
function isPromiseLike(v) {
|
|
196
|
+
return typeof v?.then === "function";
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Re-export libraries commonly used in both markdown-it and its plugins,
|
|
200
|
+
* so plugins won't have to depend on them explicitly, which reduces their
|
|
201
|
+
* bundled size (e.g. a browser build).
|
|
202
|
+
*/
|
|
203
|
+
const lib = {
|
|
204
|
+
mdurl,
|
|
205
|
+
ucmicro
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/token.ts
|
|
210
|
+
var Token = class {
|
|
211
|
+
/**
|
|
212
|
+
* Type of the token, e.g. "paragraph_open"
|
|
213
|
+
*/
|
|
214
|
+
type;
|
|
215
|
+
/**
|
|
216
|
+
* HTML tag name, e.g. "p"
|
|
217
|
+
*/
|
|
218
|
+
tag;
|
|
219
|
+
/**
|
|
220
|
+
* HTML attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]`
|
|
221
|
+
*/
|
|
222
|
+
attrs = null;
|
|
223
|
+
/**
|
|
224
|
+
* Source map info. Format: `[ line_begin, line_end ]`
|
|
225
|
+
*/
|
|
226
|
+
map = null;
|
|
227
|
+
/**
|
|
228
|
+
* Level change (number in {-1, 0, 1} set)
|
|
229
|
+
*/
|
|
230
|
+
nesting;
|
|
231
|
+
/**
|
|
232
|
+
* Nesting level, the same as `state.level`
|
|
233
|
+
*/
|
|
234
|
+
level = 0;
|
|
235
|
+
/**
|
|
236
|
+
* An array of child nodes (inline and img tokens)
|
|
237
|
+
*/
|
|
238
|
+
children = null;
|
|
239
|
+
/**
|
|
240
|
+
* In a case of self-closing tag (code, html, fence, etc.),
|
|
241
|
+
* it has contents of this tag.
|
|
242
|
+
*/
|
|
243
|
+
content = "";
|
|
244
|
+
/**
|
|
245
|
+
* '*' or '_' for emphasis, fence string for fence, etc.
|
|
246
|
+
*/
|
|
247
|
+
markup = "";
|
|
248
|
+
/**
|
|
249
|
+
* - Info string for "fence" tokens
|
|
250
|
+
* - The value "auto" for autolink "link_open" and "link_close" tokens
|
|
251
|
+
* - The string value of the item marker for ordered-list "list_item_open" tokens
|
|
252
|
+
* - Label string of "reference" tokens
|
|
253
|
+
*/
|
|
254
|
+
info = "";
|
|
255
|
+
/**
|
|
256
|
+
* A place for plugins to store an arbitrary data
|
|
257
|
+
*/
|
|
258
|
+
meta = null;
|
|
259
|
+
/**
|
|
260
|
+
* True for block-level tokens, false for inline tokens.
|
|
261
|
+
* Used in renderer to calculate line breaks
|
|
262
|
+
*/
|
|
263
|
+
block = false;
|
|
264
|
+
/**
|
|
265
|
+
* If it's true, ignore this element when rendering. Used for tight lists
|
|
266
|
+
* to hide paragraphs.
|
|
267
|
+
*/
|
|
268
|
+
hidden = false;
|
|
269
|
+
/**
|
|
270
|
+
* Create new token and fill passed properties.
|
|
271
|
+
*/
|
|
272
|
+
constructor(type, tag, nesting) {
|
|
273
|
+
this.type = type;
|
|
274
|
+
this.tag = tag;
|
|
275
|
+
this.nesting = nesting;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Search attribute index by name.
|
|
279
|
+
*/
|
|
280
|
+
attrIndex(name) {
|
|
281
|
+
if (!this.attrs) return -1;
|
|
282
|
+
const attrs = this.attrs;
|
|
283
|
+
for (let i = 0, len = attrs.length; i < len; i++) if (attrs[i][0] === name) return i;
|
|
284
|
+
return -1;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Add `[ name, value ]` attribute to list. Init attrs if necessary
|
|
288
|
+
*/
|
|
289
|
+
attrPush(attrData) {
|
|
290
|
+
if (this.attrs) this.attrs.push(attrData);
|
|
291
|
+
else this.attrs = [attrData];
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Set `name` attribute to `value`. Override old value if exists.
|
|
295
|
+
*/
|
|
296
|
+
attrSet(name, value) {
|
|
297
|
+
const idx = this.attrIndex(name);
|
|
298
|
+
const attrData = [name, value];
|
|
299
|
+
if (idx < 0) this.attrPush(attrData);
|
|
300
|
+
else this.attrs[idx] = attrData;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Get the value of attribute `name`, or null if it does not exist.
|
|
304
|
+
*/
|
|
305
|
+
attrGet(name) {
|
|
306
|
+
const idx = this.attrIndex(name);
|
|
307
|
+
let value = null;
|
|
308
|
+
if (idx >= 0) value = this.attrs[idx][1];
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Join value to existing attribute via space. Or create new attribute if not
|
|
313
|
+
* exists. Useful to operate with token classes.
|
|
314
|
+
*/
|
|
315
|
+
attrJoin(name, value) {
|
|
316
|
+
const idx = this.attrIndex(name);
|
|
317
|
+
if (idx < 0) this.attrPush([name, value]);
|
|
318
|
+
else this.attrs[idx][1] = `${this.attrs[idx][1]} ${value}`;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/parser/block/state_block.ts
|
|
324
|
+
var StateBlock = class {
|
|
325
|
+
src;
|
|
326
|
+
/**
|
|
327
|
+
* link to parser instance
|
|
328
|
+
*/
|
|
329
|
+
md;
|
|
330
|
+
env;
|
|
331
|
+
tokens;
|
|
332
|
+
/**
|
|
333
|
+
* line begin offsets for fast jumps
|
|
334
|
+
*/
|
|
335
|
+
bMarks = [];
|
|
336
|
+
/**
|
|
337
|
+
* line end offsets for fast jumps
|
|
338
|
+
*/
|
|
339
|
+
eMarks = [];
|
|
340
|
+
/**
|
|
341
|
+
* offsets of the first non-space characters (tabs not expanded)
|
|
342
|
+
*/
|
|
343
|
+
tShift = [];
|
|
344
|
+
/**
|
|
345
|
+
* indents for each line (tabs expanded)
|
|
346
|
+
*/
|
|
347
|
+
sCount = [];
|
|
348
|
+
/**
|
|
349
|
+
* An amount of virtual spaces (tabs expanded) between beginning
|
|
350
|
+
* of each line (bMarks) and real beginning of that line.
|
|
351
|
+
*
|
|
352
|
+
* It exists only as a hack because blockquotes override bMarks
|
|
353
|
+
* losing information in the process.
|
|
354
|
+
*
|
|
355
|
+
* It's used only when expanding tabs, you can think about it as
|
|
356
|
+
* an initial tab length, e.g. bsCount=21 applied to string `\t123`
|
|
357
|
+
* means first tab should be expanded to 4-21%4 === 3 spaces.
|
|
358
|
+
*/
|
|
359
|
+
bsCount = [];
|
|
360
|
+
/**
|
|
361
|
+
* required block content indent (for example, if we are
|
|
362
|
+
* inside a list, it would be positioned after list marker)
|
|
363
|
+
*/
|
|
364
|
+
blkIndent = 0;
|
|
365
|
+
/**
|
|
366
|
+
* line index in src
|
|
367
|
+
*/
|
|
368
|
+
line = 0;
|
|
369
|
+
/**
|
|
370
|
+
* lines count
|
|
371
|
+
*/
|
|
372
|
+
lineMax = 0;
|
|
373
|
+
/**
|
|
374
|
+
* loose/tight mode for lists
|
|
375
|
+
*/
|
|
376
|
+
tight = false;
|
|
377
|
+
/**
|
|
378
|
+
* indent of the current dd block (-1 if there isn't any)
|
|
379
|
+
*/
|
|
380
|
+
ddIndent = -1;
|
|
381
|
+
/**
|
|
382
|
+
* indent of the current list block (-1 if there isn't any)
|
|
383
|
+
*/
|
|
384
|
+
listIndent = -1;
|
|
385
|
+
/**
|
|
386
|
+
* used in lists to determine if they interrupt a paragraph
|
|
387
|
+
*/
|
|
388
|
+
parentType = "root";
|
|
389
|
+
level = 0;
|
|
390
|
+
/**
|
|
391
|
+
* re-export Token class to use in block rules
|
|
392
|
+
*/
|
|
393
|
+
Token = Token;
|
|
394
|
+
constructor(src, md, env, tokens) {
|
|
395
|
+
this.src = src;
|
|
396
|
+
this.md = md;
|
|
397
|
+
this.env = env;
|
|
398
|
+
this.tokens = tokens;
|
|
399
|
+
const s = this.src;
|
|
400
|
+
const len = s.length;
|
|
401
|
+
for (let start = 0; start < len;) {
|
|
402
|
+
const lineEnd = s.indexOf("\n", start);
|
|
403
|
+
const end = lineEnd === -1 ? len : lineEnd;
|
|
404
|
+
let indent = 0;
|
|
405
|
+
let offset = 0;
|
|
406
|
+
let pos = start;
|
|
407
|
+
while (pos < end) {
|
|
408
|
+
const ch = s.charCodeAt(pos);
|
|
409
|
+
if (isSpace(ch)) {
|
|
410
|
+
indent++;
|
|
411
|
+
offset += ch === 9 ? 4 - offset % 4 : 1;
|
|
412
|
+
pos++;
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
this.bMarks.push(start);
|
|
418
|
+
this.eMarks.push(end);
|
|
419
|
+
this.tShift.push(indent);
|
|
420
|
+
this.sCount.push(offset);
|
|
421
|
+
this.bsCount.push(0);
|
|
422
|
+
start = end + 1;
|
|
423
|
+
}
|
|
424
|
+
this.bMarks.push(s.length);
|
|
425
|
+
this.eMarks.push(s.length);
|
|
426
|
+
this.tShift.push(0);
|
|
427
|
+
this.sCount.push(0);
|
|
428
|
+
this.bsCount.push(0);
|
|
429
|
+
this.lineMax = this.bMarks.length - 1;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Push new token to "stream".
|
|
433
|
+
*/
|
|
434
|
+
push(type, tag, nesting) {
|
|
435
|
+
const token = new Token(type, tag, nesting);
|
|
436
|
+
token.block = true;
|
|
437
|
+
if (nesting < 0) this.level--;
|
|
438
|
+
token.level = this.level;
|
|
439
|
+
if (nesting > 0) this.level++;
|
|
440
|
+
this.tokens.push(token);
|
|
441
|
+
return token;
|
|
442
|
+
}
|
|
443
|
+
isEmpty(line) {
|
|
444
|
+
return this.bMarks[line] + this.tShift[line] >= this.eMarks[line];
|
|
445
|
+
}
|
|
446
|
+
skipEmptyLines(from) {
|
|
447
|
+
for (let max = this.lineMax; from < max; from++) if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) break;
|
|
448
|
+
return from;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Skip spaces from given position.
|
|
452
|
+
*/
|
|
453
|
+
skipSpaces(pos) {
|
|
454
|
+
const src = this.src;
|
|
455
|
+
for (let max = src.length; pos < max; pos++) if (!isSpace(src.charCodeAt(pos))) break;
|
|
456
|
+
return pos;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Skip spaces from given position in reverse.
|
|
460
|
+
*/
|
|
461
|
+
skipSpacesBack(pos, min) {
|
|
462
|
+
if (pos <= min) return pos;
|
|
463
|
+
const src = this.src;
|
|
464
|
+
while (pos > min) if (!isSpace(src.charCodeAt(--pos))) return pos + 1;
|
|
465
|
+
return pos;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Skip char codes from given position
|
|
469
|
+
*/
|
|
470
|
+
skipChars(pos, code$1) {
|
|
471
|
+
const src = this.src;
|
|
472
|
+
for (let max = src.length; pos < max; pos++) if (src.charCodeAt(pos) !== code$1) break;
|
|
473
|
+
return pos;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Skip char codes reverse from given position - 1
|
|
477
|
+
*/
|
|
478
|
+
skipCharsBack(pos, code$1, min) {
|
|
479
|
+
if (pos <= min) return pos;
|
|
480
|
+
const src = this.src;
|
|
481
|
+
while (pos > min) if (code$1 !== src.charCodeAt(--pos)) return pos + 1;
|
|
482
|
+
return pos;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* cut lines range from source.
|
|
486
|
+
*/
|
|
487
|
+
getLines(begin, end, indent, keepLastLF) {
|
|
488
|
+
if (begin >= end) return "";
|
|
489
|
+
const queue = new Array(end - begin);
|
|
490
|
+
const src = this.src;
|
|
491
|
+
for (let i = 0, line = begin; line < end; line++, i++) {
|
|
492
|
+
let lineIndent = 0;
|
|
493
|
+
const lineStart = this.bMarks[line];
|
|
494
|
+
let first = lineStart;
|
|
495
|
+
let last;
|
|
496
|
+
if (line + 1 < end || keepLastLF) last = this.eMarks[line] + 1;
|
|
497
|
+
else last = this.eMarks[line];
|
|
498
|
+
while (first < last && lineIndent < indent) {
|
|
499
|
+
const ch = src.charCodeAt(first);
|
|
500
|
+
if (isSpace(ch)) if (ch === 9) lineIndent += 4 - (lineIndent + this.bsCount[line]) % 4;
|
|
501
|
+
else lineIndent++;
|
|
502
|
+
else if (first - lineStart < this.tShift[line]) lineIndent++;
|
|
503
|
+
else break;
|
|
504
|
+
first++;
|
|
505
|
+
}
|
|
506
|
+
if (lineIndent > indent) queue[i] = " ".repeat(lineIndent - indent) + this.src.slice(first, last);
|
|
507
|
+
else queue[i] = this.src.slice(first, last);
|
|
508
|
+
}
|
|
509
|
+
return queue.join("");
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
//#endregion
|
|
514
|
+
//#region src/parser/core/state_core.ts
|
|
515
|
+
var StateCore = class {
|
|
516
|
+
src;
|
|
517
|
+
env;
|
|
518
|
+
tokens = [];
|
|
519
|
+
inlineMode = false;
|
|
520
|
+
/**
|
|
521
|
+
* link to parser instance
|
|
522
|
+
*/
|
|
523
|
+
md;
|
|
524
|
+
constructor(src, md, env) {
|
|
525
|
+
this.src = src;
|
|
526
|
+
this.env = env;
|
|
527
|
+
this.md = md;
|
|
528
|
+
}
|
|
529
|
+
Token = Token;
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
//#endregion
|
|
533
|
+
//#region src/parser/inline/state_inline.ts
|
|
534
|
+
var StateInline = class {
|
|
535
|
+
src;
|
|
536
|
+
env;
|
|
537
|
+
md;
|
|
538
|
+
tokens;
|
|
539
|
+
tokens_meta;
|
|
540
|
+
pos = 0;
|
|
541
|
+
posMax;
|
|
542
|
+
level = 0;
|
|
543
|
+
pending = "";
|
|
544
|
+
pendingLevel = 0;
|
|
545
|
+
/**
|
|
546
|
+
* Stores { start: end } pairs. Useful for backtrack
|
|
547
|
+
* optimization of pairs parse (emphasis, strikes).
|
|
548
|
+
*/
|
|
549
|
+
cache = {};
|
|
550
|
+
/**
|
|
551
|
+
* List of emphasis-like delimiters for current tag
|
|
552
|
+
*/
|
|
553
|
+
delimiters = [];
|
|
554
|
+
/**
|
|
555
|
+
* Stack of delimiter lists for upper level tags
|
|
556
|
+
*/
|
|
557
|
+
_prev_delimiters = [];
|
|
558
|
+
/**
|
|
559
|
+
* backtick length => last seen position
|
|
560
|
+
*/
|
|
561
|
+
backticks = {};
|
|
562
|
+
backticksScanned = false;
|
|
563
|
+
/**
|
|
564
|
+
* Counter used to disable inline linkify-it execution
|
|
565
|
+
* inside `<a>` and markdown links
|
|
566
|
+
*/
|
|
567
|
+
linkLevel = 0;
|
|
568
|
+
constructor(src, md, env, outTokens) {
|
|
569
|
+
this.src = src;
|
|
570
|
+
this.env = env;
|
|
571
|
+
this.md = md;
|
|
572
|
+
this.tokens = outTokens;
|
|
573
|
+
this.tokens_meta = new Array(outTokens.length);
|
|
574
|
+
this.posMax = this.src.length;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Flush pending text
|
|
578
|
+
*/
|
|
579
|
+
pushPending() {
|
|
580
|
+
const token = new Token("text", "", 0);
|
|
581
|
+
token.content = this.pending;
|
|
582
|
+
token.level = this.pendingLevel;
|
|
583
|
+
this.tokens.push(token);
|
|
584
|
+
this.pending = "";
|
|
585
|
+
return token;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Push new token to "stream".
|
|
589
|
+
* If pending text exists - flush it as text token
|
|
590
|
+
*/
|
|
591
|
+
push(type, tag, nesting) {
|
|
592
|
+
if (this.pending) this.pushPending();
|
|
593
|
+
const token = new Token(type, tag, nesting);
|
|
594
|
+
let token_meta = null;
|
|
595
|
+
if (nesting < 0) {
|
|
596
|
+
this.level--;
|
|
597
|
+
this.delimiters = this._prev_delimiters.pop() ?? [];
|
|
598
|
+
}
|
|
599
|
+
token.level = this.level;
|
|
600
|
+
if (nesting > 0) {
|
|
601
|
+
this.level++;
|
|
602
|
+
this._prev_delimiters.push(this.delimiters);
|
|
603
|
+
this.delimiters = [];
|
|
604
|
+
token_meta = { delimiters: this.delimiters };
|
|
605
|
+
}
|
|
606
|
+
this.pendingLevel = this.level;
|
|
607
|
+
this.tokens.push(token);
|
|
608
|
+
this.tokens_meta.push(token_meta);
|
|
609
|
+
return token;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Scan a sequence of emphasis-like markers, and determine whether
|
|
613
|
+
* it can start an emphasis sequence or end an emphasis sequence.
|
|
614
|
+
*
|
|
615
|
+
* - start - position to scan from (it should point at a valid marker);
|
|
616
|
+
* - canSplitWord - determine if these markers can be found inside a word
|
|
617
|
+
*/
|
|
618
|
+
scanDelims(start, canSplitWord) {
|
|
619
|
+
const src = this.src;
|
|
620
|
+
const max = this.posMax;
|
|
621
|
+
const marker = src.charCodeAt(start);
|
|
622
|
+
let lastChar;
|
|
623
|
+
if (start === 0) lastChar = 32;
|
|
624
|
+
else if (start === 1) {
|
|
625
|
+
lastChar = this.src.charCodeAt(0);
|
|
626
|
+
if ((lastChar & 63488) === 55296) lastChar = 65533;
|
|
627
|
+
} else {
|
|
628
|
+
lastChar = this.src.charCodeAt(start - 1);
|
|
629
|
+
if ((lastChar & 64512) === 56320) {
|
|
630
|
+
const highSurr = this.src.charCodeAt(start - 2);
|
|
631
|
+
lastChar = (highSurr & 64512) === 55296 ? 65536 + (highSurr - 55296 << 10) + (lastChar - 56320) : 65533;
|
|
632
|
+
} else if ((lastChar & 64512) === 55296) lastChar = 65533;
|
|
633
|
+
}
|
|
634
|
+
let pos = start;
|
|
635
|
+
while (pos < max && src.charCodeAt(pos) === marker) pos++;
|
|
636
|
+
const count = pos - start;
|
|
637
|
+
let nextChar = pos < max ? this.src.charCodeAt(pos) : 32;
|
|
638
|
+
if ((nextChar & 64512) === 55296) {
|
|
639
|
+
const lowSurr = this.src.charCodeAt(pos + 1);
|
|
640
|
+
nextChar = (lowSurr & 64512) === 56320 ? 65536 + (nextChar - 55296 << 10) + (lowSurr - 56320) : 65533;
|
|
641
|
+
} else if ((nextChar & 64512) === 56320) nextChar = 65533;
|
|
642
|
+
const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
|
|
643
|
+
const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
|
|
644
|
+
const isLastWhiteSpace = isWhiteSpace(lastChar);
|
|
645
|
+
const isNextWhiteSpace = isWhiteSpace(nextChar);
|
|
646
|
+
const left_flanking = !isNextWhiteSpace && (!isNextPunctChar || isLastWhiteSpace || isLastPunctChar);
|
|
647
|
+
const right_flanking = !isLastWhiteSpace && (!isLastPunctChar || isNextWhiteSpace || isNextPunctChar);
|
|
648
|
+
return {
|
|
649
|
+
can_open: left_flanking && (canSplitWord || !right_flanking || isLastPunctChar),
|
|
650
|
+
can_close: right_flanking && (canSplitWord || !left_flanking || isNextPunctChar),
|
|
651
|
+
length: count
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
Token = Token;
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
//#endregion
|
|
658
|
+
//#region src/parser/ruler.ts
|
|
659
|
+
/**
|
|
660
|
+
* Helper class, used by {@link MarkdownExit.core}, {@link MarkdownExit.block} and
|
|
661
|
+
* {@link MarkdownExit.inline} to manage sequences of functions (rules):
|
|
662
|
+
*
|
|
663
|
+
* - keep rules in defined order
|
|
664
|
+
* - assign the name to each rule
|
|
665
|
+
* - enable/disable rules
|
|
666
|
+
* - add/replace rules
|
|
667
|
+
* - allow assign rules to additional named chains (in the same)
|
|
668
|
+
* - caching lists of active rules
|
|
669
|
+
*
|
|
670
|
+
* You will not need use this class directly until write plugins. For simple
|
|
671
|
+
* rules control use {@link MarkdownExit.disable}, {@link MarkdownExit.enable} and
|
|
672
|
+
* {@link MarkdownExit.use}.
|
|
673
|
+
*/
|
|
674
|
+
var Ruler = class {
|
|
675
|
+
/**
|
|
676
|
+
* List of added rules. Each element is:
|
|
677
|
+
*
|
|
678
|
+
* ```js
|
|
679
|
+
* {
|
|
680
|
+
* name: XXX,
|
|
681
|
+
* enabled: Boolean,
|
|
682
|
+
* fn: Function(),
|
|
683
|
+
* alt: [ name2, name3 ]
|
|
684
|
+
* }
|
|
685
|
+
* ```
|
|
686
|
+
*/
|
|
687
|
+
__rules__ = [];
|
|
688
|
+
/**
|
|
689
|
+
* Cached rule chains.
|
|
690
|
+
*
|
|
691
|
+
* First level - chain name, '' for default.
|
|
692
|
+
* Second level - diginal anchor for fast filtering by charcodes.
|
|
693
|
+
*/
|
|
694
|
+
__cache__ = null;
|
|
695
|
+
/**
|
|
696
|
+
* Helper methods, should not be used directly
|
|
697
|
+
* Find rule index by name
|
|
698
|
+
*/
|
|
699
|
+
__find__(name) {
|
|
700
|
+
for (let i = 0; i < this.__rules__.length; i++) if (this.__rules__[i].name === name) return i;
|
|
701
|
+
return -1;
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Build rules lookup cache
|
|
705
|
+
*/
|
|
706
|
+
__compile__() {
|
|
707
|
+
const chains = new Set([""]);
|
|
708
|
+
for (const rule of this.__rules__) {
|
|
709
|
+
if (!rule.enabled) continue;
|
|
710
|
+
for (const altName of rule.alt) chains.add(altName);
|
|
711
|
+
}
|
|
712
|
+
this.__cache__ = {};
|
|
713
|
+
for (const chain of chains) {
|
|
714
|
+
const fns = [];
|
|
715
|
+
for (const rule of this.__rules__) {
|
|
716
|
+
if (!rule.enabled) continue;
|
|
717
|
+
if (chain && !rule.alt.includes(chain)) continue;
|
|
718
|
+
fns.push(rule.fn);
|
|
719
|
+
}
|
|
720
|
+
this.__cache__[chain] = fns;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Ruler.at(name, fn [, options])
|
|
725
|
+
* - name (String): rule name to replace.
|
|
726
|
+
* - fn (Function): new rule function.
|
|
727
|
+
* - options (Object): new rule options (not mandatory).
|
|
728
|
+
*
|
|
729
|
+
* Replace rule by name with new function & options. Throws error if name not
|
|
730
|
+
* found.
|
|
731
|
+
*
|
|
732
|
+
* ##### Options:
|
|
733
|
+
*
|
|
734
|
+
* - __alt__ - array with names of "alternate" chains.
|
|
735
|
+
*
|
|
736
|
+
* ##### Example
|
|
737
|
+
*
|
|
738
|
+
* Replace existing typographer replacement rule with new one:
|
|
739
|
+
*
|
|
740
|
+
* ```javascript
|
|
741
|
+
* md.core.ruler.at('replacements', function replace(state) {
|
|
742
|
+
* //...
|
|
743
|
+
* });
|
|
744
|
+
* ```
|
|
745
|
+
*/
|
|
746
|
+
at(name, fn, options = {}) {
|
|
747
|
+
const index = this.__find__(name);
|
|
748
|
+
const opt = options || {};
|
|
749
|
+
if (index === -1) throw new Error(`Parser rule not found: ${name}`);
|
|
750
|
+
this.__rules__[index].fn = fn;
|
|
751
|
+
this.__rules__[index].alt = opt.alt || [];
|
|
752
|
+
this.__cache__ = null;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Ruler.before(beforeName, ruleName, fn [, options])
|
|
756
|
+
* - beforeName (String): new rule will be added before this one.
|
|
757
|
+
* - ruleName (String): name of added rule.
|
|
758
|
+
* - fn (Function): rule function.
|
|
759
|
+
* - options (Object): rule options (not mandatory).
|
|
760
|
+
*
|
|
761
|
+
* Add new rule to chain before one with given name. See also
|
|
762
|
+
* [[Ruler.after]], [[Ruler.push]].
|
|
763
|
+
*
|
|
764
|
+
* ##### Options:
|
|
765
|
+
*
|
|
766
|
+
* - __alt__ - array with names of "alternate" chains.
|
|
767
|
+
*
|
|
768
|
+
* ##### Example
|
|
769
|
+
*
|
|
770
|
+
* ```javascript
|
|
771
|
+
* md.block.ruler.before('paragraph', 'my_rule', function replace(state) {
|
|
772
|
+
* //...
|
|
773
|
+
* });
|
|
774
|
+
* ```
|
|
775
|
+
*/
|
|
776
|
+
before(beforeName, ruleName, fn, options) {
|
|
777
|
+
const index = this.__find__(beforeName);
|
|
778
|
+
const opt = options || {};
|
|
779
|
+
if (index === -1) throw new Error(`Parser rule not found: ${beforeName}`);
|
|
780
|
+
this.__rules__.splice(index, 0, {
|
|
781
|
+
name: ruleName,
|
|
782
|
+
enabled: true,
|
|
783
|
+
fn,
|
|
784
|
+
alt: opt.alt || []
|
|
785
|
+
});
|
|
786
|
+
this.__cache__ = null;
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Ruler.after(afterName, ruleName, fn [, options])
|
|
790
|
+
* - afterName (String): new rule will be added after this one.
|
|
791
|
+
* - ruleName (String): name of added rule.
|
|
792
|
+
* - fn (Function): rule function.
|
|
793
|
+
* - options (Object): rule options (not mandatory).
|
|
794
|
+
*
|
|
795
|
+
* Add new rule to chain after one with given name. See also
|
|
796
|
+
* [[Ruler.before]], [[Ruler.push]].
|
|
797
|
+
*
|
|
798
|
+
* ##### Options:
|
|
799
|
+
*
|
|
800
|
+
* - __alt__ - array with names of "alternate" chains.
|
|
801
|
+
*
|
|
802
|
+
* ##### Example
|
|
803
|
+
*
|
|
804
|
+
* ```javascript
|
|
805
|
+
* md.inline.ruler.after('text', 'my_rule', function replace(state) {
|
|
806
|
+
* //...
|
|
807
|
+
* });
|
|
808
|
+
* ```
|
|
809
|
+
*/
|
|
810
|
+
after(afterName, ruleName, fn, options) {
|
|
811
|
+
const index = this.__find__(afterName);
|
|
812
|
+
const opt = options || {};
|
|
813
|
+
if (index === -1) throw new Error(`Parser rule not found: ${afterName}`);
|
|
814
|
+
this.__rules__.splice(index + 1, 0, {
|
|
815
|
+
name: ruleName,
|
|
816
|
+
enabled: true,
|
|
817
|
+
fn,
|
|
818
|
+
alt: opt.alt || []
|
|
819
|
+
});
|
|
820
|
+
this.__cache__ = null;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Ruler.push(ruleName, fn [, options])
|
|
824
|
+
* - ruleName (String): name of added rule.
|
|
825
|
+
* - fn (Function): rule function.
|
|
826
|
+
* - options (Object): rule options (not mandatory).
|
|
827
|
+
*
|
|
828
|
+
* Push new rule to the end of chain. See also
|
|
829
|
+
* [[Ruler.before]], [[Ruler.after]].
|
|
830
|
+
*
|
|
831
|
+
* ##### Options:
|
|
832
|
+
*
|
|
833
|
+
* - __alt__ - array with names of "alternate" chains.
|
|
834
|
+
*
|
|
835
|
+
* ##### Example
|
|
836
|
+
*
|
|
837
|
+
* ```javascript
|
|
838
|
+
* md.core.ruler.push('my_rule', function replace(state) {
|
|
839
|
+
* //...
|
|
840
|
+
* });
|
|
841
|
+
* ```
|
|
842
|
+
*/
|
|
843
|
+
push(ruleName, fn, options) {
|
|
844
|
+
const opt = options || {};
|
|
845
|
+
this.__rules__.push({
|
|
846
|
+
name: ruleName,
|
|
847
|
+
enabled: true,
|
|
848
|
+
fn,
|
|
849
|
+
alt: opt.alt || []
|
|
850
|
+
});
|
|
851
|
+
this.__cache__ = null;
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Ruler.enable(list [, ignoreInvalid]) -> Array
|
|
855
|
+
* - list (String|Array): list of rule names to enable.
|
|
856
|
+
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
|
|
857
|
+
*
|
|
858
|
+
* Enable rules with given names. If any rule name not found - throw Error.
|
|
859
|
+
* Errors can be disabled by second param.
|
|
860
|
+
*
|
|
861
|
+
* Returns list of found rule names (if no exception happened).
|
|
862
|
+
*
|
|
863
|
+
* See also [[Ruler.disable]], [[Ruler.enableOnly]].
|
|
864
|
+
*/
|
|
865
|
+
enable(list$1, ignoreInvalid) {
|
|
866
|
+
if (!Array.isArray(list$1)) list$1 = [list$1];
|
|
867
|
+
const result = [];
|
|
868
|
+
for (const name of list$1) {
|
|
869
|
+
const idx = this.__find__(name);
|
|
870
|
+
if (idx < 0) {
|
|
871
|
+
if (ignoreInvalid) continue;
|
|
872
|
+
throw new Error(`Rules manager: invalid rule name ${name}`);
|
|
873
|
+
}
|
|
874
|
+
this.__rules__[idx].enabled = true;
|
|
875
|
+
result.push(name);
|
|
876
|
+
}
|
|
877
|
+
this.__cache__ = null;
|
|
878
|
+
return result;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Ruler.enableOnly(list [, ignoreInvalid])
|
|
882
|
+
* - list (String|Array): list of rule names to enable (whitelist).
|
|
883
|
+
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
|
|
884
|
+
*
|
|
885
|
+
* Enable rules with given names, and disable everything else. If any rule name
|
|
886
|
+
* not found - throw Error. Errors can be disabled by second param.
|
|
887
|
+
*
|
|
888
|
+
* See also [[Ruler.disable]], [[Ruler.enable]].
|
|
889
|
+
*/
|
|
890
|
+
enableOnly(list$1, ignoreInvalid) {
|
|
891
|
+
if (!Array.isArray(list$1)) list$1 = [list$1];
|
|
892
|
+
for (const rule of this.__rules__) rule.enabled = false;
|
|
893
|
+
this.enable(list$1, ignoreInvalid);
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Ruler.disable(list [, ignoreInvalid]) -> Array
|
|
897
|
+
* - list (String|Array): list of rule names to disable.
|
|
898
|
+
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
|
|
899
|
+
*
|
|
900
|
+
* Disable rules with given names. If any rule name not found - throw Error.
|
|
901
|
+
* Errors can be disabled by second param.
|
|
902
|
+
*
|
|
903
|
+
* Returns list of found rule names (if no exception happened).
|
|
904
|
+
*
|
|
905
|
+
* See also [[Ruler.enable]], [[Ruler.enableOnly]].
|
|
906
|
+
*/
|
|
907
|
+
disable(list$1, ignoreInvalid) {
|
|
908
|
+
if (!Array.isArray(list$1)) list$1 = [list$1];
|
|
909
|
+
const result = [];
|
|
910
|
+
for (const name of list$1) {
|
|
911
|
+
const idx = this.__find__(name);
|
|
912
|
+
if (idx < 0) {
|
|
913
|
+
if (ignoreInvalid) continue;
|
|
914
|
+
throw new Error(`Rules manager: invalid rule name ${name}`);
|
|
915
|
+
}
|
|
916
|
+
this.__rules__[idx].enabled = false;
|
|
917
|
+
result.push(name);
|
|
918
|
+
}
|
|
919
|
+
this.__cache__ = null;
|
|
920
|
+
return result;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Ruler.getRules(chainName) -> Array
|
|
924
|
+
*
|
|
925
|
+
* Return array of active functions (rules) for given chain name. It analyzes
|
|
926
|
+
* rules configuration, compiles caches if not exists and returns result.
|
|
927
|
+
*
|
|
928
|
+
* Default chain name is `''` (empty string). It can't be skipped. That's
|
|
929
|
+
* done intentionally, to keep signature monomorphic for high speed.
|
|
930
|
+
*/
|
|
931
|
+
getRules(chainName) {
|
|
932
|
+
if (this.__cache__ === null) this.__compile__();
|
|
933
|
+
return this.__cache__[chainName] || [];
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
//#endregion
|
|
938
|
+
//#region src/parser/block/rules/blockquote.ts
|
|
939
|
+
function blockquote(state, startLine, endLine, silent) {
|
|
940
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
941
|
+
let max = state.eMarks[startLine];
|
|
942
|
+
const oldLineMax = state.lineMax;
|
|
943
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
944
|
+
if (state.src.charCodeAt(pos) !== 62) return false;
|
|
945
|
+
if (silent) return true;
|
|
946
|
+
const oldBMarks = [];
|
|
947
|
+
const oldBSCount = [];
|
|
948
|
+
const oldSCount = [];
|
|
949
|
+
const oldTShift = [];
|
|
950
|
+
const terminatorRules = state.md.block.ruler.getRules("blockquote");
|
|
951
|
+
const oldParentType = state.parentType;
|
|
952
|
+
state.parentType = "blockquote";
|
|
953
|
+
let lastLineEmpty = false;
|
|
954
|
+
let nextLine;
|
|
955
|
+
for (nextLine = startLine; nextLine < endLine; nextLine++) {
|
|
956
|
+
const isOutdented = state.sCount[nextLine] < state.blkIndent;
|
|
957
|
+
pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
958
|
+
max = state.eMarks[nextLine];
|
|
959
|
+
if (pos >= max) break;
|
|
960
|
+
if (state.src.charCodeAt(pos++) === 62 && !isOutdented) {
|
|
961
|
+
let initial = state.sCount[nextLine] + 1;
|
|
962
|
+
let spaceAfterMarker;
|
|
963
|
+
let adjustTab;
|
|
964
|
+
if (state.src.charCodeAt(pos) === 32) {
|
|
965
|
+
pos++;
|
|
966
|
+
initial++;
|
|
967
|
+
adjustTab = false;
|
|
968
|
+
spaceAfterMarker = true;
|
|
969
|
+
} else if (state.src.charCodeAt(pos) === 9) {
|
|
970
|
+
spaceAfterMarker = true;
|
|
971
|
+
if ((state.bsCount[nextLine] + initial) % 4 === 3) {
|
|
972
|
+
pos++;
|
|
973
|
+
initial++;
|
|
974
|
+
adjustTab = false;
|
|
975
|
+
} else adjustTab = true;
|
|
976
|
+
} else spaceAfterMarker = false;
|
|
977
|
+
let offset = initial;
|
|
978
|
+
oldBMarks.push(state.bMarks[nextLine]);
|
|
979
|
+
state.bMarks[nextLine] = pos;
|
|
980
|
+
while (pos < max) {
|
|
981
|
+
const ch = state.src.charCodeAt(pos);
|
|
982
|
+
if (isSpace(ch)) if (ch === 9) offset += 4 - (offset + state.bsCount[nextLine] + (adjustTab ? 1 : 0)) % 4;
|
|
983
|
+
else offset++;
|
|
984
|
+
else break;
|
|
985
|
+
pos++;
|
|
986
|
+
}
|
|
987
|
+
lastLineEmpty = pos >= max;
|
|
988
|
+
oldBSCount.push(state.bsCount[nextLine]);
|
|
989
|
+
state.bsCount[nextLine] = state.sCount[nextLine] + 1 + (spaceAfterMarker ? 1 : 0);
|
|
990
|
+
oldSCount.push(state.sCount[nextLine]);
|
|
991
|
+
state.sCount[nextLine] = offset - initial;
|
|
992
|
+
oldTShift.push(state.tShift[nextLine]);
|
|
993
|
+
state.tShift[nextLine] = pos - state.bMarks[nextLine];
|
|
994
|
+
continue;
|
|
995
|
+
}
|
|
996
|
+
if (lastLineEmpty) break;
|
|
997
|
+
let terminate = false;
|
|
998
|
+
for (let i = 0, l = terminatorRules.length; i < l; i++) if (terminatorRules[i](state, nextLine, endLine, true)) {
|
|
999
|
+
terminate = true;
|
|
1000
|
+
break;
|
|
1001
|
+
}
|
|
1002
|
+
if (terminate) {
|
|
1003
|
+
state.lineMax = nextLine;
|
|
1004
|
+
if (state.blkIndent !== 0) {
|
|
1005
|
+
oldBMarks.push(state.bMarks[nextLine]);
|
|
1006
|
+
oldBSCount.push(state.bsCount[nextLine]);
|
|
1007
|
+
oldTShift.push(state.tShift[nextLine]);
|
|
1008
|
+
oldSCount.push(state.sCount[nextLine]);
|
|
1009
|
+
state.sCount[nextLine] -= state.blkIndent;
|
|
1010
|
+
}
|
|
1011
|
+
break;
|
|
1012
|
+
}
|
|
1013
|
+
oldBMarks.push(state.bMarks[nextLine]);
|
|
1014
|
+
oldBSCount.push(state.bsCount[nextLine]);
|
|
1015
|
+
oldTShift.push(state.tShift[nextLine]);
|
|
1016
|
+
oldSCount.push(state.sCount[nextLine]);
|
|
1017
|
+
state.sCount[nextLine] = -1;
|
|
1018
|
+
}
|
|
1019
|
+
const oldIndent = state.blkIndent;
|
|
1020
|
+
state.blkIndent = 0;
|
|
1021
|
+
const token_o = state.push("blockquote_open", "blockquote", 1);
|
|
1022
|
+
token_o.markup = ">";
|
|
1023
|
+
const lines = [startLine, 0];
|
|
1024
|
+
token_o.map = lines;
|
|
1025
|
+
state.md.block.tokenize(state, startLine, nextLine);
|
|
1026
|
+
const token_c = state.push("blockquote_close", "blockquote", -1);
|
|
1027
|
+
token_c.markup = ">";
|
|
1028
|
+
state.lineMax = oldLineMax;
|
|
1029
|
+
state.parentType = oldParentType;
|
|
1030
|
+
lines[1] = state.line;
|
|
1031
|
+
for (let i = 0; i < oldTShift.length; i++) {
|
|
1032
|
+
state.bMarks[i + startLine] = oldBMarks[i];
|
|
1033
|
+
state.tShift[i + startLine] = oldTShift[i];
|
|
1034
|
+
state.sCount[i + startLine] = oldSCount[i];
|
|
1035
|
+
state.bsCount[i + startLine] = oldBSCount[i];
|
|
1036
|
+
}
|
|
1037
|
+
state.blkIndent = oldIndent;
|
|
1038
|
+
return true;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
//#endregion
|
|
1042
|
+
//#region src/parser/block/rules/code.ts
|
|
1043
|
+
function code(state, startLine, endLine) {
|
|
1044
|
+
if (state.sCount[startLine] - state.blkIndent < 4) return false;
|
|
1045
|
+
let nextLine = startLine + 1;
|
|
1046
|
+
let last = nextLine;
|
|
1047
|
+
while (nextLine < endLine) {
|
|
1048
|
+
if (state.isEmpty(nextLine)) {
|
|
1049
|
+
nextLine++;
|
|
1050
|
+
continue;
|
|
1051
|
+
}
|
|
1052
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4) {
|
|
1053
|
+
nextLine++;
|
|
1054
|
+
last = nextLine;
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
1059
|
+
state.line = last;
|
|
1060
|
+
const token = state.push("code_block", "code", 0);
|
|
1061
|
+
token.content = `${state.getLines(startLine, last, 4 + state.blkIndent, false)}\n`;
|
|
1062
|
+
token.map = [startLine, state.line];
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
//#endregion
|
|
1067
|
+
//#region src/parser/block/rules/fence.ts
|
|
1068
|
+
function fence(state, startLine, endLine, silent) {
|
|
1069
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1070
|
+
let max = state.eMarks[startLine];
|
|
1071
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1072
|
+
if (pos + 3 > max) return false;
|
|
1073
|
+
const marker = state.src.charCodeAt(pos);
|
|
1074
|
+
if (marker !== 126 && marker !== 96) return false;
|
|
1075
|
+
let mem = pos;
|
|
1076
|
+
pos = state.skipChars(pos, marker);
|
|
1077
|
+
let len = pos - mem;
|
|
1078
|
+
if (len < 3) return false;
|
|
1079
|
+
const markup = state.src.slice(mem, pos);
|
|
1080
|
+
const params = state.src.slice(pos, max);
|
|
1081
|
+
if (marker === 96) {
|
|
1082
|
+
if (params.includes(String.fromCharCode(marker))) return false;
|
|
1083
|
+
}
|
|
1084
|
+
if (silent) return true;
|
|
1085
|
+
let nextLine = startLine;
|
|
1086
|
+
let haveEndMarker = false;
|
|
1087
|
+
for (;;) {
|
|
1088
|
+
nextLine++;
|
|
1089
|
+
if (nextLine >= endLine) break;
|
|
1090
|
+
pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
1091
|
+
max = state.eMarks[nextLine];
|
|
1092
|
+
if (pos < max && state.sCount[nextLine] < state.blkIndent) break;
|
|
1093
|
+
if (state.src.charCodeAt(pos) !== marker) continue;
|
|
1094
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4) continue;
|
|
1095
|
+
pos = state.skipChars(pos, marker);
|
|
1096
|
+
if (pos - mem < len) continue;
|
|
1097
|
+
pos = state.skipSpaces(pos);
|
|
1098
|
+
if (pos < max) continue;
|
|
1099
|
+
haveEndMarker = true;
|
|
1100
|
+
break;
|
|
1101
|
+
}
|
|
1102
|
+
len = state.sCount[startLine];
|
|
1103
|
+
state.line = nextLine + (haveEndMarker ? 1 : 0);
|
|
1104
|
+
const token = state.push("fence", "code", 0);
|
|
1105
|
+
token.info = params;
|
|
1106
|
+
token.content = state.getLines(startLine + 1, nextLine, len, true);
|
|
1107
|
+
token.markup = markup;
|
|
1108
|
+
token.map = [startLine, state.line];
|
|
1109
|
+
return true;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
//#endregion
|
|
1113
|
+
//#region src/parser/block/rules/heading.ts
|
|
1114
|
+
function heading(state, startLine, endLine, silent) {
|
|
1115
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1116
|
+
let max = state.eMarks[startLine];
|
|
1117
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1118
|
+
let ch = state.src.charCodeAt(pos);
|
|
1119
|
+
if (ch !== 35 || pos >= max) return false;
|
|
1120
|
+
let level = 1;
|
|
1121
|
+
ch = state.src.charCodeAt(++pos);
|
|
1122
|
+
while (ch === 35 && pos < max && level <= 6) {
|
|
1123
|
+
level++;
|
|
1124
|
+
ch = state.src.charCodeAt(++pos);
|
|
1125
|
+
}
|
|
1126
|
+
if (level > 6 || pos < max && !isSpace(ch)) return false;
|
|
1127
|
+
if (silent) return true;
|
|
1128
|
+
max = state.skipSpacesBack(max, pos);
|
|
1129
|
+
const tmp = state.skipCharsBack(max, 35, pos);
|
|
1130
|
+
if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) max = tmp;
|
|
1131
|
+
state.line = startLine + 1;
|
|
1132
|
+
const token_o = state.push("heading_open", `h${String(level)}`, 1);
|
|
1133
|
+
token_o.markup = "########".slice(0, level);
|
|
1134
|
+
token_o.map = [startLine, state.line];
|
|
1135
|
+
const token_i = state.push("inline", "", 0);
|
|
1136
|
+
token_i.content = asciiTrim(state.src.slice(pos, max));
|
|
1137
|
+
token_i.map = [startLine, state.line];
|
|
1138
|
+
token_i.children = [];
|
|
1139
|
+
const token_c = state.push("heading_close", `h${String(level)}`, -1);
|
|
1140
|
+
token_c.markup = "########".slice(0, level);
|
|
1141
|
+
return true;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
//#endregion
|
|
1145
|
+
//#region src/parser/block/rules/hr.ts
|
|
1146
|
+
function hr(state, startLine, endLine, silent) {
|
|
1147
|
+
const max = state.eMarks[startLine];
|
|
1148
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1149
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1150
|
+
const marker = state.src.charCodeAt(pos++);
|
|
1151
|
+
if (marker !== 42 && marker !== 45 && marker !== 95) return false;
|
|
1152
|
+
let cnt = 1;
|
|
1153
|
+
while (pos < max) {
|
|
1154
|
+
const ch = state.src.charCodeAt(pos++);
|
|
1155
|
+
if (ch !== marker && !isSpace(ch)) return false;
|
|
1156
|
+
if (ch === marker) cnt++;
|
|
1157
|
+
}
|
|
1158
|
+
if (cnt < 3) return false;
|
|
1159
|
+
if (silent) return true;
|
|
1160
|
+
state.line = startLine + 1;
|
|
1161
|
+
const token = state.push("hr", "hr", 0);
|
|
1162
|
+
token.map = [startLine, state.line];
|
|
1163
|
+
token.markup = String.fromCharCode(marker).repeat(cnt);
|
|
1164
|
+
return true;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
//#endregion
|
|
1168
|
+
//#region src/parser/utils/html_blocks.ts
|
|
1169
|
+
var html_blocks_default = [
|
|
1170
|
+
"address",
|
|
1171
|
+
"article",
|
|
1172
|
+
"aside",
|
|
1173
|
+
"base",
|
|
1174
|
+
"basefont",
|
|
1175
|
+
"blockquote",
|
|
1176
|
+
"body",
|
|
1177
|
+
"caption",
|
|
1178
|
+
"center",
|
|
1179
|
+
"col",
|
|
1180
|
+
"colgroup",
|
|
1181
|
+
"dd",
|
|
1182
|
+
"details",
|
|
1183
|
+
"dialog",
|
|
1184
|
+
"dir",
|
|
1185
|
+
"div",
|
|
1186
|
+
"dl",
|
|
1187
|
+
"dt",
|
|
1188
|
+
"fieldset",
|
|
1189
|
+
"figcaption",
|
|
1190
|
+
"figure",
|
|
1191
|
+
"footer",
|
|
1192
|
+
"form",
|
|
1193
|
+
"frame",
|
|
1194
|
+
"frameset",
|
|
1195
|
+
"h1",
|
|
1196
|
+
"h2",
|
|
1197
|
+
"h3",
|
|
1198
|
+
"h4",
|
|
1199
|
+
"h5",
|
|
1200
|
+
"h6",
|
|
1201
|
+
"head",
|
|
1202
|
+
"header",
|
|
1203
|
+
"hr",
|
|
1204
|
+
"html",
|
|
1205
|
+
"iframe",
|
|
1206
|
+
"legend",
|
|
1207
|
+
"li",
|
|
1208
|
+
"link",
|
|
1209
|
+
"main",
|
|
1210
|
+
"menu",
|
|
1211
|
+
"menuitem",
|
|
1212
|
+
"nav",
|
|
1213
|
+
"noframes",
|
|
1214
|
+
"ol",
|
|
1215
|
+
"optgroup",
|
|
1216
|
+
"option",
|
|
1217
|
+
"p",
|
|
1218
|
+
"param",
|
|
1219
|
+
"search",
|
|
1220
|
+
"section",
|
|
1221
|
+
"summary",
|
|
1222
|
+
"table",
|
|
1223
|
+
"tbody",
|
|
1224
|
+
"td",
|
|
1225
|
+
"tfoot",
|
|
1226
|
+
"th",
|
|
1227
|
+
"thead",
|
|
1228
|
+
"title",
|
|
1229
|
+
"tr",
|
|
1230
|
+
"track",
|
|
1231
|
+
"ul"
|
|
1232
|
+
];
|
|
1233
|
+
|
|
1234
|
+
//#endregion
|
|
1235
|
+
//#region src/parser/utils/html_re.ts
|
|
1236
|
+
const open_tag = `<[A-Za-z][A-Za-z0-9\\-]*(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^"'=<>\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*\\/?>`;
|
|
1237
|
+
const close_tag = "<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>";
|
|
1238
|
+
const HTML_TAG_RE = /* @__PURE__ */ new RegExp(`^(?:${open_tag}|${close_tag}|<!---?>|<!--(?:[^-]|-[^-]|--[^>])*-->|<\\?[\\s\\S]*?\\?>|<![A-Za-z][^>]*>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>)`);
|
|
1239
|
+
const HTML_OPEN_CLOSE_TAG_RE = /* @__PURE__ */ new RegExp(`^(?:${open_tag}|${close_tag})`);
|
|
1240
|
+
|
|
1241
|
+
//#endregion
|
|
1242
|
+
//#region src/parser/block/rules/html_block.ts
|
|
1243
|
+
const HTML_SEQUENCES = [
|
|
1244
|
+
[
|
|
1245
|
+
/^<(script|pre|style|textarea)(?=(\s|>|$))/i,
|
|
1246
|
+
/<\/(script|pre|style|textarea)>/i,
|
|
1247
|
+
true
|
|
1248
|
+
],
|
|
1249
|
+
[
|
|
1250
|
+
/^<!--/,
|
|
1251
|
+
/-->/,
|
|
1252
|
+
true
|
|
1253
|
+
],
|
|
1254
|
+
[
|
|
1255
|
+
/^<\?/,
|
|
1256
|
+
/\?>/,
|
|
1257
|
+
true
|
|
1258
|
+
],
|
|
1259
|
+
[
|
|
1260
|
+
/^<![A-Z]/,
|
|
1261
|
+
/>/,
|
|
1262
|
+
true
|
|
1263
|
+
],
|
|
1264
|
+
[
|
|
1265
|
+
/^<!\[CDATA\[/,
|
|
1266
|
+
/\]\]>/,
|
|
1267
|
+
true
|
|
1268
|
+
],
|
|
1269
|
+
[
|
|
1270
|
+
new RegExp(`^</?(${html_blocks_default.join("|")})(?=(\\s|/?>|$))`, "i"),
|
|
1271
|
+
/^$/,
|
|
1272
|
+
true
|
|
1273
|
+
],
|
|
1274
|
+
[
|
|
1275
|
+
/* @__PURE__ */ new RegExp(`${HTML_OPEN_CLOSE_TAG_RE.source}\\s*$`),
|
|
1276
|
+
/^$/,
|
|
1277
|
+
false
|
|
1278
|
+
]
|
|
1279
|
+
];
|
|
1280
|
+
function html_block(state, startLine, endLine, silent) {
|
|
1281
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1282
|
+
let max = state.eMarks[startLine];
|
|
1283
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1284
|
+
if (!state.md.options.html) return false;
|
|
1285
|
+
if (state.src.charCodeAt(pos) !== 60) return false;
|
|
1286
|
+
let lineText = state.src.slice(pos, max);
|
|
1287
|
+
let i = 0;
|
|
1288
|
+
for (; i < HTML_SEQUENCES.length; i++) if (HTML_SEQUENCES[i][0].test(lineText)) break;
|
|
1289
|
+
if (i === HTML_SEQUENCES.length) return false;
|
|
1290
|
+
if (silent) return HTML_SEQUENCES[i][2];
|
|
1291
|
+
let nextLine = startLine + 1;
|
|
1292
|
+
const endsOnBlankLine = HTML_SEQUENCES[i][1].test("");
|
|
1293
|
+
if (!HTML_SEQUENCES[i][1].test(lineText)) for (; nextLine < endLine; nextLine++) {
|
|
1294
|
+
if (state.sCount[nextLine] < state.blkIndent) {
|
|
1295
|
+
if (endsOnBlankLine || !state.isEmpty(nextLine)) break;
|
|
1296
|
+
}
|
|
1297
|
+
pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
1298
|
+
max = state.eMarks[nextLine];
|
|
1299
|
+
lineText = state.src.slice(pos, max);
|
|
1300
|
+
if (HTML_SEQUENCES[i][1].test(lineText)) {
|
|
1301
|
+
if (lineText.length !== 0) nextLine++;
|
|
1302
|
+
break;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
state.line = nextLine;
|
|
1306
|
+
const token = state.push("html_block", "", 0);
|
|
1307
|
+
token.map = [startLine, nextLine];
|
|
1308
|
+
token.content = state.getLines(startLine, nextLine, state.blkIndent, true);
|
|
1309
|
+
return true;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
//#endregion
|
|
1313
|
+
//#region src/parser/block/rules/lheading.ts
|
|
1314
|
+
function lheading(state, startLine, endLine) {
|
|
1315
|
+
const terminatorRules = state.md.block.ruler.getRules("paragraph");
|
|
1316
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1317
|
+
const oldParentType = state.parentType;
|
|
1318
|
+
state.parentType = "paragraph";
|
|
1319
|
+
let level = 0;
|
|
1320
|
+
let marker;
|
|
1321
|
+
let nextLine = startLine + 1;
|
|
1322
|
+
for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {
|
|
1323
|
+
if (state.sCount[nextLine] - state.blkIndent > 3) continue;
|
|
1324
|
+
if (state.sCount[nextLine] >= state.blkIndent) {
|
|
1325
|
+
let pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
1326
|
+
const max = state.eMarks[nextLine];
|
|
1327
|
+
if (pos < max) {
|
|
1328
|
+
marker = state.src.charCodeAt(pos);
|
|
1329
|
+
if (marker === 45 || marker === 61) {
|
|
1330
|
+
pos = state.skipChars(pos, marker);
|
|
1331
|
+
pos = state.skipSpaces(pos);
|
|
1332
|
+
if (pos >= max) {
|
|
1333
|
+
level = marker === 61 ? 1 : 2;
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
if (state.sCount[nextLine] < 0) continue;
|
|
1340
|
+
let terminate = false;
|
|
1341
|
+
for (let i = 0, l = terminatorRules.length; i < l; i++) if (terminatorRules[i](state, nextLine, endLine, true)) {
|
|
1342
|
+
terminate = true;
|
|
1343
|
+
break;
|
|
1344
|
+
}
|
|
1345
|
+
if (terminate) break;
|
|
1346
|
+
}
|
|
1347
|
+
if (!level || marker === void 0) {
|
|
1348
|
+
state.parentType = oldParentType;
|
|
1349
|
+
return false;
|
|
1350
|
+
}
|
|
1351
|
+
const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
|
|
1352
|
+
state.line = nextLine + 1;
|
|
1353
|
+
const token_o = state.push("heading_open", `h${String(level)}`, 1);
|
|
1354
|
+
token_o.markup = String.fromCharCode(marker);
|
|
1355
|
+
token_o.map = [startLine, state.line];
|
|
1356
|
+
const token_i = state.push("inline", "", 0);
|
|
1357
|
+
token_i.content = content;
|
|
1358
|
+
token_i.map = [startLine, state.line - 1];
|
|
1359
|
+
token_i.children = [];
|
|
1360
|
+
const token_c = state.push("heading_close", `h${String(level)}`, -1);
|
|
1361
|
+
token_c.markup = String.fromCharCode(marker);
|
|
1362
|
+
state.parentType = oldParentType;
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
//#endregion
|
|
1367
|
+
//#region src/parser/block/rules/list.ts
|
|
1368
|
+
function skipBulletListMarker(state, startLine) {
|
|
1369
|
+
const max = state.eMarks[startLine];
|
|
1370
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1371
|
+
const marker = state.src.charCodeAt(pos++);
|
|
1372
|
+
if (marker !== 42 && marker !== 45 && marker !== 43) return -1;
|
|
1373
|
+
if (pos < max) {
|
|
1374
|
+
if (!isSpace(state.src.charCodeAt(pos))) return -1;
|
|
1375
|
+
}
|
|
1376
|
+
return pos;
|
|
1377
|
+
}
|
|
1378
|
+
function skipOrderedListMarker(state, startLine) {
|
|
1379
|
+
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
1380
|
+
const max = state.eMarks[startLine];
|
|
1381
|
+
let pos = start;
|
|
1382
|
+
if (pos + 1 >= max) return -1;
|
|
1383
|
+
let ch = state.src.charCodeAt(pos++);
|
|
1384
|
+
if (ch < 48 || ch > 57) return -1;
|
|
1385
|
+
for (;;) {
|
|
1386
|
+
if (pos >= max) return -1;
|
|
1387
|
+
ch = state.src.charCodeAt(pos++);
|
|
1388
|
+
if (ch >= 48 && ch <= 57) {
|
|
1389
|
+
if (pos - start >= 10) return -1;
|
|
1390
|
+
continue;
|
|
1391
|
+
}
|
|
1392
|
+
if (ch === 41 || ch === 46) break;
|
|
1393
|
+
return -1;
|
|
1394
|
+
}
|
|
1395
|
+
if (pos < max) {
|
|
1396
|
+
ch = state.src.charCodeAt(pos);
|
|
1397
|
+
if (!isSpace(ch)) return -1;
|
|
1398
|
+
}
|
|
1399
|
+
return pos;
|
|
1400
|
+
}
|
|
1401
|
+
function markTightParagraphs(state, idx) {
|
|
1402
|
+
const level = state.level + 2;
|
|
1403
|
+
for (let i = idx + 2, l = state.tokens.length - 2; i < l; i++) if (state.tokens[i].level === level && state.tokens[i].type === "paragraph_open") {
|
|
1404
|
+
state.tokens[i + 2].hidden = true;
|
|
1405
|
+
state.tokens[i].hidden = true;
|
|
1406
|
+
i += 2;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
function list(state, startLine, endLine, silent) {
|
|
1410
|
+
let max, pos, start, token;
|
|
1411
|
+
let nextLine = startLine;
|
|
1412
|
+
let tight = true;
|
|
1413
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4) return false;
|
|
1414
|
+
if (state.listIndent >= 0 && state.sCount[nextLine] - state.listIndent >= 4 && state.sCount[nextLine] < state.blkIndent) return false;
|
|
1415
|
+
let isTerminatingParagraph = false;
|
|
1416
|
+
if (silent && state.parentType === "paragraph") {
|
|
1417
|
+
if (state.sCount[nextLine] >= state.blkIndent) isTerminatingParagraph = true;
|
|
1418
|
+
}
|
|
1419
|
+
let isOrdered;
|
|
1420
|
+
let markerValue;
|
|
1421
|
+
let posAfterMarker = skipOrderedListMarker(state, nextLine);
|
|
1422
|
+
if (posAfterMarker >= 0) {
|
|
1423
|
+
isOrdered = true;
|
|
1424
|
+
start = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
1425
|
+
markerValue = Number(state.src.slice(start, posAfterMarker - 1));
|
|
1426
|
+
if (isTerminatingParagraph && markerValue !== 1) return false;
|
|
1427
|
+
} else {
|
|
1428
|
+
posAfterMarker = skipBulletListMarker(state, nextLine);
|
|
1429
|
+
if (posAfterMarker >= 0) isOrdered = false;
|
|
1430
|
+
else return false;
|
|
1431
|
+
}
|
|
1432
|
+
if (isTerminatingParagraph) {
|
|
1433
|
+
if (state.skipSpaces(posAfterMarker) >= state.eMarks[nextLine]) return false;
|
|
1434
|
+
}
|
|
1435
|
+
if (silent) return true;
|
|
1436
|
+
const markerCharCode = state.src.charCodeAt(posAfterMarker - 1);
|
|
1437
|
+
const listTokIdx = state.tokens.length;
|
|
1438
|
+
if (isOrdered) {
|
|
1439
|
+
token = state.push("ordered_list_open", "ol", 1);
|
|
1440
|
+
if (markerValue !== 1) token.attrs = [["start", markerValue.toString()]];
|
|
1441
|
+
} else token = state.push("bullet_list_open", "ul", 1);
|
|
1442
|
+
const listLines = [nextLine, 0];
|
|
1443
|
+
token.map = listLines;
|
|
1444
|
+
token.markup = String.fromCharCode(markerCharCode);
|
|
1445
|
+
let prevEmptyEnd = false;
|
|
1446
|
+
const terminatorRules = state.md.block.ruler.getRules("list");
|
|
1447
|
+
const oldParentType = state.parentType;
|
|
1448
|
+
state.parentType = "list";
|
|
1449
|
+
while (nextLine < endLine) {
|
|
1450
|
+
pos = posAfterMarker;
|
|
1451
|
+
max = state.eMarks[nextLine];
|
|
1452
|
+
const initial = state.sCount[nextLine] + posAfterMarker - (state.bMarks[nextLine] + state.tShift[nextLine]);
|
|
1453
|
+
let offset = initial;
|
|
1454
|
+
while (pos < max) {
|
|
1455
|
+
const ch = state.src.charCodeAt(pos);
|
|
1456
|
+
if (ch === 9) offset += 4 - (offset + state.bsCount[nextLine]) % 4;
|
|
1457
|
+
else if (ch === 32) offset++;
|
|
1458
|
+
else break;
|
|
1459
|
+
pos++;
|
|
1460
|
+
}
|
|
1461
|
+
const contentStart = pos;
|
|
1462
|
+
let indentAfterMarker;
|
|
1463
|
+
if (contentStart >= max) indentAfterMarker = 1;
|
|
1464
|
+
else indentAfterMarker = offset - initial;
|
|
1465
|
+
if (indentAfterMarker > 4) indentAfterMarker = 1;
|
|
1466
|
+
const indent = initial + indentAfterMarker;
|
|
1467
|
+
token = state.push("list_item_open", "li", 1);
|
|
1468
|
+
token.markup = String.fromCharCode(markerCharCode);
|
|
1469
|
+
const itemLines = [nextLine, 0];
|
|
1470
|
+
token.map = itemLines;
|
|
1471
|
+
if (isOrdered) token.info = state.src.slice(start, posAfterMarker - 1);
|
|
1472
|
+
const oldTight = state.tight;
|
|
1473
|
+
const oldTShift = state.tShift[nextLine];
|
|
1474
|
+
const oldSCount = state.sCount[nextLine];
|
|
1475
|
+
const oldListIndent = state.listIndent;
|
|
1476
|
+
state.listIndent = state.blkIndent;
|
|
1477
|
+
state.blkIndent = indent;
|
|
1478
|
+
state.tight = true;
|
|
1479
|
+
state.tShift[nextLine] = contentStart - state.bMarks[nextLine];
|
|
1480
|
+
state.sCount[nextLine] = offset;
|
|
1481
|
+
if (contentStart >= max && state.isEmpty(nextLine + 1)) state.line = Math.min(state.line + 2, endLine);
|
|
1482
|
+
else state.md.block.tokenize(state, nextLine, endLine, true);
|
|
1483
|
+
if (!state.tight || prevEmptyEnd) tight = false;
|
|
1484
|
+
prevEmptyEnd = state.line - nextLine > 1 && state.isEmpty(state.line - 1);
|
|
1485
|
+
state.blkIndent = state.listIndent;
|
|
1486
|
+
state.listIndent = oldListIndent;
|
|
1487
|
+
state.tShift[nextLine] = oldTShift;
|
|
1488
|
+
state.sCount[nextLine] = oldSCount;
|
|
1489
|
+
state.tight = oldTight;
|
|
1490
|
+
token = state.push("list_item_close", "li", -1);
|
|
1491
|
+
token.markup = String.fromCharCode(markerCharCode);
|
|
1492
|
+
nextLine = state.line;
|
|
1493
|
+
itemLines[1] = nextLine;
|
|
1494
|
+
if (nextLine >= endLine) break;
|
|
1495
|
+
if (state.sCount[nextLine] < state.blkIndent) break;
|
|
1496
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4) break;
|
|
1497
|
+
let terminate = false;
|
|
1498
|
+
for (let i = 0, l = terminatorRules.length; i < l; i++) if (terminatorRules[i](state, nextLine, endLine, true)) {
|
|
1499
|
+
terminate = true;
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
if (terminate) break;
|
|
1503
|
+
if (isOrdered) {
|
|
1504
|
+
posAfterMarker = skipOrderedListMarker(state, nextLine);
|
|
1505
|
+
if (posAfterMarker < 0) break;
|
|
1506
|
+
start = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
1507
|
+
} else {
|
|
1508
|
+
posAfterMarker = skipBulletListMarker(state, nextLine);
|
|
1509
|
+
if (posAfterMarker < 0) break;
|
|
1510
|
+
}
|
|
1511
|
+
if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) break;
|
|
1512
|
+
}
|
|
1513
|
+
if (isOrdered) token = state.push("ordered_list_close", "ol", -1);
|
|
1514
|
+
else token = state.push("bullet_list_close", "ul", -1);
|
|
1515
|
+
token.markup = String.fromCharCode(markerCharCode);
|
|
1516
|
+
listLines[1] = nextLine;
|
|
1517
|
+
state.line = nextLine;
|
|
1518
|
+
state.parentType = oldParentType;
|
|
1519
|
+
if (tight) markTightParagraphs(state, listTokIdx);
|
|
1520
|
+
return true;
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
//#endregion
|
|
1524
|
+
//#region src/parser/block/rules/paragraph.ts
|
|
1525
|
+
function paragraph(state, startLine, endLine) {
|
|
1526
|
+
const terminatorRules = state.md.block.ruler.getRules("paragraph");
|
|
1527
|
+
const oldParentType = state.parentType;
|
|
1528
|
+
let nextLine = startLine + 1;
|
|
1529
|
+
state.parentType = "paragraph";
|
|
1530
|
+
for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {
|
|
1531
|
+
if (state.sCount[nextLine] - state.blkIndent > 3) continue;
|
|
1532
|
+
if (state.sCount[nextLine] < 0) continue;
|
|
1533
|
+
let terminate = false;
|
|
1534
|
+
for (let i = 0, l = terminatorRules.length; i < l; i++) if (terminatorRules[i](state, nextLine, endLine, true)) {
|
|
1535
|
+
terminate = true;
|
|
1536
|
+
break;
|
|
1537
|
+
}
|
|
1538
|
+
if (terminate) break;
|
|
1539
|
+
}
|
|
1540
|
+
const content = asciiTrim(state.getLines(startLine, nextLine, state.blkIndent, false));
|
|
1541
|
+
state.line = nextLine;
|
|
1542
|
+
const token_o = state.push("paragraph_open", "p", 1);
|
|
1543
|
+
token_o.map = [startLine, state.line];
|
|
1544
|
+
const token_i = state.push("inline", "", 0);
|
|
1545
|
+
token_i.content = content;
|
|
1546
|
+
token_i.map = [startLine, state.line];
|
|
1547
|
+
token_i.children = [];
|
|
1548
|
+
state.push("paragraph_close", "p", -1);
|
|
1549
|
+
state.parentType = oldParentType;
|
|
1550
|
+
return true;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
//#endregion
|
|
1554
|
+
//#region src/parser/block/rules/reference.ts
|
|
1555
|
+
function reference(state, startLine, endLine, silent) {
|
|
1556
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1557
|
+
let max = state.eMarks[startLine];
|
|
1558
|
+
let nextLine = startLine + 1;
|
|
1559
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1560
|
+
if (state.src.charCodeAt(pos) !== 91) return false;
|
|
1561
|
+
function getNextLine(nextLine$1) {
|
|
1562
|
+
const endLine$1 = state.lineMax;
|
|
1563
|
+
if (nextLine$1 >= endLine$1 || state.isEmpty(nextLine$1)) return null;
|
|
1564
|
+
let isContinuation = false;
|
|
1565
|
+
if (state.sCount[nextLine$1] - state.blkIndent > 3) isContinuation = true;
|
|
1566
|
+
if (state.sCount[nextLine$1] < 0) isContinuation = true;
|
|
1567
|
+
if (!isContinuation) {
|
|
1568
|
+
const terminatorRules = state.md.block.ruler.getRules("reference");
|
|
1569
|
+
const oldParentType = state.parentType;
|
|
1570
|
+
state.parentType = "reference";
|
|
1571
|
+
let terminate = false;
|
|
1572
|
+
for (let i = 0, l = terminatorRules.length; i < l; i++) if (terminatorRules[i](state, nextLine$1, endLine$1, true)) {
|
|
1573
|
+
terminate = true;
|
|
1574
|
+
break;
|
|
1575
|
+
}
|
|
1576
|
+
state.parentType = oldParentType;
|
|
1577
|
+
if (terminate) return null;
|
|
1578
|
+
}
|
|
1579
|
+
const pos$1 = state.bMarks[nextLine$1] + state.tShift[nextLine$1];
|
|
1580
|
+
const max$1 = state.eMarks[nextLine$1];
|
|
1581
|
+
return state.src.slice(pos$1, max$1 + 1);
|
|
1582
|
+
}
|
|
1583
|
+
let str = state.src.slice(pos, max + 1);
|
|
1584
|
+
max = str.length;
|
|
1585
|
+
let labelEnd = -1;
|
|
1586
|
+
for (pos = 1; pos < max; pos++) {
|
|
1587
|
+
const ch = str.charCodeAt(pos);
|
|
1588
|
+
if (ch === 91) return false;
|
|
1589
|
+
else if (ch === 93) {
|
|
1590
|
+
labelEnd = pos;
|
|
1591
|
+
break;
|
|
1592
|
+
} else if (ch === 10) {
|
|
1593
|
+
const lineContent = getNextLine(nextLine);
|
|
1594
|
+
if (lineContent !== null) {
|
|
1595
|
+
str += lineContent;
|
|
1596
|
+
max = str.length;
|
|
1597
|
+
nextLine++;
|
|
1598
|
+
}
|
|
1599
|
+
} else if (ch === 92) {
|
|
1600
|
+
pos++;
|
|
1601
|
+
if (pos < max && str.charCodeAt(pos) === 10) {
|
|
1602
|
+
const lineContent = getNextLine(nextLine);
|
|
1603
|
+
if (lineContent !== null) {
|
|
1604
|
+
str += lineContent;
|
|
1605
|
+
max = str.length;
|
|
1606
|
+
nextLine++;
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 58) return false;
|
|
1612
|
+
for (pos = labelEnd + 2; pos < max; pos++) {
|
|
1613
|
+
const ch = str.charCodeAt(pos);
|
|
1614
|
+
if (ch === 10) {
|
|
1615
|
+
const lineContent = getNextLine(nextLine);
|
|
1616
|
+
if (lineContent !== null) {
|
|
1617
|
+
str += lineContent;
|
|
1618
|
+
max = str.length;
|
|
1619
|
+
nextLine++;
|
|
1620
|
+
}
|
|
1621
|
+
} else if (isSpace(ch)) {} else break;
|
|
1622
|
+
}
|
|
1623
|
+
const destRes = state.md.helpers.parseLinkDestination(str, pos, max);
|
|
1624
|
+
if (!destRes.ok) return false;
|
|
1625
|
+
const href = state.md.normalizeLink(destRes.str);
|
|
1626
|
+
if (!state.md.validateLink(href)) return false;
|
|
1627
|
+
pos = destRes.pos;
|
|
1628
|
+
const destEndPos = pos;
|
|
1629
|
+
const destEndLineNo = nextLine;
|
|
1630
|
+
const start = pos;
|
|
1631
|
+
for (; pos < max; pos++) {
|
|
1632
|
+
const ch = str.charCodeAt(pos);
|
|
1633
|
+
if (ch === 10) {
|
|
1634
|
+
const lineContent = getNextLine(nextLine);
|
|
1635
|
+
if (lineContent !== null) {
|
|
1636
|
+
str += lineContent;
|
|
1637
|
+
max = str.length;
|
|
1638
|
+
nextLine++;
|
|
1639
|
+
}
|
|
1640
|
+
} else if (isSpace(ch)) {} else break;
|
|
1641
|
+
}
|
|
1642
|
+
let titleRes = state.md.helpers.parseLinkTitle(str, pos, max);
|
|
1643
|
+
while (titleRes.can_continue) {
|
|
1644
|
+
const lineContent = getNextLine(nextLine);
|
|
1645
|
+
if (lineContent === null) break;
|
|
1646
|
+
str += lineContent;
|
|
1647
|
+
pos = max;
|
|
1648
|
+
max = str.length;
|
|
1649
|
+
nextLine++;
|
|
1650
|
+
titleRes = state.md.helpers.parseLinkTitle(str, pos, max, titleRes);
|
|
1651
|
+
}
|
|
1652
|
+
let title;
|
|
1653
|
+
if (pos < max && start !== pos && titleRes.ok) {
|
|
1654
|
+
title = titleRes.str;
|
|
1655
|
+
pos = titleRes.pos;
|
|
1656
|
+
} else {
|
|
1657
|
+
title = "";
|
|
1658
|
+
pos = destEndPos;
|
|
1659
|
+
nextLine = destEndLineNo;
|
|
1660
|
+
}
|
|
1661
|
+
while (pos < max) {
|
|
1662
|
+
if (!isSpace(str.charCodeAt(pos))) break;
|
|
1663
|
+
pos++;
|
|
1664
|
+
}
|
|
1665
|
+
if (pos < max && str.charCodeAt(pos) !== 10) {
|
|
1666
|
+
if (title) {
|
|
1667
|
+
title = "";
|
|
1668
|
+
pos = destEndPos;
|
|
1669
|
+
nextLine = destEndLineNo;
|
|
1670
|
+
while (pos < max) {
|
|
1671
|
+
if (!isSpace(str.charCodeAt(pos))) break;
|
|
1672
|
+
pos++;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
if (pos < max && str.charCodeAt(pos) !== 10) return false;
|
|
1677
|
+
const label = normalizeReference(str.slice(1, labelEnd));
|
|
1678
|
+
if (!label) return false;
|
|
1679
|
+
/* istanbul ignore if */
|
|
1680
|
+
if (silent) return true;
|
|
1681
|
+
if (typeof state.env.references === "undefined") state.env.references = {};
|
|
1682
|
+
if (typeof state.env.references[label] === "undefined") state.env.references[label] = {
|
|
1683
|
+
title,
|
|
1684
|
+
href
|
|
1685
|
+
};
|
|
1686
|
+
state.line = nextLine;
|
|
1687
|
+
const token = state.push("reference", "", 0);
|
|
1688
|
+
token.map = [startLine, state.line];
|
|
1689
|
+
token.info = label;
|
|
1690
|
+
token.meta = {
|
|
1691
|
+
title,
|
|
1692
|
+
href
|
|
1693
|
+
};
|
|
1694
|
+
return true;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
//#endregion
|
|
1698
|
+
//#region src/parser/block/rules/table.ts
|
|
1699
|
+
const MAX_AUTOCOMPLETED_CELLS = 65536;
|
|
1700
|
+
function getLine(state, line) {
|
|
1701
|
+
const pos = state.bMarks[line] + state.tShift[line];
|
|
1702
|
+
const max = state.eMarks[line];
|
|
1703
|
+
return state.src.slice(pos, max);
|
|
1704
|
+
}
|
|
1705
|
+
function escapedSplit(str) {
|
|
1706
|
+
const result = [];
|
|
1707
|
+
const max = str.length;
|
|
1708
|
+
let pos = 0;
|
|
1709
|
+
let ch = str.charCodeAt(pos);
|
|
1710
|
+
let isEscaped = false;
|
|
1711
|
+
let lastPos = 0;
|
|
1712
|
+
let current = "";
|
|
1713
|
+
while (pos < max) {
|
|
1714
|
+
if (ch === 124) if (!isEscaped) {
|
|
1715
|
+
result.push(current + str.substring(lastPos, pos));
|
|
1716
|
+
current = "";
|
|
1717
|
+
lastPos = pos + 1;
|
|
1718
|
+
} else {
|
|
1719
|
+
current += str.substring(lastPos, pos - 1);
|
|
1720
|
+
lastPos = pos;
|
|
1721
|
+
}
|
|
1722
|
+
isEscaped = ch === 92;
|
|
1723
|
+
pos++;
|
|
1724
|
+
ch = str.charCodeAt(pos);
|
|
1725
|
+
}
|
|
1726
|
+
result.push(current + str.substring(lastPos));
|
|
1727
|
+
return result;
|
|
1728
|
+
}
|
|
1729
|
+
function table(state, startLine, endLine, silent) {
|
|
1730
|
+
if (startLine + 2 > endLine) return false;
|
|
1731
|
+
let nextLine = startLine + 1;
|
|
1732
|
+
if (state.sCount[nextLine] < state.blkIndent) return false;
|
|
1733
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4) return false;
|
|
1734
|
+
let pos = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
1735
|
+
if (pos >= state.eMarks[nextLine]) return false;
|
|
1736
|
+
const firstCh = state.src.charCodeAt(pos++);
|
|
1737
|
+
if (firstCh !== 124 && firstCh !== 45 && firstCh !== 58) return false;
|
|
1738
|
+
if (pos >= state.eMarks[nextLine]) return false;
|
|
1739
|
+
const secondCh = state.src.charCodeAt(pos++);
|
|
1740
|
+
if (secondCh !== 124 && secondCh !== 45 && secondCh !== 58 && !isSpace(secondCh)) return false;
|
|
1741
|
+
if (firstCh === 45 && isSpace(secondCh)) return false;
|
|
1742
|
+
while (pos < state.eMarks[nextLine]) {
|
|
1743
|
+
const ch = state.src.charCodeAt(pos);
|
|
1744
|
+
if (ch !== 124 && ch !== 45 && ch !== 58 && !isSpace(ch)) return false;
|
|
1745
|
+
pos++;
|
|
1746
|
+
}
|
|
1747
|
+
let lineText = getLine(state, startLine + 1);
|
|
1748
|
+
let columns = lineText.split("|");
|
|
1749
|
+
const aligns = [];
|
|
1750
|
+
for (let i = 0; i < columns.length; i++) {
|
|
1751
|
+
const t = columns[i].trim();
|
|
1752
|
+
if (!t) if (i === 0 || i === columns.length - 1) continue;
|
|
1753
|
+
else return false;
|
|
1754
|
+
if (!/^:?-+:?$/.test(t)) return false;
|
|
1755
|
+
if (t.charCodeAt(t.length - 1) === 58) aligns.push(t.charCodeAt(0) === 58 ? "center" : "right");
|
|
1756
|
+
else if (t.charCodeAt(0) === 58) aligns.push("left");
|
|
1757
|
+
else aligns.push("");
|
|
1758
|
+
}
|
|
1759
|
+
lineText = getLine(state, startLine).trim();
|
|
1760
|
+
if (!lineText.includes("|")) return false;
|
|
1761
|
+
if (state.sCount[startLine] - state.blkIndent >= 4) return false;
|
|
1762
|
+
columns = escapedSplit(lineText);
|
|
1763
|
+
if (columns.length && columns[0] === "") columns.shift();
|
|
1764
|
+
if (columns.length && columns[columns.length - 1] === "") columns.pop();
|
|
1765
|
+
const columnCount = columns.length;
|
|
1766
|
+
if (columnCount === 0 || columnCount !== aligns.length) return false;
|
|
1767
|
+
if (silent) return true;
|
|
1768
|
+
const oldParentType = state.parentType;
|
|
1769
|
+
state.parentType = "table";
|
|
1770
|
+
const terminatorRules = state.md.block.ruler.getRules("blockquote");
|
|
1771
|
+
const token_to = state.push("table_open", "table", 1);
|
|
1772
|
+
const tableLines = [startLine, 0];
|
|
1773
|
+
token_to.map = tableLines;
|
|
1774
|
+
const token_tho = state.push("thead_open", "thead", 1);
|
|
1775
|
+
token_tho.map = [startLine, startLine + 1];
|
|
1776
|
+
const token_htro = state.push("tr_open", "tr", 1);
|
|
1777
|
+
token_htro.map = [startLine, startLine + 1];
|
|
1778
|
+
for (let i = 0; i < columns.length; i++) {
|
|
1779
|
+
const token_ho = state.push("th_open", "th", 1);
|
|
1780
|
+
if (aligns[i]) token_ho.attrs = [["style", `text-align:${aligns[i]}`]];
|
|
1781
|
+
const token_il = state.push("inline", "", 0);
|
|
1782
|
+
token_il.content = columns[i].trim();
|
|
1783
|
+
token_il.children = [];
|
|
1784
|
+
state.push("th_close", "th", -1);
|
|
1785
|
+
}
|
|
1786
|
+
state.push("tr_close", "tr", -1);
|
|
1787
|
+
state.push("thead_close", "thead", -1);
|
|
1788
|
+
let tbodyLines;
|
|
1789
|
+
let autocompletedCells = 0;
|
|
1790
|
+
for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {
|
|
1791
|
+
if (state.sCount[nextLine] < state.blkIndent) break;
|
|
1792
|
+
let terminate = false;
|
|
1793
|
+
for (let i = 0, l = terminatorRules.length; i < l; i++) if (terminatorRules[i](state, nextLine, endLine, true)) {
|
|
1794
|
+
terminate = true;
|
|
1795
|
+
break;
|
|
1796
|
+
}
|
|
1797
|
+
if (terminate) break;
|
|
1798
|
+
lineText = getLine(state, nextLine).trim();
|
|
1799
|
+
if (!lineText) break;
|
|
1800
|
+
if (state.sCount[nextLine] - state.blkIndent >= 4) break;
|
|
1801
|
+
columns = escapedSplit(lineText);
|
|
1802
|
+
if (columns.length && columns[0] === "") columns.shift();
|
|
1803
|
+
if (columns.length && columns[columns.length - 1] === "") columns.pop();
|
|
1804
|
+
autocompletedCells += columnCount - columns.length;
|
|
1805
|
+
if (autocompletedCells > MAX_AUTOCOMPLETED_CELLS) break;
|
|
1806
|
+
if (nextLine === startLine + 2) {
|
|
1807
|
+
const token_tbo = state.push("tbody_open", "tbody", 1);
|
|
1808
|
+
token_tbo.map = tbodyLines = [startLine + 2, 0];
|
|
1809
|
+
}
|
|
1810
|
+
const token_tro = state.push("tr_open", "tr", 1);
|
|
1811
|
+
token_tro.map = [nextLine, nextLine + 1];
|
|
1812
|
+
for (let i = 0; i < columnCount; i++) {
|
|
1813
|
+
const token_tdo = state.push("td_open", "td", 1);
|
|
1814
|
+
if (aligns[i]) token_tdo.attrs = [["style", `text-align:${aligns[i]}`]];
|
|
1815
|
+
const token_il = state.push("inline", "", 0);
|
|
1816
|
+
token_il.content = columns[i] ? columns[i].trim() : "";
|
|
1817
|
+
token_il.children = [];
|
|
1818
|
+
state.push("td_close", "td", -1);
|
|
1819
|
+
}
|
|
1820
|
+
state.push("tr_close", "tr", -1);
|
|
1821
|
+
}
|
|
1822
|
+
if (tbodyLines) {
|
|
1823
|
+
state.push("tbody_close", "tbody", -1);
|
|
1824
|
+
tbodyLines[1] = nextLine;
|
|
1825
|
+
}
|
|
1826
|
+
state.push("table_close", "table", -1);
|
|
1827
|
+
tableLines[1] = nextLine;
|
|
1828
|
+
state.parentType = oldParentType;
|
|
1829
|
+
state.line = nextLine;
|
|
1830
|
+
return true;
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
//#endregion
|
|
1834
|
+
//#region src/parser/block/parser_block.ts
|
|
1835
|
+
const _rules$2 = [
|
|
1836
|
+
[
|
|
1837
|
+
"table",
|
|
1838
|
+
table,
|
|
1839
|
+
["paragraph", "reference"]
|
|
1840
|
+
],
|
|
1841
|
+
["code", code],
|
|
1842
|
+
[
|
|
1843
|
+
"fence",
|
|
1844
|
+
fence,
|
|
1845
|
+
[
|
|
1846
|
+
"paragraph",
|
|
1847
|
+
"reference",
|
|
1848
|
+
"blockquote",
|
|
1849
|
+
"list"
|
|
1850
|
+
]
|
|
1851
|
+
],
|
|
1852
|
+
[
|
|
1853
|
+
"blockquote",
|
|
1854
|
+
blockquote,
|
|
1855
|
+
[
|
|
1856
|
+
"paragraph",
|
|
1857
|
+
"reference",
|
|
1858
|
+
"blockquote",
|
|
1859
|
+
"list"
|
|
1860
|
+
]
|
|
1861
|
+
],
|
|
1862
|
+
[
|
|
1863
|
+
"hr",
|
|
1864
|
+
hr,
|
|
1865
|
+
[
|
|
1866
|
+
"paragraph",
|
|
1867
|
+
"reference",
|
|
1868
|
+
"blockquote",
|
|
1869
|
+
"list"
|
|
1870
|
+
]
|
|
1871
|
+
],
|
|
1872
|
+
[
|
|
1873
|
+
"list",
|
|
1874
|
+
list,
|
|
1875
|
+
[
|
|
1876
|
+
"paragraph",
|
|
1877
|
+
"reference",
|
|
1878
|
+
"blockquote"
|
|
1879
|
+
]
|
|
1880
|
+
],
|
|
1881
|
+
["reference", reference],
|
|
1882
|
+
[
|
|
1883
|
+
"html_block",
|
|
1884
|
+
html_block,
|
|
1885
|
+
[
|
|
1886
|
+
"paragraph",
|
|
1887
|
+
"reference",
|
|
1888
|
+
"blockquote"
|
|
1889
|
+
]
|
|
1890
|
+
],
|
|
1891
|
+
[
|
|
1892
|
+
"heading",
|
|
1893
|
+
heading,
|
|
1894
|
+
[
|
|
1895
|
+
"paragraph",
|
|
1896
|
+
"reference",
|
|
1897
|
+
"blockquote"
|
|
1898
|
+
]
|
|
1899
|
+
],
|
|
1900
|
+
["lheading", lheading],
|
|
1901
|
+
["paragraph", paragraph]
|
|
1902
|
+
];
|
|
1903
|
+
var ParserBlock = class {
|
|
1904
|
+
/**
|
|
1905
|
+
* {@link Ruler} instance. Keep configuration of block rules.
|
|
1906
|
+
*/
|
|
1907
|
+
ruler;
|
|
1908
|
+
constructor() {
|
|
1909
|
+
this.ruler = new Ruler();
|
|
1910
|
+
for (let i = 0; i < _rules$2.length; i++) this.ruler.push(_rules$2[i][0], _rules$2[i][1], { alt: (_rules$2[i][2] || []).slice() });
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1913
|
+
* Generate tokens for input range
|
|
1914
|
+
*/
|
|
1915
|
+
tokenize(state, startLine, endLine, silent) {
|
|
1916
|
+
const rules = this.ruler.getRules("");
|
|
1917
|
+
const len = rules.length;
|
|
1918
|
+
const maxNesting = state.md.options.maxNesting;
|
|
1919
|
+
let line = startLine;
|
|
1920
|
+
let hasEmptyLines = false;
|
|
1921
|
+
while (line < endLine) {
|
|
1922
|
+
state.line = line = state.skipEmptyLines(line);
|
|
1923
|
+
if (line >= endLine) break;
|
|
1924
|
+
if (state.sCount[line] < state.blkIndent) break;
|
|
1925
|
+
if (state.level >= maxNesting) {
|
|
1926
|
+
state.line = endLine;
|
|
1927
|
+
break;
|
|
1928
|
+
}
|
|
1929
|
+
const prevLine = state.line;
|
|
1930
|
+
let ok = false;
|
|
1931
|
+
for (let i = 0; i < len; i++) {
|
|
1932
|
+
ok = rules[i](state, line, endLine, false);
|
|
1933
|
+
if (ok) {
|
|
1934
|
+
if (prevLine >= state.line) throw new Error("block rule didn't increment state.line");
|
|
1935
|
+
break;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
if (!ok) throw new Error("none of the block rules matched");
|
|
1939
|
+
state.tight = !hasEmptyLines;
|
|
1940
|
+
if (state.isEmpty(state.line - 1)) hasEmptyLines = true;
|
|
1941
|
+
line = state.line;
|
|
1942
|
+
if (line < endLine && state.isEmpty(line)) {
|
|
1943
|
+
hasEmptyLines = true;
|
|
1944
|
+
line++;
|
|
1945
|
+
state.line = line;
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
/**
|
|
1950
|
+
* Process input string and push block tokens into `outTokens`
|
|
1951
|
+
*/
|
|
1952
|
+
parse(src, md, env, outTokens) {
|
|
1953
|
+
if (!src) return;
|
|
1954
|
+
const state = new this.State(src, md, env, outTokens);
|
|
1955
|
+
this.tokenize(state, state.line, state.lineMax);
|
|
1956
|
+
}
|
|
1957
|
+
State = StateBlock;
|
|
1958
|
+
};
|
|
1959
|
+
|
|
1960
|
+
//#endregion
|
|
1961
|
+
//#region src/parser/core/rules/block.ts
|
|
1962
|
+
function block(state) {
|
|
1963
|
+
let token;
|
|
1964
|
+
if (state.inlineMode) {
|
|
1965
|
+
token = new state.Token("inline", "", 0);
|
|
1966
|
+
token.content = state.src;
|
|
1967
|
+
token.map = [0, 1];
|
|
1968
|
+
token.children = [];
|
|
1969
|
+
state.tokens.push(token);
|
|
1970
|
+
} else state.md.block.parse(state.src, state.md, state.env, state.tokens);
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
//#endregion
|
|
1974
|
+
//#region src/parser/core/rules/inline.ts
|
|
1975
|
+
function inline(state) {
|
|
1976
|
+
const tokens = state.tokens;
|
|
1977
|
+
for (let i = 0, l = tokens.length; i < l; i++) {
|
|
1978
|
+
const tok = tokens[i];
|
|
1979
|
+
if (tok.type === "inline") state.md.inline.parse(tok.content, state.md, state.env, tok.children);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
//#endregion
|
|
1984
|
+
//#region src/parser/core/rules/linkify.ts
|
|
1985
|
+
function isLinkOpen$1(str) {
|
|
1986
|
+
return /^<a[>\s]/i.test(str);
|
|
1987
|
+
}
|
|
1988
|
+
function isLinkClose$1(str) {
|
|
1989
|
+
return /^<\/a\s*>/i.test(str);
|
|
1990
|
+
}
|
|
1991
|
+
function linkify$1(state) {
|
|
1992
|
+
if (!state.md.options.linkify) return;
|
|
1993
|
+
const blockTokens = state.tokens;
|
|
1994
|
+
const linkify$2 = state.md.linkify;
|
|
1995
|
+
for (let j = 0, l = blockTokens.length; j < l; j++) {
|
|
1996
|
+
if (blockTokens[j].type !== "inline" || !linkify$2.pretest(blockTokens[j].content)) continue;
|
|
1997
|
+
const tokens = blockTokens[j].children;
|
|
1998
|
+
let htmlLinkLevel = 0;
|
|
1999
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
2000
|
+
const currentToken = tokens[i];
|
|
2001
|
+
if (currentToken.type === "link_close") {
|
|
2002
|
+
i--;
|
|
2003
|
+
while (tokens[i].level !== currentToken.level && tokens[i].type !== "link_open") i--;
|
|
2004
|
+
continue;
|
|
2005
|
+
}
|
|
2006
|
+
if (currentToken.type === "html_inline") {
|
|
2007
|
+
if (isLinkOpen$1(currentToken.content) && htmlLinkLevel > 0) htmlLinkLevel--;
|
|
2008
|
+
if (isLinkClose$1(currentToken.content)) htmlLinkLevel++;
|
|
2009
|
+
}
|
|
2010
|
+
if (htmlLinkLevel > 0) continue;
|
|
2011
|
+
if (currentToken.type === "text") {
|
|
2012
|
+
const text$1 = currentToken.content;
|
|
2013
|
+
if (!linkify$2.pretest(text$1)) continue;
|
|
2014
|
+
const links = linkify$2.match(text$1);
|
|
2015
|
+
if (!links?.length) continue;
|
|
2016
|
+
const nodes = [];
|
|
2017
|
+
let level = currentToken.level;
|
|
2018
|
+
let lastPos = 0;
|
|
2019
|
+
const startFrom = links[0].index === 0 && i > 0 && tokens[i - 1].type === "text_special" ? 1 : 0;
|
|
2020
|
+
for (let ln = startFrom; ln < links.length; ln++) {
|
|
2021
|
+
const link$1 = links[ln];
|
|
2022
|
+
const fullUrl = state.md.normalizeLink(link$1.url);
|
|
2023
|
+
if (!state.md.validateLink(fullUrl)) continue;
|
|
2024
|
+
let urlText = link$1.text;
|
|
2025
|
+
if (!link$1.schema) urlText = state.md.normalizeLinkText(`http://${urlText}`).replace(/^http:\/\//, "");
|
|
2026
|
+
else if (link$1.schema === "mailto:" && !/^mailto:/i.test(urlText)) urlText = state.md.normalizeLinkText(`mailto:${urlText}`).replace(/^mailto:/, "");
|
|
2027
|
+
else urlText = state.md.normalizeLinkText(urlText);
|
|
2028
|
+
const pos = link$1.index;
|
|
2029
|
+
if (pos > lastPos) {
|
|
2030
|
+
const token = new state.Token("text", "", 0);
|
|
2031
|
+
token.content = text$1.slice(lastPos, pos);
|
|
2032
|
+
token.level = level;
|
|
2033
|
+
nodes.push(token);
|
|
2034
|
+
}
|
|
2035
|
+
const token_o = new state.Token("link_open", "a", 1);
|
|
2036
|
+
token_o.attrs = [["href", fullUrl]];
|
|
2037
|
+
token_o.level = level++;
|
|
2038
|
+
token_o.markup = "linkify";
|
|
2039
|
+
token_o.info = "auto";
|
|
2040
|
+
nodes.push(token_o);
|
|
2041
|
+
const token_t = new state.Token("text", "", 0);
|
|
2042
|
+
token_t.content = urlText;
|
|
2043
|
+
token_t.level = level;
|
|
2044
|
+
nodes.push(token_t);
|
|
2045
|
+
const token_c = new state.Token("link_close", "a", -1);
|
|
2046
|
+
token_c.level = --level;
|
|
2047
|
+
token_c.markup = "linkify";
|
|
2048
|
+
token_c.info = "auto";
|
|
2049
|
+
nodes.push(token_c);
|
|
2050
|
+
lastPos = link$1.lastIndex;
|
|
2051
|
+
}
|
|
2052
|
+
if (lastPos < text$1.length) {
|
|
2053
|
+
const token = new state.Token("text", "", 0);
|
|
2054
|
+
token.content = text$1.slice(lastPos);
|
|
2055
|
+
token.level = level;
|
|
2056
|
+
nodes.push(token);
|
|
2057
|
+
}
|
|
2058
|
+
tokens.splice(i, 1, ...nodes);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
//#endregion
|
|
2065
|
+
//#region src/parser/core/rules/normalize.ts
|
|
2066
|
+
const NEWLINES_RE = /\r\n?|\n/g;
|
|
2067
|
+
const NULL_RE = /\0/g;
|
|
2068
|
+
function normalize(state) {
|
|
2069
|
+
let str = state.src;
|
|
2070
|
+
const hasCR = str.includes("\r");
|
|
2071
|
+
const hasNull = str.includes("\0");
|
|
2072
|
+
if (!hasCR && !hasNull) return;
|
|
2073
|
+
if (hasCR) str = str.replace(NEWLINES_RE, "\n");
|
|
2074
|
+
if (hasNull) str = str.replace(NULL_RE, "�");
|
|
2075
|
+
state.src = str;
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
//#endregion
|
|
2079
|
+
//#region src/parser/core/rules/replacements.ts
|
|
2080
|
+
const RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/;
|
|
2081
|
+
const SCOPED_ABBR_TEST_RE = /\((?:c|tm|r)\)/i;
|
|
2082
|
+
const SCOPED_ABBR_RE = /\((c|tm|r)\)/gi;
|
|
2083
|
+
const SCOPED_ABBR = {
|
|
2084
|
+
c: "©",
|
|
2085
|
+
r: "®",
|
|
2086
|
+
tm: "™"
|
|
2087
|
+
};
|
|
2088
|
+
function replaceFn(match, name) {
|
|
2089
|
+
return SCOPED_ABBR[name.toLowerCase()];
|
|
2090
|
+
}
|
|
2091
|
+
function replace_scoped(inlineTokens) {
|
|
2092
|
+
let inside_autolink = 0;
|
|
2093
|
+
for (let i = inlineTokens.length - 1; i >= 0; i--) {
|
|
2094
|
+
const token = inlineTokens[i];
|
|
2095
|
+
if (token.type === "text" && !inside_autolink) token.content = token.content.replace(SCOPED_ABBR_RE, replaceFn);
|
|
2096
|
+
if (token.type === "link_open" && token.info === "auto") inside_autolink--;
|
|
2097
|
+
if (token.type === "link_close" && token.info === "auto") inside_autolink++;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
function replace_rare(inlineTokens) {
|
|
2101
|
+
let inside_autolink = 0;
|
|
2102
|
+
for (let i = inlineTokens.length - 1; i >= 0; i--) {
|
|
2103
|
+
const token = inlineTokens[i];
|
|
2104
|
+
if (token.type === "text" && !inside_autolink) {
|
|
2105
|
+
if (RARE_RE.test(token.content)) token.content = token.content.replace(/\+-/g, "±").replace(/\.{2,}/g, "…").replace(/([?!])…/g, "$1..").replace(/([?!]){4,}/g, "$1$1$1").replace(/,{2,}/g, ",").replace(/(^|[^-])---(?=[^-]|$)/gm, "$1—").replace(/(^|\s)--(?=\s|$)/gm, "$1–").replace(/(^|[^-\s])--(?=[^-\s]|$)/gm, "$1–");
|
|
2106
|
+
}
|
|
2107
|
+
if (token.type === "link_open" && token.info === "auto") inside_autolink--;
|
|
2108
|
+
if (token.type === "link_close" && token.info === "auto") inside_autolink++;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
function replace(state) {
|
|
2112
|
+
let blkIdx;
|
|
2113
|
+
if (!state.md.options.typographer) return;
|
|
2114
|
+
for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
|
|
2115
|
+
if (state.tokens[blkIdx].type !== "inline") continue;
|
|
2116
|
+
if (SCOPED_ABBR_TEST_RE.test(state.tokens[blkIdx].content)) replace_scoped(state.tokens[blkIdx].children);
|
|
2117
|
+
if (RARE_RE.test(state.tokens[blkIdx].content)) replace_rare(state.tokens[blkIdx].children);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
//#endregion
|
|
2122
|
+
//#region src/parser/core/rules/smartquotes.ts
|
|
2123
|
+
const QUOTE_TEST_RE = /['"]/;
|
|
2124
|
+
const QUOTE_RE = /['"]/g;
|
|
2125
|
+
const APOSTROPHE = "’";
|
|
2126
|
+
function addReplacement(replacements, tokenIdx, pos, ch) {
|
|
2127
|
+
if (!replacements[tokenIdx]) replacements[tokenIdx] = [];
|
|
2128
|
+
replacements[tokenIdx].push({
|
|
2129
|
+
pos,
|
|
2130
|
+
ch
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2133
|
+
function applyReplacements(str, replacements) {
|
|
2134
|
+
let result = "";
|
|
2135
|
+
let lastPos = 0;
|
|
2136
|
+
replacements.sort((a, b) => a.pos - b.pos);
|
|
2137
|
+
for (let i = 0; i < replacements.length; i++) {
|
|
2138
|
+
const replacement = replacements[i];
|
|
2139
|
+
result += str.slice(lastPos, replacement.pos) + replacement.ch;
|
|
2140
|
+
lastPos = replacement.pos + 1;
|
|
2141
|
+
}
|
|
2142
|
+
return result + str.slice(lastPos);
|
|
2143
|
+
}
|
|
2144
|
+
function process_inlines(tokens, state) {
|
|
2145
|
+
let j;
|
|
2146
|
+
const stack = [];
|
|
2147
|
+
const replacements = {};
|
|
2148
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
2149
|
+
const token = tokens[i];
|
|
2150
|
+
const thisLevel = tokens[i].level;
|
|
2151
|
+
for (j = stack.length - 1; j >= 0; j--) if (stack[j].level <= thisLevel) break;
|
|
2152
|
+
stack.length = j + 1;
|
|
2153
|
+
if (token.type !== "text") continue;
|
|
2154
|
+
const text$1 = token.content;
|
|
2155
|
+
let pos = 0;
|
|
2156
|
+
const max = text$1.length;
|
|
2157
|
+
OUTER: while (pos < max) {
|
|
2158
|
+
QUOTE_RE.lastIndex = pos;
|
|
2159
|
+
const t = QUOTE_RE.exec(text$1);
|
|
2160
|
+
if (!t) break;
|
|
2161
|
+
let canOpen = true;
|
|
2162
|
+
let canClose = true;
|
|
2163
|
+
pos = t.index + 1;
|
|
2164
|
+
const isSingle = t[0] === "'";
|
|
2165
|
+
let lastChar = 32;
|
|
2166
|
+
if (t.index - 1 >= 0) lastChar = text$1.charCodeAt(t.index - 1);
|
|
2167
|
+
else for (j = i - 1; j >= 0; j--) {
|
|
2168
|
+
if (tokens[j].type === "softbreak" || tokens[j].type === "hardbreak") break;
|
|
2169
|
+
if (!tokens[j].content) continue;
|
|
2170
|
+
lastChar = tokens[j].content.charCodeAt(tokens[j].content.length - 1);
|
|
2171
|
+
break;
|
|
2172
|
+
}
|
|
2173
|
+
let nextChar = 32;
|
|
2174
|
+
if (pos < max) nextChar = text$1.charCodeAt(pos);
|
|
2175
|
+
else for (j = i + 1; j < tokens.length; j++) {
|
|
2176
|
+
if (tokens[j].type === "softbreak" || tokens[j].type === "hardbreak") break;
|
|
2177
|
+
if (!tokens[j].content) continue;
|
|
2178
|
+
nextChar = tokens[j].content.charCodeAt(0);
|
|
2179
|
+
break;
|
|
2180
|
+
}
|
|
2181
|
+
const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar);
|
|
2182
|
+
const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar);
|
|
2183
|
+
const isLastWhiteSpace = isWhiteSpace(lastChar);
|
|
2184
|
+
const isNextWhiteSpace = isWhiteSpace(nextChar);
|
|
2185
|
+
if (isNextWhiteSpace) canOpen = false;
|
|
2186
|
+
else if (isNextPunctChar) {
|
|
2187
|
+
if (!(isLastWhiteSpace || isLastPunctChar)) canOpen = false;
|
|
2188
|
+
}
|
|
2189
|
+
if (isLastWhiteSpace) canClose = false;
|
|
2190
|
+
else if (isLastPunctChar) {
|
|
2191
|
+
if (!(isNextWhiteSpace || isNextPunctChar)) canClose = false;
|
|
2192
|
+
}
|
|
2193
|
+
if (nextChar === 34 && t[0] === "\"") {
|
|
2194
|
+
if (lastChar >= 48 && lastChar <= 57) canClose = canOpen = false;
|
|
2195
|
+
}
|
|
2196
|
+
if (canOpen && canClose) {
|
|
2197
|
+
canOpen = isLastPunctChar;
|
|
2198
|
+
canClose = isNextPunctChar;
|
|
2199
|
+
}
|
|
2200
|
+
if (!canOpen && !canClose) {
|
|
2201
|
+
if (isSingle) addReplacement(replacements, i, t.index, APOSTROPHE);
|
|
2202
|
+
continue;
|
|
2203
|
+
}
|
|
2204
|
+
if (canClose) for (j = stack.length - 1; j >= 0; j--) {
|
|
2205
|
+
let item = stack[j];
|
|
2206
|
+
if (stack[j].level < thisLevel) break;
|
|
2207
|
+
if (item.single === isSingle && stack[j].level === thisLevel) {
|
|
2208
|
+
item = stack[j];
|
|
2209
|
+
let openQuote;
|
|
2210
|
+
let closeQuote;
|
|
2211
|
+
if (isSingle) {
|
|
2212
|
+
openQuote = state.md.options.quotes[2];
|
|
2213
|
+
closeQuote = state.md.options.quotes[3];
|
|
2214
|
+
} else {
|
|
2215
|
+
openQuote = state.md.options.quotes[0];
|
|
2216
|
+
closeQuote = state.md.options.quotes[1];
|
|
2217
|
+
}
|
|
2218
|
+
addReplacement(replacements, i, t.index, closeQuote);
|
|
2219
|
+
addReplacement(replacements, item.token, item.pos, openQuote);
|
|
2220
|
+
stack.length = j;
|
|
2221
|
+
continue OUTER;
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
if (canOpen) stack.push({
|
|
2225
|
+
token: i,
|
|
2226
|
+
pos: t.index,
|
|
2227
|
+
single: isSingle,
|
|
2228
|
+
level: thisLevel
|
|
2229
|
+
});
|
|
2230
|
+
else if (canClose && isSingle) addReplacement(replacements, i, t.index, APOSTROPHE);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
Object.keys(replacements).forEach((tokenIdx) => {
|
|
2234
|
+
tokens[tokenIdx].content = applyReplacements(tokens[tokenIdx].content, replacements[tokenIdx]);
|
|
2235
|
+
});
|
|
2236
|
+
}
|
|
2237
|
+
function smartquotes(state) {
|
|
2238
|
+
if (!state.md.options.typographer) return;
|
|
2239
|
+
for (let blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
|
|
2240
|
+
if (state.tokens[blkIdx].type !== "inline" || !QUOTE_TEST_RE.test(state.tokens[blkIdx].content)) continue;
|
|
2241
|
+
process_inlines(state.tokens[blkIdx].children, state);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
//#endregion
|
|
2246
|
+
//#region src/parser/core/rules/text_join.ts
|
|
2247
|
+
function text_join(state) {
|
|
2248
|
+
let curr, last;
|
|
2249
|
+
const blockTokens = state.tokens;
|
|
2250
|
+
const l = blockTokens.length;
|
|
2251
|
+
for (let j = 0; j < l; j++) {
|
|
2252
|
+
if (blockTokens[j].type !== "inline") continue;
|
|
2253
|
+
const tokens = blockTokens[j].children;
|
|
2254
|
+
const max = tokens.length;
|
|
2255
|
+
for (curr = 0; curr < max; curr++) if (tokens[curr].type === "text_special") tokens[curr].type = "text";
|
|
2256
|
+
for (curr = last = 0; curr < max; curr++) if (tokens[curr].type === "text" && curr + 1 < max && tokens[curr + 1].type === "text") tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content;
|
|
2257
|
+
else {
|
|
2258
|
+
if (curr !== last) tokens[last] = tokens[curr];
|
|
2259
|
+
last++;
|
|
2260
|
+
}
|
|
2261
|
+
if (curr !== last) tokens.length = last;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
//#endregion
|
|
2266
|
+
//#region src/parser/core/parser_core.ts
|
|
2267
|
+
const _rules$1 = [
|
|
2268
|
+
["normalize", normalize],
|
|
2269
|
+
["block", block],
|
|
2270
|
+
["inline", inline],
|
|
2271
|
+
["linkify", linkify$1],
|
|
2272
|
+
["replacements", replace],
|
|
2273
|
+
["smartquotes", smartquotes],
|
|
2274
|
+
["text_join", text_join]
|
|
2275
|
+
];
|
|
2276
|
+
var Core = class {
|
|
2277
|
+
/**
|
|
2278
|
+
* {@link Ruler} instance. Keep configuration of core rules.
|
|
2279
|
+
*/
|
|
2280
|
+
ruler;
|
|
2281
|
+
constructor() {
|
|
2282
|
+
this.ruler = new Ruler();
|
|
2283
|
+
for (let i = 0; i < _rules$1.length; i++) this.ruler.push(_rules$1[i][0], _rules$1[i][1]);
|
|
2284
|
+
}
|
|
2285
|
+
/**
|
|
2286
|
+
* Executes core chain rules.
|
|
2287
|
+
*/
|
|
2288
|
+
process(state) {
|
|
2289
|
+
const rules = this.ruler.getRules("");
|
|
2290
|
+
for (let i = 0, l = rules.length; i < l; i++) rules[i](state);
|
|
2291
|
+
}
|
|
2292
|
+
State = StateCore;
|
|
2293
|
+
};
|
|
2294
|
+
|
|
2295
|
+
//#endregion
|
|
2296
|
+
//#region src/parser/helpers/parse_link_destination.ts
|
|
2297
|
+
function parseLinkDestination(str, start, max) {
|
|
2298
|
+
let code$1;
|
|
2299
|
+
let pos = start;
|
|
2300
|
+
const result = {
|
|
2301
|
+
ok: false,
|
|
2302
|
+
pos: 0,
|
|
2303
|
+
str: ""
|
|
2304
|
+
};
|
|
2305
|
+
if (str.charCodeAt(pos) === 60) {
|
|
2306
|
+
pos++;
|
|
2307
|
+
while (pos < max) {
|
|
2308
|
+
code$1 = str.charCodeAt(pos);
|
|
2309
|
+
if (code$1 === 10) return result;
|
|
2310
|
+
if (code$1 === 60) return result;
|
|
2311
|
+
if (code$1 === 62) {
|
|
2312
|
+
result.pos = pos + 1;
|
|
2313
|
+
result.str = unescapeAll(str.slice(start + 1, pos));
|
|
2314
|
+
result.ok = true;
|
|
2315
|
+
return result;
|
|
2316
|
+
}
|
|
2317
|
+
if (code$1 === 92 && pos + 1 < max) {
|
|
2318
|
+
pos += 2;
|
|
2319
|
+
continue;
|
|
2320
|
+
}
|
|
2321
|
+
pos++;
|
|
2322
|
+
}
|
|
2323
|
+
return result;
|
|
2324
|
+
}
|
|
2325
|
+
let level = 0;
|
|
2326
|
+
while (pos < max) {
|
|
2327
|
+
code$1 = str.charCodeAt(pos);
|
|
2328
|
+
if (code$1 === 32) break;
|
|
2329
|
+
if (code$1 < 32 || code$1 === 127) break;
|
|
2330
|
+
if (code$1 === 92 && pos + 1 < max) {
|
|
2331
|
+
if (str.charCodeAt(pos + 1) === 32) break;
|
|
2332
|
+
pos += 2;
|
|
2333
|
+
continue;
|
|
2334
|
+
}
|
|
2335
|
+
if (code$1 === 40) {
|
|
2336
|
+
level++;
|
|
2337
|
+
if (level > 32) return result;
|
|
2338
|
+
}
|
|
2339
|
+
if (code$1 === 41) {
|
|
2340
|
+
if (level === 0) break;
|
|
2341
|
+
level--;
|
|
2342
|
+
}
|
|
2343
|
+
pos++;
|
|
2344
|
+
}
|
|
2345
|
+
if (start === pos) return result;
|
|
2346
|
+
if (level !== 0) return result;
|
|
2347
|
+
result.str = unescapeAll(str.slice(start, pos));
|
|
2348
|
+
result.pos = pos;
|
|
2349
|
+
result.ok = true;
|
|
2350
|
+
return result;
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
//#endregion
|
|
2354
|
+
//#region src/parser/helpers/parse_link_label.ts
|
|
2355
|
+
function parseLinkLabel(state, start, disableNested = false) {
|
|
2356
|
+
let level;
|
|
2357
|
+
let found = false;
|
|
2358
|
+
let marker;
|
|
2359
|
+
let prevPos;
|
|
2360
|
+
const max = state.posMax;
|
|
2361
|
+
const oldPos = state.pos;
|
|
2362
|
+
state.pos = start + 1;
|
|
2363
|
+
level = 1;
|
|
2364
|
+
while (state.pos < max) {
|
|
2365
|
+
marker = state.src.charCodeAt(state.pos);
|
|
2366
|
+
if (marker === 93) {
|
|
2367
|
+
level--;
|
|
2368
|
+
if (level === 0) {
|
|
2369
|
+
found = true;
|
|
2370
|
+
break;
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
prevPos = state.pos;
|
|
2374
|
+
state.md.inline.skipToken(state);
|
|
2375
|
+
if (marker === 91) {
|
|
2376
|
+
if (prevPos === state.pos - 1) level++;
|
|
2377
|
+
else if (disableNested) {
|
|
2378
|
+
state.pos = oldPos;
|
|
2379
|
+
return -1;
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
let labelEnd = -1;
|
|
2384
|
+
if (found) labelEnd = state.pos;
|
|
2385
|
+
state.pos = oldPos;
|
|
2386
|
+
return labelEnd;
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
//#endregion
|
|
2390
|
+
//#region src/parser/helpers/parse_link_title.ts
|
|
2391
|
+
function parseLinkTitle(str, start, max, prev_state) {
|
|
2392
|
+
let code$1;
|
|
2393
|
+
let pos = start;
|
|
2394
|
+
const state = {
|
|
2395
|
+
ok: false,
|
|
2396
|
+
can_continue: false,
|
|
2397
|
+
pos: 0,
|
|
2398
|
+
str: "",
|
|
2399
|
+
marker: 0
|
|
2400
|
+
};
|
|
2401
|
+
if (prev_state) {
|
|
2402
|
+
state.str = prev_state.str;
|
|
2403
|
+
state.marker = prev_state.marker;
|
|
2404
|
+
} else {
|
|
2405
|
+
if (pos >= max) return state;
|
|
2406
|
+
let marker = str.charCodeAt(pos);
|
|
2407
|
+
if (marker !== 34 && marker !== 39 && marker !== 40) return state;
|
|
2408
|
+
start++;
|
|
2409
|
+
pos++;
|
|
2410
|
+
if (marker === 40) marker = 41;
|
|
2411
|
+
state.marker = marker;
|
|
2412
|
+
}
|
|
2413
|
+
while (pos < max) {
|
|
2414
|
+
code$1 = str.charCodeAt(pos);
|
|
2415
|
+
if (code$1 === state.marker) {
|
|
2416
|
+
state.pos = pos + 1;
|
|
2417
|
+
state.str += unescapeAll(str.slice(start, pos));
|
|
2418
|
+
state.ok = true;
|
|
2419
|
+
return state;
|
|
2420
|
+
} else if (code$1 === 40 && state.marker === 41) return state;
|
|
2421
|
+
else if (code$1 === 92 && pos + 1 < max) pos++;
|
|
2422
|
+
pos++;
|
|
2423
|
+
}
|
|
2424
|
+
state.can_continue = true;
|
|
2425
|
+
state.str += unescapeAll(str.slice(start, pos));
|
|
2426
|
+
return state;
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
//#endregion
|
|
2430
|
+
//#region src/parser/helpers/index.ts
|
|
2431
|
+
const helpers = {
|
|
2432
|
+
parseLinkDestination,
|
|
2433
|
+
parseLinkLabel,
|
|
2434
|
+
parseLinkTitle
|
|
2435
|
+
};
|
|
2436
|
+
|
|
2437
|
+
//#endregion
|
|
2438
|
+
//#region src/parser/inline/rules/autolink.ts
|
|
2439
|
+
const EMAIL_RE = /^([\w.!#$%&'*+/=?^`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*)$/i;
|
|
2440
|
+
const AUTOLINK_RE = /^([a-z][a-z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/i;
|
|
2441
|
+
function autolink(state, silent) {
|
|
2442
|
+
let pos = state.pos;
|
|
2443
|
+
if (state.src.charCodeAt(pos) !== 60) return false;
|
|
2444
|
+
const start = state.pos;
|
|
2445
|
+
const max = state.posMax;
|
|
2446
|
+
for (;;) {
|
|
2447
|
+
if (++pos >= max) return false;
|
|
2448
|
+
const ch = state.src.charCodeAt(pos);
|
|
2449
|
+
if (ch === 60) return false;
|
|
2450
|
+
if (ch === 62) break;
|
|
2451
|
+
}
|
|
2452
|
+
const url = state.src.slice(start + 1, pos);
|
|
2453
|
+
if (AUTOLINK_RE.test(url)) {
|
|
2454
|
+
const fullUrl = state.md.normalizeLink(url);
|
|
2455
|
+
if (!state.md.validateLink(fullUrl)) return false;
|
|
2456
|
+
if (!silent) {
|
|
2457
|
+
const token_o = state.push("link_open", "a", 1);
|
|
2458
|
+
token_o.attrs = [["href", fullUrl]];
|
|
2459
|
+
token_o.markup = "autolink";
|
|
2460
|
+
token_o.info = "auto";
|
|
2461
|
+
const token_t = state.push("text", "", 0);
|
|
2462
|
+
token_t.content = state.md.normalizeLinkText(url);
|
|
2463
|
+
const token_c = state.push("link_close", "a", -1);
|
|
2464
|
+
token_c.markup = "autolink";
|
|
2465
|
+
token_c.info = "auto";
|
|
2466
|
+
}
|
|
2467
|
+
state.pos += url.length + 2;
|
|
2468
|
+
return true;
|
|
2469
|
+
}
|
|
2470
|
+
if (EMAIL_RE.test(url)) {
|
|
2471
|
+
const fullUrl = state.md.normalizeLink(`mailto:${url}`);
|
|
2472
|
+
if (!state.md.validateLink(fullUrl)) return false;
|
|
2473
|
+
if (!silent) {
|
|
2474
|
+
const token_o = state.push("link_open", "a", 1);
|
|
2475
|
+
token_o.attrs = [["href", fullUrl]];
|
|
2476
|
+
token_o.markup = "autolink";
|
|
2477
|
+
token_o.info = "auto";
|
|
2478
|
+
const token_t = state.push("text", "", 0);
|
|
2479
|
+
token_t.content = state.md.normalizeLinkText(url);
|
|
2480
|
+
const token_c = state.push("link_close", "a", -1);
|
|
2481
|
+
token_c.markup = "autolink";
|
|
2482
|
+
token_c.info = "auto";
|
|
2483
|
+
}
|
|
2484
|
+
state.pos += url.length + 2;
|
|
2485
|
+
return true;
|
|
2486
|
+
}
|
|
2487
|
+
return false;
|
|
2488
|
+
}
|
|
2489
|
+
|
|
2490
|
+
//#endregion
|
|
2491
|
+
//#region src/parser/inline/rules/backticks.ts
|
|
2492
|
+
function backtick(state, silent) {
|
|
2493
|
+
let pos = state.pos;
|
|
2494
|
+
const src = state.src;
|
|
2495
|
+
if (src.charCodeAt(pos) !== 96) return false;
|
|
2496
|
+
const start = pos;
|
|
2497
|
+
pos++;
|
|
2498
|
+
const max = state.posMax;
|
|
2499
|
+
while (pos < max && src.charCodeAt(pos) === 96) pos++;
|
|
2500
|
+
const marker = src.slice(start, pos);
|
|
2501
|
+
const openerLength = marker.length;
|
|
2502
|
+
if (state.backticksScanned && (state.backticks[openerLength] || 0) <= start) {
|
|
2503
|
+
if (!silent) state.pending += marker;
|
|
2504
|
+
state.pos += openerLength;
|
|
2505
|
+
return true;
|
|
2506
|
+
}
|
|
2507
|
+
let matchEnd = pos;
|
|
2508
|
+
let matchStart;
|
|
2509
|
+
while (true) {
|
|
2510
|
+
matchStart = src.indexOf("`", matchEnd);
|
|
2511
|
+
if (matchStart === -1) break;
|
|
2512
|
+
matchEnd = matchStart + 1;
|
|
2513
|
+
while (matchEnd < max && src.charCodeAt(matchEnd) === 96) matchEnd++;
|
|
2514
|
+
const closerLength = matchEnd - matchStart;
|
|
2515
|
+
if (closerLength === openerLength) {
|
|
2516
|
+
if (!silent) {
|
|
2517
|
+
const token = state.push("code_inline", "code", 0);
|
|
2518
|
+
token.markup = marker;
|
|
2519
|
+
token.content = src.slice(pos, matchStart).replace(/\n/g, " ").replace(/^ (.+) $/, "$1");
|
|
2520
|
+
}
|
|
2521
|
+
state.pos = matchEnd;
|
|
2522
|
+
return true;
|
|
2523
|
+
}
|
|
2524
|
+
state.backticks[closerLength] = matchStart;
|
|
2525
|
+
}
|
|
2526
|
+
state.backticksScanned = true;
|
|
2527
|
+
if (!silent) state.pending += marker;
|
|
2528
|
+
state.pos += openerLength;
|
|
2529
|
+
return true;
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
//#endregion
|
|
2533
|
+
//#region src/parser/inline/rules/balance_pairs.ts
|
|
2534
|
+
function processDelimiters(delimiters) {
|
|
2535
|
+
const openersBottom = {};
|
|
2536
|
+
const max = delimiters.length;
|
|
2537
|
+
if (!max) return;
|
|
2538
|
+
let headerIdx = 0;
|
|
2539
|
+
let lastTokenIdx = -2;
|
|
2540
|
+
const jumps = [];
|
|
2541
|
+
for (let closerIdx = 0; closerIdx < max; closerIdx++) {
|
|
2542
|
+
const closer = delimiters[closerIdx];
|
|
2543
|
+
jumps.push(0);
|
|
2544
|
+
if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) headerIdx = closerIdx;
|
|
2545
|
+
lastTokenIdx = closer.token;
|
|
2546
|
+
closer.length = closer.length || 0;
|
|
2547
|
+
if (!closer.close) continue;
|
|
2548
|
+
if (!openersBottom.hasOwnProperty(closer.marker)) openersBottom[closer.marker] = [
|
|
2549
|
+
-1,
|
|
2550
|
+
-1,
|
|
2551
|
+
-1,
|
|
2552
|
+
-1,
|
|
2553
|
+
-1,
|
|
2554
|
+
-1
|
|
2555
|
+
];
|
|
2556
|
+
const minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + closer.length % 3];
|
|
2557
|
+
let openerIdx = headerIdx - jumps[headerIdx] - 1;
|
|
2558
|
+
let newMinOpenerIdx = openerIdx;
|
|
2559
|
+
for (; openerIdx > minOpenerIdx; openerIdx -= jumps[openerIdx] + 1) {
|
|
2560
|
+
const opener = delimiters[openerIdx];
|
|
2561
|
+
if (opener.marker !== closer.marker) continue;
|
|
2562
|
+
if (opener.open && opener.end < 0) {
|
|
2563
|
+
let isOddMatch = false;
|
|
2564
|
+
if (opener.close || closer.open) {
|
|
2565
|
+
if ((opener.length + closer.length) % 3 === 0) {
|
|
2566
|
+
if (opener.length % 3 !== 0 || closer.length % 3 !== 0) isOddMatch = true;
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
if (!isOddMatch) {
|
|
2570
|
+
const lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open ? jumps[openerIdx - 1] + 1 : 0;
|
|
2571
|
+
jumps[closerIdx] = closerIdx - openerIdx + lastJump;
|
|
2572
|
+
jumps[openerIdx] = lastJump;
|
|
2573
|
+
closer.open = false;
|
|
2574
|
+
opener.end = closerIdx;
|
|
2575
|
+
opener.close = false;
|
|
2576
|
+
newMinOpenerIdx = -1;
|
|
2577
|
+
lastTokenIdx = -2;
|
|
2578
|
+
break;
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
if (newMinOpenerIdx !== -1) openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length || 0) % 3] = newMinOpenerIdx;
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
function link_pairs(state) {
|
|
2586
|
+
const tokens_meta = state.tokens_meta;
|
|
2587
|
+
const max = state.tokens_meta.length;
|
|
2588
|
+
processDelimiters(state.delimiters);
|
|
2589
|
+
for (let curr = 0; curr < max; curr++) {
|
|
2590
|
+
const delimiters = tokens_meta[curr]?.delimiters;
|
|
2591
|
+
if (delimiters) processDelimiters(delimiters);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
//#endregion
|
|
2596
|
+
//#region src/parser/inline/rules/emphasis.ts
|
|
2597
|
+
function emphasis_tokenize(state, silent) {
|
|
2598
|
+
const start = state.pos;
|
|
2599
|
+
const marker = state.src.charCodeAt(start);
|
|
2600
|
+
if (silent) return false;
|
|
2601
|
+
if (marker !== 95 && marker !== 42) return false;
|
|
2602
|
+
const scanned = state.scanDelims(state.pos, marker === 42);
|
|
2603
|
+
for (let i = 0; i < scanned.length; i++) {
|
|
2604
|
+
const token = state.push("text", "", 0);
|
|
2605
|
+
token.content = String.fromCharCode(marker);
|
|
2606
|
+
state.delimiters.push({
|
|
2607
|
+
marker,
|
|
2608
|
+
length: scanned.length,
|
|
2609
|
+
token: state.tokens.length - 1,
|
|
2610
|
+
end: -1,
|
|
2611
|
+
open: scanned.can_open,
|
|
2612
|
+
close: scanned.can_close
|
|
2613
|
+
});
|
|
2614
|
+
}
|
|
2615
|
+
state.pos += scanned.length;
|
|
2616
|
+
return true;
|
|
2617
|
+
}
|
|
2618
|
+
function postProcess$1(state, delimiters) {
|
|
2619
|
+
const max = delimiters.length;
|
|
2620
|
+
for (let i = max - 1; i >= 0; i--) {
|
|
2621
|
+
const startDelim = delimiters[i];
|
|
2622
|
+
if (startDelim.marker !== 95 && startDelim.marker !== 42) continue;
|
|
2623
|
+
if (startDelim.end === -1) continue;
|
|
2624
|
+
const endDelim = delimiters[startDelim.end];
|
|
2625
|
+
const isStrong = i > 0 && delimiters[i - 1].end === startDelim.end + 1 && delimiters[i - 1].marker === startDelim.marker && delimiters[i - 1].token === startDelim.token - 1 && delimiters[startDelim.end + 1].token === endDelim.token + 1;
|
|
2626
|
+
const ch = String.fromCharCode(startDelim.marker);
|
|
2627
|
+
const token_o = state.tokens[startDelim.token];
|
|
2628
|
+
token_o.type = isStrong ? "strong_open" : "em_open";
|
|
2629
|
+
token_o.tag = isStrong ? "strong" : "em";
|
|
2630
|
+
token_o.nesting = 1;
|
|
2631
|
+
token_o.markup = isStrong ? ch + ch : ch;
|
|
2632
|
+
token_o.content = "";
|
|
2633
|
+
const token_c = state.tokens[endDelim.token];
|
|
2634
|
+
token_c.type = isStrong ? "strong_close" : "em_close";
|
|
2635
|
+
token_c.tag = isStrong ? "strong" : "em";
|
|
2636
|
+
token_c.nesting = -1;
|
|
2637
|
+
token_c.markup = isStrong ? ch + ch : ch;
|
|
2638
|
+
token_c.content = "";
|
|
2639
|
+
if (isStrong) {
|
|
2640
|
+
state.tokens[delimiters[i - 1].token].content = "";
|
|
2641
|
+
state.tokens[delimiters[startDelim.end + 1].token].content = "";
|
|
2642
|
+
i--;
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
function emphasis_post_process(state) {
|
|
2647
|
+
const tokens_meta = state.tokens_meta;
|
|
2648
|
+
const max = state.tokens_meta.length;
|
|
2649
|
+
postProcess$1(state, state.delimiters);
|
|
2650
|
+
for (let curr = 0; curr < max; curr++) {
|
|
2651
|
+
const delimiters = tokens_meta[curr]?.delimiters;
|
|
2652
|
+
if (delimiters) postProcess$1(state, delimiters);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
var emphasis_default = {
|
|
2656
|
+
tokenize: emphasis_tokenize,
|
|
2657
|
+
postProcess: emphasis_post_process
|
|
2658
|
+
};
|
|
2659
|
+
|
|
2660
|
+
//#endregion
|
|
2661
|
+
//#region src/parser/inline/rules/entity.ts
|
|
2662
|
+
const DIGITAL_RE = /^&#(x[a-f0-9]{1,6}|\d{1,7});/i;
|
|
2663
|
+
const NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i;
|
|
2664
|
+
function entity(state, silent) {
|
|
2665
|
+
const pos = state.pos;
|
|
2666
|
+
const max = state.posMax;
|
|
2667
|
+
if (state.src.charCodeAt(pos) !== 38) return false;
|
|
2668
|
+
if (pos + 1 >= max) return false;
|
|
2669
|
+
if (state.src.charCodeAt(pos + 1) === 35) {
|
|
2670
|
+
const match = state.src.slice(pos).match(DIGITAL_RE);
|
|
2671
|
+
if (match) {
|
|
2672
|
+
if (!silent) {
|
|
2673
|
+
const code$1 = match[1][0].toLowerCase() === "x" ? Number.parseInt(match[1].slice(1), 16) : Number.parseInt(match[1], 10);
|
|
2674
|
+
const token = state.push("text_special", "", 0);
|
|
2675
|
+
token.content = isValidEntityCode(code$1) ? fromCodePoint(code$1) : fromCodePoint(65533);
|
|
2676
|
+
token.markup = match[0];
|
|
2677
|
+
token.info = "entity";
|
|
2678
|
+
}
|
|
2679
|
+
state.pos += match[0].length;
|
|
2680
|
+
return true;
|
|
2681
|
+
}
|
|
2682
|
+
} else {
|
|
2683
|
+
const match = state.src.slice(pos).match(NAMED_RE);
|
|
2684
|
+
if (match) {
|
|
2685
|
+
const decoded = decodeHTMLStrict(match[0]);
|
|
2686
|
+
if (decoded !== match[0]) {
|
|
2687
|
+
if (!silent) {
|
|
2688
|
+
const token = state.push("text_special", "", 0);
|
|
2689
|
+
token.content = decoded;
|
|
2690
|
+
token.markup = match[0];
|
|
2691
|
+
token.info = "entity";
|
|
2692
|
+
}
|
|
2693
|
+
state.pos += match[0].length;
|
|
2694
|
+
return true;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
return false;
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
//#endregion
|
|
2702
|
+
//#region src/parser/inline/rules/escape.ts
|
|
2703
|
+
const ESCAPED = [];
|
|
2704
|
+
for (let i = 0; i < 256; i++) ESCAPED.push(0);
|
|
2705
|
+
for (const ch of "\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("")) ESCAPED[ch.charCodeAt(0)] = 1;
|
|
2706
|
+
function escape(state, silent) {
|
|
2707
|
+
let pos = state.pos;
|
|
2708
|
+
const max = state.posMax;
|
|
2709
|
+
if (state.src.charCodeAt(pos) !== 92) return false;
|
|
2710
|
+
pos++;
|
|
2711
|
+
if (pos >= max) return false;
|
|
2712
|
+
let ch1 = state.src.charCodeAt(pos);
|
|
2713
|
+
if (ch1 === 10) {
|
|
2714
|
+
if (!silent) state.push("hardbreak", "br", 0);
|
|
2715
|
+
pos++;
|
|
2716
|
+
while (pos < max) {
|
|
2717
|
+
ch1 = state.src.charCodeAt(pos);
|
|
2718
|
+
if (!isSpace(ch1)) break;
|
|
2719
|
+
pos++;
|
|
2720
|
+
}
|
|
2721
|
+
state.pos = pos;
|
|
2722
|
+
return true;
|
|
2723
|
+
}
|
|
2724
|
+
if (ch1 === 32) {
|
|
2725
|
+
if (!silent) {
|
|
2726
|
+
const token = state.push("text_special", "", 0);
|
|
2727
|
+
token.content = "\\";
|
|
2728
|
+
token.markup = "\\";
|
|
2729
|
+
token.info = "escape";
|
|
2730
|
+
}
|
|
2731
|
+
state.pos = pos;
|
|
2732
|
+
return true;
|
|
2733
|
+
}
|
|
2734
|
+
let escapedStr = state.src[pos];
|
|
2735
|
+
if (ch1 >= 55296 && ch1 <= 56319 && pos + 1 < max) {
|
|
2736
|
+
const ch2 = state.src.charCodeAt(pos + 1);
|
|
2737
|
+
if (ch2 >= 56320 && ch2 <= 57343) {
|
|
2738
|
+
escapedStr += state.src[pos + 1];
|
|
2739
|
+
pos++;
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
const origStr = `\\${escapedStr}`;
|
|
2743
|
+
if (!silent) {
|
|
2744
|
+
const token = state.push("text_special", "", 0);
|
|
2745
|
+
if (ch1 < 256 && ESCAPED[ch1] !== 0) token.content = escapedStr;
|
|
2746
|
+
else token.content = origStr;
|
|
2747
|
+
token.markup = origStr;
|
|
2748
|
+
token.info = "escape";
|
|
2749
|
+
}
|
|
2750
|
+
state.pos = pos + 1;
|
|
2751
|
+
return true;
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
//#endregion
|
|
2755
|
+
//#region src/parser/inline/rules/fragments_join.ts
|
|
2756
|
+
function fragments_join(state) {
|
|
2757
|
+
let curr, last;
|
|
2758
|
+
let level = 0;
|
|
2759
|
+
const tokens = state.tokens;
|
|
2760
|
+
const max = state.tokens.length;
|
|
2761
|
+
for (curr = last = 0; curr < max; curr++) {
|
|
2762
|
+
if (tokens[curr].nesting < 0) level--;
|
|
2763
|
+
tokens[curr].level = level;
|
|
2764
|
+
if (tokens[curr].nesting > 0) level++;
|
|
2765
|
+
if (tokens[curr].type === "text" && curr + 1 < max && tokens[curr + 1].type === "text") tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content;
|
|
2766
|
+
else {
|
|
2767
|
+
if (curr !== last) tokens[last] = tokens[curr];
|
|
2768
|
+
last++;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
if (curr !== last) tokens.length = last;
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
//#endregion
|
|
2775
|
+
//#region src/parser/inline/rules/html_inline.ts
|
|
2776
|
+
function isLinkOpen(str) {
|
|
2777
|
+
return /^<a[>\s]/i.test(str);
|
|
2778
|
+
}
|
|
2779
|
+
function isLinkClose(str) {
|
|
2780
|
+
return /^<\/a\s*>/i.test(str);
|
|
2781
|
+
}
|
|
2782
|
+
function isLetter(ch) {
|
|
2783
|
+
const lc = ch | 32;
|
|
2784
|
+
return lc >= 97 && lc <= 122;
|
|
2785
|
+
}
|
|
2786
|
+
function html_inline(state, silent) {
|
|
2787
|
+
if (!state.md.options.html) return false;
|
|
2788
|
+
const max = state.posMax;
|
|
2789
|
+
const pos = state.pos;
|
|
2790
|
+
if (state.src.charCodeAt(pos) !== 60 || pos + 2 >= max) return false;
|
|
2791
|
+
const ch = state.src.charCodeAt(pos + 1);
|
|
2792
|
+
if (ch !== 33 && ch !== 63 && ch !== 47 && !isLetter(ch)) return false;
|
|
2793
|
+
const match = state.src.slice(pos).match(HTML_TAG_RE);
|
|
2794
|
+
if (!match) return false;
|
|
2795
|
+
if (!silent) {
|
|
2796
|
+
const token = state.push("html_inline", "", 0);
|
|
2797
|
+
token.content = match[0];
|
|
2798
|
+
if (isLinkOpen(token.content)) state.linkLevel++;
|
|
2799
|
+
if (isLinkClose(token.content)) state.linkLevel--;
|
|
2800
|
+
}
|
|
2801
|
+
state.pos += match[0].length;
|
|
2802
|
+
return true;
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
//#endregion
|
|
2806
|
+
//#region src/parser/inline/rules/image.ts
|
|
2807
|
+
function image(state, silent) {
|
|
2808
|
+
let code$1, content, label, pos, ref, res, title, start;
|
|
2809
|
+
let href = "";
|
|
2810
|
+
const oldPos = state.pos;
|
|
2811
|
+
const max = state.posMax;
|
|
2812
|
+
if (state.src.charCodeAt(state.pos) !== 33) return false;
|
|
2813
|
+
if (state.src.charCodeAt(state.pos + 1) !== 91) return false;
|
|
2814
|
+
const labelStart = state.pos + 2;
|
|
2815
|
+
const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false);
|
|
2816
|
+
if (labelEnd < 0) return false;
|
|
2817
|
+
pos = labelEnd + 1;
|
|
2818
|
+
if (pos < max && state.src.charCodeAt(pos) === 40) {
|
|
2819
|
+
pos++;
|
|
2820
|
+
for (; pos < max; pos++) {
|
|
2821
|
+
code$1 = state.src.charCodeAt(pos);
|
|
2822
|
+
if (!isSpace(code$1) && code$1 !== 10) break;
|
|
2823
|
+
}
|
|
2824
|
+
if (pos >= max) return false;
|
|
2825
|
+
start = pos;
|
|
2826
|
+
res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);
|
|
2827
|
+
if (res.ok) {
|
|
2828
|
+
href = state.md.normalizeLink(res.str);
|
|
2829
|
+
if (state.md.validateLink(href)) pos = res.pos;
|
|
2830
|
+
else href = "";
|
|
2831
|
+
}
|
|
2832
|
+
start = pos;
|
|
2833
|
+
for (; pos < max; pos++) {
|
|
2834
|
+
code$1 = state.src.charCodeAt(pos);
|
|
2835
|
+
if (!isSpace(code$1) && code$1 !== 10) break;
|
|
2836
|
+
}
|
|
2837
|
+
res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax);
|
|
2838
|
+
if (pos < max && start !== pos && res.ok) {
|
|
2839
|
+
title = res.str;
|
|
2840
|
+
pos = res.pos;
|
|
2841
|
+
for (; pos < max; pos++) {
|
|
2842
|
+
code$1 = state.src.charCodeAt(pos);
|
|
2843
|
+
if (!isSpace(code$1) && code$1 !== 10) break;
|
|
2844
|
+
}
|
|
2845
|
+
} else title = "";
|
|
2846
|
+
if (pos >= max || state.src.charCodeAt(pos) !== 41) {
|
|
2847
|
+
state.pos = oldPos;
|
|
2848
|
+
return false;
|
|
2849
|
+
}
|
|
2850
|
+
pos++;
|
|
2851
|
+
} else {
|
|
2852
|
+
if (typeof state.env.references === "undefined") return false;
|
|
2853
|
+
if (pos < max && state.src.charCodeAt(pos) === 91) {
|
|
2854
|
+
start = pos + 1;
|
|
2855
|
+
pos = state.md.helpers.parseLinkLabel(state, pos);
|
|
2856
|
+
if (pos >= 0) label = state.src.slice(start, pos++);
|
|
2857
|
+
else pos = labelEnd + 1;
|
|
2858
|
+
} else pos = labelEnd + 1;
|
|
2859
|
+
if (!label) label = state.src.slice(labelStart, labelEnd);
|
|
2860
|
+
ref = state.env.references[normalizeReference(label)];
|
|
2861
|
+
if (!ref) {
|
|
2862
|
+
state.pos = oldPos;
|
|
2863
|
+
return false;
|
|
2864
|
+
}
|
|
2865
|
+
href = ref.href;
|
|
2866
|
+
title = ref.title;
|
|
2867
|
+
}
|
|
2868
|
+
if (!silent) {
|
|
2869
|
+
content = state.src.slice(labelStart, labelEnd);
|
|
2870
|
+
const tokens = [];
|
|
2871
|
+
state.md.inline.parse(content, state.md, state.env, tokens);
|
|
2872
|
+
const token = state.push("image", "img", 0);
|
|
2873
|
+
const attrs = [["src", href], ["alt", ""]];
|
|
2874
|
+
token.attrs = attrs;
|
|
2875
|
+
token.children = tokens;
|
|
2876
|
+
token.content = content;
|
|
2877
|
+
if (title) attrs.push(["title", title]);
|
|
2878
|
+
}
|
|
2879
|
+
state.pos = pos;
|
|
2880
|
+
state.posMax = max;
|
|
2881
|
+
return true;
|
|
2882
|
+
}
|
|
2883
|
+
|
|
2884
|
+
//#endregion
|
|
2885
|
+
//#region src/parser/inline/rules/link.ts
|
|
2886
|
+
function link(state, silent) {
|
|
2887
|
+
let code$1, label, res, ref;
|
|
2888
|
+
let href = "";
|
|
2889
|
+
let title = "";
|
|
2890
|
+
let start = state.pos;
|
|
2891
|
+
let parseReference = true;
|
|
2892
|
+
if (state.src.charCodeAt(state.pos) !== 91) return false;
|
|
2893
|
+
const oldPos = state.pos;
|
|
2894
|
+
const max = state.posMax;
|
|
2895
|
+
const labelStart = state.pos + 1;
|
|
2896
|
+
const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true);
|
|
2897
|
+
if (labelEnd < 0) return false;
|
|
2898
|
+
let pos = labelEnd + 1;
|
|
2899
|
+
if (pos < max && state.src.charCodeAt(pos) === 40) {
|
|
2900
|
+
parseReference = false;
|
|
2901
|
+
pos++;
|
|
2902
|
+
for (; pos < max; pos++) {
|
|
2903
|
+
code$1 = state.src.charCodeAt(pos);
|
|
2904
|
+
if (!isSpace(code$1) && code$1 !== 10) break;
|
|
2905
|
+
}
|
|
2906
|
+
if (pos >= max) return false;
|
|
2907
|
+
start = pos;
|
|
2908
|
+
res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);
|
|
2909
|
+
if (res.ok) {
|
|
2910
|
+
href = state.md.normalizeLink(res.str);
|
|
2911
|
+
if (state.md.validateLink(href)) pos = res.pos;
|
|
2912
|
+
else href = "";
|
|
2913
|
+
start = pos;
|
|
2914
|
+
for (; pos < max; pos++) {
|
|
2915
|
+
code$1 = state.src.charCodeAt(pos);
|
|
2916
|
+
if (!isSpace(code$1) && code$1 !== 10) break;
|
|
2917
|
+
}
|
|
2918
|
+
res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax);
|
|
2919
|
+
if (pos < max && start !== pos && res.ok) {
|
|
2920
|
+
title = res.str;
|
|
2921
|
+
pos = res.pos;
|
|
2922
|
+
for (; pos < max; pos++) {
|
|
2923
|
+
code$1 = state.src.charCodeAt(pos);
|
|
2924
|
+
if (!isSpace(code$1) && code$1 !== 10) break;
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
if (pos >= max || state.src.charCodeAt(pos) !== 41) parseReference = true;
|
|
2929
|
+
pos++;
|
|
2930
|
+
}
|
|
2931
|
+
if (parseReference) {
|
|
2932
|
+
if (typeof state.env.references === "undefined") return false;
|
|
2933
|
+
if (pos < max && state.src.charCodeAt(pos) === 91) {
|
|
2934
|
+
start = pos + 1;
|
|
2935
|
+
pos = state.md.helpers.parseLinkLabel(state, pos);
|
|
2936
|
+
if (pos >= 0) label = state.src.slice(start, pos++);
|
|
2937
|
+
else pos = labelEnd + 1;
|
|
2938
|
+
} else pos = labelEnd + 1;
|
|
2939
|
+
if (!label) label = state.src.slice(labelStart, labelEnd);
|
|
2940
|
+
ref = state.env.references[normalizeReference(label)];
|
|
2941
|
+
if (!ref) {
|
|
2942
|
+
state.pos = oldPos;
|
|
2943
|
+
return false;
|
|
2944
|
+
}
|
|
2945
|
+
href = ref.href;
|
|
2946
|
+
title = ref.title;
|
|
2947
|
+
}
|
|
2948
|
+
if (!silent) {
|
|
2949
|
+
state.pos = labelStart;
|
|
2950
|
+
state.posMax = labelEnd;
|
|
2951
|
+
const token_o = state.push("link_open", "a", 1);
|
|
2952
|
+
const attrs = [["href", href]];
|
|
2953
|
+
token_o.attrs = attrs;
|
|
2954
|
+
if (title) attrs.push(["title", title]);
|
|
2955
|
+
state.linkLevel++;
|
|
2956
|
+
state.md.inline.tokenize(state);
|
|
2957
|
+
state.linkLevel--;
|
|
2958
|
+
state.push("link_close", "a", -1);
|
|
2959
|
+
}
|
|
2960
|
+
state.pos = pos;
|
|
2961
|
+
state.posMax = max;
|
|
2962
|
+
return true;
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
//#endregion
|
|
2966
|
+
//#region src/parser/inline/rules/linkify.ts
|
|
2967
|
+
const SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i;
|
|
2968
|
+
function linkify(state, silent) {
|
|
2969
|
+
if (!state.md.options.linkify) return false;
|
|
2970
|
+
if (state.linkLevel > 0) return false;
|
|
2971
|
+
const pos = state.pos;
|
|
2972
|
+
const max = state.posMax;
|
|
2973
|
+
if (pos + 3 > max) return false;
|
|
2974
|
+
if (state.src.charCodeAt(pos) !== 58) return false;
|
|
2975
|
+
if (state.src.charCodeAt(pos + 1) !== 47) return false;
|
|
2976
|
+
if (state.src.charCodeAt(pos + 2) !== 47) return false;
|
|
2977
|
+
const match = state.pending.match(SCHEME_RE);
|
|
2978
|
+
if (!match) return false;
|
|
2979
|
+
const proto = match[1];
|
|
2980
|
+
const link$1 = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length));
|
|
2981
|
+
if (!link$1) return false;
|
|
2982
|
+
let url = link$1.url;
|
|
2983
|
+
if (url.length <= proto.length) return false;
|
|
2984
|
+
let urlEnd = url.length;
|
|
2985
|
+
while (urlEnd > 0 && url.charCodeAt(urlEnd - 1) === 42) urlEnd--;
|
|
2986
|
+
if (urlEnd !== url.length) url = url.slice(0, urlEnd);
|
|
2987
|
+
const fullUrl = state.md.normalizeLink(url);
|
|
2988
|
+
if (!state.md.validateLink(fullUrl)) return false;
|
|
2989
|
+
if (!silent) {
|
|
2990
|
+
state.pending = state.pending.slice(0, -proto.length);
|
|
2991
|
+
const token_o = state.push("link_open", "a", 1);
|
|
2992
|
+
token_o.attrs = [["href", fullUrl]];
|
|
2993
|
+
token_o.markup = "linkify";
|
|
2994
|
+
token_o.info = "auto";
|
|
2995
|
+
const token_t = state.push("text", "", 0);
|
|
2996
|
+
token_t.content = state.md.normalizeLinkText(url);
|
|
2997
|
+
const token_c = state.push("link_close", "a", -1);
|
|
2998
|
+
token_c.markup = "linkify";
|
|
2999
|
+
token_c.info = "auto";
|
|
3000
|
+
}
|
|
3001
|
+
state.pos += url.length - proto.length;
|
|
3002
|
+
return true;
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
//#endregion
|
|
3006
|
+
//#region src/parser/inline/rules/newline.ts
|
|
3007
|
+
function newline(state, silent) {
|
|
3008
|
+
let pos = state.pos;
|
|
3009
|
+
if (state.src.charCodeAt(pos) !== 10) return false;
|
|
3010
|
+
const pmax = state.pending.length - 1;
|
|
3011
|
+
const max = state.posMax;
|
|
3012
|
+
if (!silent) if (pmax >= 0 && state.pending.charCodeAt(pmax) === 32) if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 32) {
|
|
3013
|
+
let ws = pmax - 1;
|
|
3014
|
+
while (ws >= 1 && state.pending.charCodeAt(ws - 1) === 32) ws--;
|
|
3015
|
+
state.pending = state.pending.slice(0, ws);
|
|
3016
|
+
state.push("hardbreak", "br", 0);
|
|
3017
|
+
} else {
|
|
3018
|
+
state.pending = state.pending.slice(0, -1);
|
|
3019
|
+
state.push("softbreak", "br", 0);
|
|
3020
|
+
}
|
|
3021
|
+
else state.push("softbreak", "br", 0);
|
|
3022
|
+
pos++;
|
|
3023
|
+
while (pos < max && isSpace(state.src.charCodeAt(pos))) pos++;
|
|
3024
|
+
state.pos = pos;
|
|
3025
|
+
return true;
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
//#endregion
|
|
3029
|
+
//#region src/parser/inline/rules/strikethrough.ts
|
|
3030
|
+
function strikethrough_tokenize(state, silent) {
|
|
3031
|
+
const start = state.pos;
|
|
3032
|
+
const marker = state.src.charCodeAt(start);
|
|
3033
|
+
if (silent) return false;
|
|
3034
|
+
if (marker !== 126) return false;
|
|
3035
|
+
const scanned = state.scanDelims(state.pos, true);
|
|
3036
|
+
let len = scanned.length;
|
|
3037
|
+
const ch = String.fromCharCode(marker);
|
|
3038
|
+
if (len < 2) return false;
|
|
3039
|
+
let token;
|
|
3040
|
+
if (len % 2) {
|
|
3041
|
+
token = state.push("text", "", 0);
|
|
3042
|
+
token.content = ch;
|
|
3043
|
+
len--;
|
|
3044
|
+
}
|
|
3045
|
+
for (let i = 0; i < len; i += 2) {
|
|
3046
|
+
token = state.push("text", "", 0);
|
|
3047
|
+
token.content = ch + ch;
|
|
3048
|
+
state.delimiters.push({
|
|
3049
|
+
marker,
|
|
3050
|
+
length: 0,
|
|
3051
|
+
token: state.tokens.length - 1,
|
|
3052
|
+
end: -1,
|
|
3053
|
+
open: scanned.can_open,
|
|
3054
|
+
close: scanned.can_close
|
|
3055
|
+
});
|
|
3056
|
+
}
|
|
3057
|
+
state.pos += scanned.length;
|
|
3058
|
+
return true;
|
|
3059
|
+
}
|
|
3060
|
+
function postProcess(state, delimiters) {
|
|
3061
|
+
let token;
|
|
3062
|
+
const loneMarkers = [];
|
|
3063
|
+
const max = delimiters.length;
|
|
3064
|
+
for (let i = 0; i < max; i++) {
|
|
3065
|
+
const startDelim = delimiters[i];
|
|
3066
|
+
if (startDelim.marker !== 126) continue;
|
|
3067
|
+
if (startDelim.end === -1) continue;
|
|
3068
|
+
const endDelim = delimiters[startDelim.end];
|
|
3069
|
+
token = state.tokens[startDelim.token];
|
|
3070
|
+
token.type = "s_open";
|
|
3071
|
+
token.tag = "s";
|
|
3072
|
+
token.nesting = 1;
|
|
3073
|
+
token.markup = "~~";
|
|
3074
|
+
token.content = "";
|
|
3075
|
+
token = state.tokens[endDelim.token];
|
|
3076
|
+
token.type = "s_close";
|
|
3077
|
+
token.tag = "s";
|
|
3078
|
+
token.nesting = -1;
|
|
3079
|
+
token.markup = "~~";
|
|
3080
|
+
token.content = "";
|
|
3081
|
+
if (state.tokens[endDelim.token - 1].type === "text" && state.tokens[endDelim.token - 1].content === "~") loneMarkers.push(endDelim.token - 1);
|
|
3082
|
+
}
|
|
3083
|
+
while (loneMarkers.length) {
|
|
3084
|
+
const i = loneMarkers.pop();
|
|
3085
|
+
let j = i + 1;
|
|
3086
|
+
while (j < state.tokens.length && state.tokens[j].type === "s_close") j++;
|
|
3087
|
+
j--;
|
|
3088
|
+
if (i !== j) {
|
|
3089
|
+
token = state.tokens[j];
|
|
3090
|
+
state.tokens[j] = state.tokens[i];
|
|
3091
|
+
state.tokens[i] = token;
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
function strikethrough_postProcess(state) {
|
|
3096
|
+
const tokens_meta = state.tokens_meta;
|
|
3097
|
+
const max = state.tokens_meta.length;
|
|
3098
|
+
postProcess(state, state.delimiters);
|
|
3099
|
+
for (let curr = 0; curr < max; curr++) {
|
|
3100
|
+
const delimiters = tokens_meta[curr]?.delimiters;
|
|
3101
|
+
if (delimiters) postProcess(state, delimiters);
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
var strikethrough_default = {
|
|
3105
|
+
tokenize: strikethrough_tokenize,
|
|
3106
|
+
postProcess: strikethrough_postProcess
|
|
3107
|
+
};
|
|
3108
|
+
|
|
3109
|
+
//#endregion
|
|
3110
|
+
//#region src/parser/inline/rules/text.ts
|
|
3111
|
+
function isTerminatorChar(ch) {
|
|
3112
|
+
switch (ch) {
|
|
3113
|
+
case 10:
|
|
3114
|
+
case 33:
|
|
3115
|
+
case 35:
|
|
3116
|
+
case 36:
|
|
3117
|
+
case 37:
|
|
3118
|
+
case 38:
|
|
3119
|
+
case 42:
|
|
3120
|
+
case 43:
|
|
3121
|
+
case 45:
|
|
3122
|
+
case 58:
|
|
3123
|
+
case 60:
|
|
3124
|
+
case 61:
|
|
3125
|
+
case 62:
|
|
3126
|
+
case 64:
|
|
3127
|
+
case 91:
|
|
3128
|
+
case 92:
|
|
3129
|
+
case 93:
|
|
3130
|
+
case 94:
|
|
3131
|
+
case 95:
|
|
3132
|
+
case 96:
|
|
3133
|
+
case 123:
|
|
3134
|
+
case 125:
|
|
3135
|
+
case 126: return true;
|
|
3136
|
+
default: return false;
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
function text(state, silent) {
|
|
3140
|
+
let pos = state.pos;
|
|
3141
|
+
const src = state.src;
|
|
3142
|
+
while (pos < state.posMax && !isTerminatorChar(src.charCodeAt(pos))) pos++;
|
|
3143
|
+
if (pos === state.pos) return false;
|
|
3144
|
+
if (!silent) state.pending += src.slice(state.pos, pos);
|
|
3145
|
+
state.pos = pos;
|
|
3146
|
+
return true;
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
//#endregion
|
|
3150
|
+
//#region src/parser/inline/parser_inline.ts
|
|
3151
|
+
const _rules = [
|
|
3152
|
+
["text", text],
|
|
3153
|
+
["linkify", linkify],
|
|
3154
|
+
["newline", newline],
|
|
3155
|
+
["escape", escape],
|
|
3156
|
+
["backticks", backtick],
|
|
3157
|
+
["strikethrough", strikethrough_default.tokenize],
|
|
3158
|
+
["emphasis", emphasis_default.tokenize],
|
|
3159
|
+
["link", link],
|
|
3160
|
+
["image", image],
|
|
3161
|
+
["autolink", autolink],
|
|
3162
|
+
["html_inline", html_inline],
|
|
3163
|
+
["entity", entity]
|
|
3164
|
+
];
|
|
3165
|
+
const _rules2 = [
|
|
3166
|
+
["balance_pairs", link_pairs],
|
|
3167
|
+
["strikethrough", strikethrough_default.postProcess],
|
|
3168
|
+
["emphasis", emphasis_default.postProcess],
|
|
3169
|
+
["fragments_join", fragments_join]
|
|
3170
|
+
];
|
|
3171
|
+
var ParserInline = class {
|
|
3172
|
+
/**
|
|
3173
|
+
* {@link Ruler} instance. Keep configuration of inline rules.
|
|
3174
|
+
*/
|
|
3175
|
+
ruler;
|
|
3176
|
+
/**
|
|
3177
|
+
* {@link Ruler} instance. Second ruler used for post-processing
|
|
3178
|
+
* (e.g. in emphasis-like rules).
|
|
3179
|
+
*/
|
|
3180
|
+
ruler2;
|
|
3181
|
+
constructor() {
|
|
3182
|
+
/**
|
|
3183
|
+
* ParserInline#ruler -> Ruler
|
|
3184
|
+
*
|
|
3185
|
+
* [[Ruler]] instance. Keep configuration of inline rules.
|
|
3186
|
+
*/
|
|
3187
|
+
this.ruler = new Ruler();
|
|
3188
|
+
for (let i = 0; i < _rules.length; i++) this.ruler.push(_rules[i][0], _rules[i][1]);
|
|
3189
|
+
/**
|
|
3190
|
+
* ParserInline#ruler2 -> Ruler
|
|
3191
|
+
*
|
|
3192
|
+
* [[Ruler]] instance. Second ruler used for post-processing
|
|
3193
|
+
* (e.g. in emphasis-like rules).
|
|
3194
|
+
*/
|
|
3195
|
+
this.ruler2 = new Ruler();
|
|
3196
|
+
for (let i = 0; i < _rules2.length; i++) this.ruler2.push(_rules2[i][0], _rules2[i][1]);
|
|
3197
|
+
}
|
|
3198
|
+
/**
|
|
3199
|
+
* Skip single token by running all rules in validation mode;
|
|
3200
|
+
* returns `true` if any rule reported success
|
|
3201
|
+
*/
|
|
3202
|
+
skipToken(state) {
|
|
3203
|
+
const pos = state.pos;
|
|
3204
|
+
const rules = this.ruler.getRules("");
|
|
3205
|
+
const len = rules.length;
|
|
3206
|
+
const maxNesting = state.md.options.maxNesting;
|
|
3207
|
+
const cache = state.cache;
|
|
3208
|
+
const cachedPos = cache[pos];
|
|
3209
|
+
if (cachedPos !== void 0) {
|
|
3210
|
+
state.pos = cachedPos;
|
|
3211
|
+
return;
|
|
3212
|
+
}
|
|
3213
|
+
let ok = false;
|
|
3214
|
+
if (state.level < maxNesting) for (let i = 0; i < len; i++) {
|
|
3215
|
+
state.level++;
|
|
3216
|
+
ok = rules[i](state, true);
|
|
3217
|
+
state.level--;
|
|
3218
|
+
if (ok) {
|
|
3219
|
+
if (pos >= state.pos) throw new Error("inline rule didn't increment state.pos");
|
|
3220
|
+
break;
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
else state.pos = state.posMax;
|
|
3224
|
+
if (!ok) state.pos++;
|
|
3225
|
+
cache[pos] = state.pos;
|
|
3226
|
+
}
|
|
3227
|
+
/**
|
|
3228
|
+
* Generate tokens for input range
|
|
3229
|
+
*/
|
|
3230
|
+
tokenize(state) {
|
|
3231
|
+
const rules = this.ruler.getRules("");
|
|
3232
|
+
const len = rules.length;
|
|
3233
|
+
const end = state.posMax;
|
|
3234
|
+
const maxNesting = state.md.options.maxNesting;
|
|
3235
|
+
while (state.pos < end) {
|
|
3236
|
+
const prevPos = state.pos;
|
|
3237
|
+
let ok = false;
|
|
3238
|
+
if (state.level < maxNesting) for (let i = 0; i < len; i++) {
|
|
3239
|
+
ok = rules[i](state, false);
|
|
3240
|
+
if (ok) {
|
|
3241
|
+
if (prevPos >= state.pos) throw new Error("inline rule didn't increment state.pos");
|
|
3242
|
+
break;
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
if (ok) {
|
|
3246
|
+
if (state.pos >= end) break;
|
|
3247
|
+
continue;
|
|
3248
|
+
}
|
|
3249
|
+
state.pending += state.src[state.pos++];
|
|
3250
|
+
}
|
|
3251
|
+
if (state.pending) state.pushPending();
|
|
3252
|
+
}
|
|
3253
|
+
/**
|
|
3254
|
+
* Process input string and push inline tokens into `outTokens`
|
|
3255
|
+
*/
|
|
3256
|
+
parse(str, md, env, outTokens) {
|
|
3257
|
+
const state = new this.State(str, md, env, outTokens);
|
|
3258
|
+
this.tokenize(state);
|
|
3259
|
+
const rules = this.ruler2.getRules("");
|
|
3260
|
+
const len = rules.length;
|
|
3261
|
+
for (let i = 0; i < len; i++) rules[i](state);
|
|
3262
|
+
}
|
|
3263
|
+
State = StateInline;
|
|
3264
|
+
};
|
|
3265
|
+
|
|
3266
|
+
//#endregion
|
|
3267
|
+
//#region src/parser/utils/link.ts
|
|
3268
|
+
const BAD_PROTO_RE = /^(vbscript|javascript|file|data):/;
|
|
3269
|
+
const GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/;
|
|
3270
|
+
function validateLink(url) {
|
|
3271
|
+
const str = url.trim().toLowerCase();
|
|
3272
|
+
return BAD_PROTO_RE.test(str) ? GOOD_DATA_RE.test(str) : true;
|
|
3273
|
+
}
|
|
3274
|
+
const RECODE_HOSTNAME_FOR = [
|
|
3275
|
+
"http:",
|
|
3276
|
+
"https:",
|
|
3277
|
+
"mailto:"
|
|
3278
|
+
];
|
|
3279
|
+
function normalizeLink(url) {
|
|
3280
|
+
const parsed = mdurl.parse(url, true);
|
|
3281
|
+
if (parsed.hostname) {
|
|
3282
|
+
if (!parsed.protocol || RECODE_HOSTNAME_FOR.includes(parsed.protocol)) try {
|
|
3283
|
+
parsed.hostname = punycode.toASCII(parsed.hostname);
|
|
3284
|
+
} catch {}
|
|
3285
|
+
}
|
|
3286
|
+
return mdurl.encode(mdurl.format(parsed));
|
|
3287
|
+
}
|
|
3288
|
+
function normalizeLinkText(url) {
|
|
3289
|
+
const parsed = mdurl.parse(url, true);
|
|
3290
|
+
if (parsed.hostname) {
|
|
3291
|
+
if (!parsed.protocol || RECODE_HOSTNAME_FOR.includes(parsed.protocol)) try {
|
|
3292
|
+
parsed.hostname = punycode.toUnicode(parsed.hostname);
|
|
3293
|
+
} catch {}
|
|
3294
|
+
}
|
|
3295
|
+
return mdurl.decode(mdurl.format(parsed), `${mdurl.decode.defaultChars}%`);
|
|
3296
|
+
}
|
|
3297
|
+
|
|
3298
|
+
//#endregion
|
|
3299
|
+
//#region src/parser/parser.ts
|
|
3300
|
+
const defaultOptions = {
|
|
3301
|
+
html: false,
|
|
3302
|
+
linkify: false,
|
|
3303
|
+
typographer: false,
|
|
3304
|
+
quotes: "“”‘’",
|
|
3305
|
+
maxNesting: 100
|
|
3306
|
+
};
|
|
3307
|
+
var Parser = class {
|
|
3308
|
+
/**
|
|
3309
|
+
* Instance of {@link ParserInline}. You may need it to add new rules when writing plugins.
|
|
3310
|
+
*/
|
|
3311
|
+
inline = new ParserInline();
|
|
3312
|
+
/**
|
|
3313
|
+
* Instance of {@link ParserBlock}. You may need it to add new rules when writing plugins.
|
|
3314
|
+
*/
|
|
3315
|
+
block = new ParserBlock();
|
|
3316
|
+
/**
|
|
3317
|
+
* Instance of {@link Core} chain executor. You may need it to add new rules when writing plugins.
|
|
3318
|
+
*/
|
|
3319
|
+
core = new Core();
|
|
3320
|
+
/**
|
|
3321
|
+
* [linkify-it](https://github.com/markdown-it/linkify-it) instance.
|
|
3322
|
+
* Used by [linkify](https://github.com/serkodev/markdown-exit/blob/main/packages/markdown-exit/src/parser/core/rules/linkify.ts)
|
|
3323
|
+
* rule.
|
|
3324
|
+
*/
|
|
3325
|
+
linkify = new LinkifyIt();
|
|
3326
|
+
/**
|
|
3327
|
+
* Link validation function. CommonMark allows too much in links. By default
|
|
3328
|
+
* we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas
|
|
3329
|
+
* except some embedded image types.
|
|
3330
|
+
*
|
|
3331
|
+
* You can change this behaviour:
|
|
3332
|
+
*
|
|
3333
|
+
* ```javascript
|
|
3334
|
+
* // enable everything
|
|
3335
|
+
* md.validateLink = () => true
|
|
3336
|
+
* ```
|
|
3337
|
+
*/
|
|
3338
|
+
validateLink = validateLink;
|
|
3339
|
+
/**
|
|
3340
|
+
* Function used to encode link url to a machine-readable format,
|
|
3341
|
+
* which includes url-encoding, punycode, etc.
|
|
3342
|
+
*/
|
|
3343
|
+
normalizeLink = normalizeLink;
|
|
3344
|
+
/**
|
|
3345
|
+
* Function used to decode link url to a human-readable format`
|
|
3346
|
+
*/
|
|
3347
|
+
normalizeLinkText = normalizeLinkText;
|
|
3348
|
+
/**
|
|
3349
|
+
* Link components parser functions, useful to write plugins. See details
|
|
3350
|
+
* [here](https://github.com/serkodev/markdown-exit/tree/main/packages/markdown-exit/src/parser/helpers).
|
|
3351
|
+
*/
|
|
3352
|
+
helpers = { ...helpers };
|
|
3353
|
+
options = { ...defaultOptions };
|
|
3354
|
+
/**
|
|
3355
|
+
* Parse input string and returns list of block tokens (special token type
|
|
3356
|
+
* "inline" will contain list of inline tokens). You should not call this
|
|
3357
|
+
* method directly, until you write custom renderer (for example, to produce
|
|
3358
|
+
* AST).
|
|
3359
|
+
*
|
|
3360
|
+
* `env` is used to pass data between "distributed" rules and return additional
|
|
3361
|
+
* metadata like reference info, needed for the renderer. It also can be used to
|
|
3362
|
+
* inject data in specific cases. Usually, you will be ok to pass `{}`,
|
|
3363
|
+
* and then pass updated object to renderer.
|
|
3364
|
+
*
|
|
3365
|
+
* @param src source string
|
|
3366
|
+
* @param env environment sandbox
|
|
3367
|
+
*/
|
|
3368
|
+
parse(src, env = {}) {
|
|
3369
|
+
if (typeof src !== "string") throw new TypeError("Input data should be a String");
|
|
3370
|
+
const state = new this.core.State(src, this, env);
|
|
3371
|
+
this.core.process(state);
|
|
3372
|
+
return state.tokens;
|
|
3373
|
+
}
|
|
3374
|
+
/**
|
|
3375
|
+
* The same as {@link parse} but skip all block rules. It returns the
|
|
3376
|
+
* block tokens list with the single `inline` element, containing parsed inline
|
|
3377
|
+
* tokens in `children` property. Also updates `env` object.
|
|
3378
|
+
*
|
|
3379
|
+
* @param src source string
|
|
3380
|
+
* @param env environment sandbox
|
|
3381
|
+
*/
|
|
3382
|
+
parseInline(src, env = {}) {
|
|
3383
|
+
const state = new this.core.State(src, this, env);
|
|
3384
|
+
state.inlineMode = true;
|
|
3385
|
+
this.core.process(state);
|
|
3386
|
+
return state.tokens;
|
|
3387
|
+
}
|
|
3388
|
+
};
|
|
3389
|
+
|
|
3390
|
+
//#endregion
|
|
3391
|
+
//#region src/presets/commonmark.ts
|
|
3392
|
+
const commonmarkPreset = {
|
|
3393
|
+
options: {
|
|
3394
|
+
html: true,
|
|
3395
|
+
xhtmlOut: true,
|
|
3396
|
+
breaks: false,
|
|
3397
|
+
langPrefix: "language-",
|
|
3398
|
+
linkify: false,
|
|
3399
|
+
typographer: false,
|
|
3400
|
+
quotes: "“”‘’",
|
|
3401
|
+
highlight: null,
|
|
3402
|
+
maxNesting: 20
|
|
3403
|
+
},
|
|
3404
|
+
components: {
|
|
3405
|
+
core: { rules: [
|
|
3406
|
+
"normalize",
|
|
3407
|
+
"block",
|
|
3408
|
+
"inline",
|
|
3409
|
+
"text_join"
|
|
3410
|
+
] },
|
|
3411
|
+
block: { rules: [
|
|
3412
|
+
"blockquote",
|
|
3413
|
+
"code",
|
|
3414
|
+
"fence",
|
|
3415
|
+
"heading",
|
|
3416
|
+
"hr",
|
|
3417
|
+
"html_block",
|
|
3418
|
+
"lheading",
|
|
3419
|
+
"list",
|
|
3420
|
+
"reference",
|
|
3421
|
+
"paragraph"
|
|
3422
|
+
] },
|
|
3423
|
+
inline: {
|
|
3424
|
+
rules: [
|
|
3425
|
+
"autolink",
|
|
3426
|
+
"backticks",
|
|
3427
|
+
"emphasis",
|
|
3428
|
+
"entity",
|
|
3429
|
+
"escape",
|
|
3430
|
+
"html_inline",
|
|
3431
|
+
"image",
|
|
3432
|
+
"link",
|
|
3433
|
+
"newline",
|
|
3434
|
+
"text"
|
|
3435
|
+
],
|
|
3436
|
+
rules2: [
|
|
3437
|
+
"balance_pairs",
|
|
3438
|
+
"emphasis",
|
|
3439
|
+
"fragments_join"
|
|
3440
|
+
]
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
};
|
|
3444
|
+
var commonmark_default = commonmarkPreset;
|
|
3445
|
+
|
|
3446
|
+
//#endregion
|
|
3447
|
+
//#region src/presets/default.ts
|
|
3448
|
+
const defaultPreset = {
|
|
3449
|
+
options: {
|
|
3450
|
+
...defaultOptions,
|
|
3451
|
+
xhtmlOut: false,
|
|
3452
|
+
breaks: false,
|
|
3453
|
+
langPrefix: "language-",
|
|
3454
|
+
highlight: null
|
|
3455
|
+
},
|
|
3456
|
+
components: {
|
|
3457
|
+
core: {},
|
|
3458
|
+
block: {},
|
|
3459
|
+
inline: {}
|
|
3460
|
+
}
|
|
3461
|
+
};
|
|
3462
|
+
var default_default = defaultPreset;
|
|
3463
|
+
|
|
3464
|
+
//#endregion
|
|
3465
|
+
//#region src/presets/zero.ts
|
|
3466
|
+
const zeroPreset = {
|
|
3467
|
+
options: {
|
|
3468
|
+
html: false,
|
|
3469
|
+
xhtmlOut: false,
|
|
3470
|
+
breaks: false,
|
|
3471
|
+
langPrefix: "language-",
|
|
3472
|
+
linkify: false,
|
|
3473
|
+
typographer: false,
|
|
3474
|
+
quotes: "“”‘’",
|
|
3475
|
+
highlight: null,
|
|
3476
|
+
maxNesting: 20
|
|
3477
|
+
},
|
|
3478
|
+
components: {
|
|
3479
|
+
core: { rules: [
|
|
3480
|
+
"normalize",
|
|
3481
|
+
"block",
|
|
3482
|
+
"inline",
|
|
3483
|
+
"text_join"
|
|
3484
|
+
] },
|
|
3485
|
+
block: { rules: ["paragraph"] },
|
|
3486
|
+
inline: {
|
|
3487
|
+
rules: ["text"],
|
|
3488
|
+
rules2: ["balance_pairs", "fragments_join"]
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
};
|
|
3492
|
+
var zero_default = zeroPreset;
|
|
3493
|
+
|
|
3494
|
+
//#endregion
|
|
3495
|
+
//#region src/renderer.ts
|
|
3496
|
+
const default_rules = {};
|
|
3497
|
+
default_rules.code_inline = function(tokens, idx, options, env, slf) {
|
|
3498
|
+
const token = tokens[idx];
|
|
3499
|
+
return `<code${slf.renderAttrs(token)}>${escapeHtml(token.content)}</code>`;
|
|
3500
|
+
};
|
|
3501
|
+
default_rules.code_block = function(tokens, idx, options, env, slf) {
|
|
3502
|
+
const token = tokens[idx];
|
|
3503
|
+
return `<pre${slf.renderAttrs(token)}><code>${escapeHtml(tokens[idx].content)}</code></pre>\n`;
|
|
3504
|
+
};
|
|
3505
|
+
default_rules.fence = function(tokens, idx, options, env, slf) {
|
|
3506
|
+
const token = tokens[idx];
|
|
3507
|
+
const info = token.info ? unescapeAll(token.info).trim() : "";
|
|
3508
|
+
let langName = "";
|
|
3509
|
+
let langAttrs = "";
|
|
3510
|
+
if (info) {
|
|
3511
|
+
const arr = info.split(/(\s+)/g);
|
|
3512
|
+
langName = arr[0];
|
|
3513
|
+
langAttrs = arr.slice(2).join("");
|
|
3514
|
+
}
|
|
3515
|
+
function finalize(highlighted$1) {
|
|
3516
|
+
if (highlighted$1.indexOf("<pre") === 0) return `${highlighted$1}\n`;
|
|
3517
|
+
if (info) {
|
|
3518
|
+
const i = token.attrIndex("class");
|
|
3519
|
+
const tmpAttrs = token.attrs ? token.attrs.slice() : [];
|
|
3520
|
+
if (i < 0) tmpAttrs.push(["class", options.langPrefix + langName]);
|
|
3521
|
+
else {
|
|
3522
|
+
tmpAttrs[i] = tmpAttrs[i].slice();
|
|
3523
|
+
tmpAttrs[i][1] += ` ${options.langPrefix}${langName}`;
|
|
3524
|
+
}
|
|
3525
|
+
const tmpToken = { attrs: tmpAttrs };
|
|
3526
|
+
return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted$1}</code></pre>\n`;
|
|
3527
|
+
}
|
|
3528
|
+
return `<pre><code${slf.renderAttrs(token)}>${highlighted$1}</code></pre>\n`;
|
|
3529
|
+
}
|
|
3530
|
+
const resolveHighlighted = () => {
|
|
3531
|
+
if (!options.highlight) return escapeHtml(token.content);
|
|
3532
|
+
const highlighted$1 = options.highlight(token.content, langName, langAttrs, env);
|
|
3533
|
+
if (isPromiseLike(highlighted$1)) return highlighted$1.then((v) => v || escapeHtml(token.content));
|
|
3534
|
+
return highlighted$1 || escapeHtml(token.content);
|
|
3535
|
+
};
|
|
3536
|
+
const highlighted = resolveHighlighted();
|
|
3537
|
+
return isPromiseLike(highlighted) ? highlighted.then(finalize) : finalize(highlighted);
|
|
3538
|
+
};
|
|
3539
|
+
default_rules.image = function(tokens, idx, options, env, slf) {
|
|
3540
|
+
const token = tokens[idx];
|
|
3541
|
+
token.attrs[token.attrIndex("alt")][1] = slf.renderInlineAsText(token.children, options, env);
|
|
3542
|
+
return slf.renderToken(tokens, idx, options);
|
|
3543
|
+
};
|
|
3544
|
+
default_rules.hardbreak = function(tokens, idx, options) {
|
|
3545
|
+
return options.xhtmlOut ? "<br />\n" : "<br>\n";
|
|
3546
|
+
};
|
|
3547
|
+
default_rules.softbreak = function(tokens, idx, options) {
|
|
3548
|
+
return options.breaks ? options.xhtmlOut ? "<br />\n" : "<br>\n" : "\n";
|
|
3549
|
+
};
|
|
3550
|
+
default_rules.text = function(tokens, idx) {
|
|
3551
|
+
return escapeHtml(tokens[idx].content);
|
|
3552
|
+
};
|
|
3553
|
+
default_rules.html_block = function(tokens, idx) {
|
|
3554
|
+
return tokens[idx].content;
|
|
3555
|
+
};
|
|
3556
|
+
default_rules.html_inline = function(tokens, idx) {
|
|
3557
|
+
return tokens[idx].content;
|
|
3558
|
+
};
|
|
3559
|
+
default_rules.reference = function(tokens, idx) {
|
|
3560
|
+
return tokens[idx].content;
|
|
3561
|
+
};
|
|
3562
|
+
var Renderer = class Renderer {
|
|
3563
|
+
/**
|
|
3564
|
+
* Contains render rules for tokens. Can be updated and extended.
|
|
3565
|
+
*
|
|
3566
|
+
* ##### Example
|
|
3567
|
+
*
|
|
3568
|
+
* ```javascript
|
|
3569
|
+
* md.renderer.rules.strong_open = () => '<b>';
|
|
3570
|
+
* md.renderer.rules.strong_close = () => '</b>';
|
|
3571
|
+
*
|
|
3572
|
+
* var result = md.renderInline(...);
|
|
3573
|
+
* ```
|
|
3574
|
+
*
|
|
3575
|
+
* @see https://github.com/serkodev/markdown-exit/tree/main/packages/markdown-exit/src/renderer.ts
|
|
3576
|
+
*/
|
|
3577
|
+
rules = assign({}, default_rules);
|
|
3578
|
+
/**
|
|
3579
|
+
* Creates new {@link Renderer} instance and fill {@link Renderer#rules} with defaults.
|
|
3580
|
+
*/
|
|
3581
|
+
constructor() {}
|
|
3582
|
+
/**
|
|
3583
|
+
* Render token attributes to string.
|
|
3584
|
+
*/
|
|
3585
|
+
renderAttrs(token) {
|
|
3586
|
+
const attrs = token.attrs;
|
|
3587
|
+
if (!attrs) return "";
|
|
3588
|
+
const len = attrs.length;
|
|
3589
|
+
if (len === 0) return "";
|
|
3590
|
+
let result = "";
|
|
3591
|
+
for (let i = 0; i < len; i++) result += ` ${escapeHtml(attrs[i][0])}="${escapeHtml(attrs[i][1])}"`;
|
|
3592
|
+
return result;
|
|
3593
|
+
}
|
|
3594
|
+
/**
|
|
3595
|
+
* Default token renderer. Can be overriden by custom function
|
|
3596
|
+
* in {@link Renderer#rules}.
|
|
3597
|
+
*
|
|
3598
|
+
* @param tokens list of tokens
|
|
3599
|
+
* @param idx token index to render
|
|
3600
|
+
* @param options params of parser instance
|
|
3601
|
+
* @param env additional data from parsed input (references, for example)
|
|
3602
|
+
*/
|
|
3603
|
+
renderToken(tokens, idx, options, env = {}) {
|
|
3604
|
+
const token = tokens[idx];
|
|
3605
|
+
let result = "";
|
|
3606
|
+
if (token.hidden) return "";
|
|
3607
|
+
if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) result += "\n";
|
|
3608
|
+
result += (token.nesting === -1 ? "</" : "<") + token.tag;
|
|
3609
|
+
result += this.renderAttrs(token);
|
|
3610
|
+
if (token.nesting === 0 && options.xhtmlOut) result += " /";
|
|
3611
|
+
let needLf = false;
|
|
3612
|
+
if (token.block) {
|
|
3613
|
+
needLf = true;
|
|
3614
|
+
if (token.nesting === 1) {
|
|
3615
|
+
if (idx + 1 < tokens.length) {
|
|
3616
|
+
const nextToken = tokens[idx + 1];
|
|
3617
|
+
if (nextToken.type === "inline" || nextToken.type === "reference" || nextToken.hidden) needLf = false;
|
|
3618
|
+
else if (nextToken.nesting === -1 && nextToken.tag === token.tag) needLf = false;
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
result += needLf ? ">\n" : ">";
|
|
3623
|
+
return result;
|
|
3624
|
+
}
|
|
3625
|
+
/**
|
|
3626
|
+
* The same as {@link Renderer.render}, but for single token of `inline` type.
|
|
3627
|
+
*
|
|
3628
|
+
* @param tokens list of block tokens to render
|
|
3629
|
+
* @param options params of parser instance
|
|
3630
|
+
* @param env additional data from parsed input (references, for example)
|
|
3631
|
+
*/
|
|
3632
|
+
renderInline(tokens, options, env = {}) {
|
|
3633
|
+
let result = "";
|
|
3634
|
+
const rules = this.rules;
|
|
3635
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
3636
|
+
const rule = rules[tokens[i].type];
|
|
3637
|
+
if (rule) {
|
|
3638
|
+
const _result = rule(tokens, i, options, env, this);
|
|
3639
|
+
if (isPromiseLike(_result)) throw new Error("Renderer.renderInline: async rule detected, use renderInlineAsync()");
|
|
3640
|
+
result += _result;
|
|
3641
|
+
} else result += this.renderToken(tokens, i, options, env);
|
|
3642
|
+
}
|
|
3643
|
+
return result;
|
|
3644
|
+
}
|
|
3645
|
+
/**
|
|
3646
|
+
* Special kludge for image `alt` attributes to conform CommonMark spec.
|
|
3647
|
+
* Don't try to use it! Spec requires to show `alt` content with stripped markup,
|
|
3648
|
+
* instead of simple escaping.
|
|
3649
|
+
*
|
|
3650
|
+
* @param tokens list of block tokens to render
|
|
3651
|
+
* @param options params of parser instance
|
|
3652
|
+
* @param env additional data from parsed input (references, for example)
|
|
3653
|
+
*/
|
|
3654
|
+
renderInlineAsText(tokens, options, env = {}) {
|
|
3655
|
+
let result = "";
|
|
3656
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
3657
|
+
const token = tokens[i];
|
|
3658
|
+
switch (token.type) {
|
|
3659
|
+
case "text":
|
|
3660
|
+
result += token.content;
|
|
3661
|
+
break;
|
|
3662
|
+
case "image":
|
|
3663
|
+
result += this.renderInlineAsText(token.children, options, env);
|
|
3664
|
+
break;
|
|
3665
|
+
case "html_inline":
|
|
3666
|
+
case "html_block":
|
|
3667
|
+
result += token.content;
|
|
3668
|
+
break;
|
|
3669
|
+
case "softbreak":
|
|
3670
|
+
case "hardbreak":
|
|
3671
|
+
result += "\n";
|
|
3672
|
+
break;
|
|
3673
|
+
default:
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
return result;
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3679
|
+
* Takes token stream and generates HTML. Probably, you will never need to call
|
|
3680
|
+
* this method directly.
|
|
3681
|
+
*
|
|
3682
|
+
* @param tokens list of block tokens to render
|
|
3683
|
+
* @param options params of parser instance
|
|
3684
|
+
* @param env additional data from parsed input (references, for example)
|
|
3685
|
+
*/
|
|
3686
|
+
render(tokens, options, env = {}) {
|
|
3687
|
+
let result = "";
|
|
3688
|
+
const rules = this.rules;
|
|
3689
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
3690
|
+
const type = tokens[i].type;
|
|
3691
|
+
if (type === "inline") result += this.renderInline(tokens[i].children, options, env);
|
|
3692
|
+
else {
|
|
3693
|
+
const rule = rules[type];
|
|
3694
|
+
if (rule) {
|
|
3695
|
+
const _result = rule(tokens, i, options, env, this);
|
|
3696
|
+
if (isPromiseLike(_result)) throw new Error("Renderer.render: async rule detected, use renderAsync()");
|
|
3697
|
+
result += _result;
|
|
3698
|
+
} else result += this.renderToken(tokens, i, options, env);
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
return result;
|
|
3702
|
+
}
|
|
3703
|
+
/**
|
|
3704
|
+
* Async version of {@link Renderer.renderInline}. Runs all render rules in parallel
|
|
3705
|
+
* (Promise.all) and preserves output order.
|
|
3706
|
+
*/
|
|
3707
|
+
async renderInlineAsync(tokens, options, env) {
|
|
3708
|
+
const renderInline = this.renderInline;
|
|
3709
|
+
if (renderInline !== Renderer.prototype.renderInline && this.renderInlineAsync === Renderer.prototype.renderInlineAsync) return renderInline.call(this, tokens, options, env);
|
|
3710
|
+
const tasks = [];
|
|
3711
|
+
const rules = this.rules;
|
|
3712
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
3713
|
+
const rule = rules[tokens[i].type];
|
|
3714
|
+
if (rule) tasks.push(Promise.resolve(rule(tokens, i, options, env, this)));
|
|
3715
|
+
else tasks.push(Promise.resolve(this.renderToken(tokens, i, options, env)));
|
|
3716
|
+
}
|
|
3717
|
+
return (await Promise.all(tasks)).join("");
|
|
3718
|
+
}
|
|
3719
|
+
/**
|
|
3720
|
+
* Async version of {@link Renderer.render}. Runs all render rules in parallel
|
|
3721
|
+
* (Promise.all) and preserves output order.
|
|
3722
|
+
*
|
|
3723
|
+
* If `render` has been overridden or monkey-patched on this instance — a
|
|
3724
|
+
* common plugin pattern in the markdown-it ecosystem (e.g. @mdit-vue) — the
|
|
3725
|
+
* wrapper is honored by falling back to the sync path, so patched logic is
|
|
3726
|
+
* not silently bypassed. Async rules still throw there, as with `render()`.
|
|
3727
|
+
* If `renderAsync` itself is patched too, that wrapper owns the async path:
|
|
3728
|
+
* this base implementation then renders asynchronously right away and does
|
|
3729
|
+
* not route back through the patched sync `render` (#35).
|
|
3730
|
+
*/
|
|
3731
|
+
async renderAsync(tokens, options, env) {
|
|
3732
|
+
const render = this.render;
|
|
3733
|
+
if (render !== Renderer.prototype.render && this.renderAsync === Renderer.prototype.renderAsync) return render.call(this, tokens, options, env);
|
|
3734
|
+
const tasks = [];
|
|
3735
|
+
const rules = this.rules;
|
|
3736
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
3737
|
+
const tok = tokens[i];
|
|
3738
|
+
const type = tok.type;
|
|
3739
|
+
if (type === "inline") tasks.push(this.renderInlineAsync(tok.children, options, env));
|
|
3740
|
+
else {
|
|
3741
|
+
const rule = rules[type];
|
|
3742
|
+
if (rule) tasks.push(Promise.resolve(rule(tokens, i, options, env, this)));
|
|
3743
|
+
else tasks.push(Promise.resolve(this.renderToken(tokens, i, options, env)));
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
return (await Promise.all(tasks)).join("");
|
|
3747
|
+
}
|
|
3748
|
+
};
|
|
3749
|
+
|
|
3750
|
+
//#endregion
|
|
3751
|
+
//#region src/core.ts
|
|
3752
|
+
const config = {
|
|
3753
|
+
default: default_default,
|
|
3754
|
+
zero: zero_default,
|
|
3755
|
+
commonmark: commonmark_default
|
|
3756
|
+
};
|
|
3757
|
+
var MarkdownExit = class extends Parser {
|
|
3758
|
+
/**
|
|
3759
|
+
* Instance of {@link Renderer}. Use it to modify output look. Or to add rendering
|
|
3760
|
+
* rules for new token types, generated by plugins.
|
|
3761
|
+
*
|
|
3762
|
+
* ##### Example
|
|
3763
|
+
*
|
|
3764
|
+
* ```javascript
|
|
3765
|
+
* function myToken(tokens, idx, options, env, self) {
|
|
3766
|
+
* //...
|
|
3767
|
+
* return result;
|
|
3768
|
+
* };
|
|
3769
|
+
*
|
|
3770
|
+
* md.renderer.rules['my_token'] = myToken
|
|
3771
|
+
* ```
|
|
3772
|
+
*
|
|
3773
|
+
* See {@link Renderer} docs and [source code](https://github.com/serkodev/markdown-exit/tree/main/packages/markdown-exit/src/renderer.ts).
|
|
3774
|
+
*/
|
|
3775
|
+
renderer = new Renderer();
|
|
3776
|
+
/**
|
|
3777
|
+
* Assorted utility functions, useful to write plugins. See details
|
|
3778
|
+
* [here](https://github.com/serkodev/markdown-exit/tree/main/packages/markdown-exit/src/common/utils.ts).
|
|
3779
|
+
*/
|
|
3780
|
+
utils = utils_exports;
|
|
3781
|
+
options = { ...config.default.options };
|
|
3782
|
+
constructor(presetNameOrOptions, options) {
|
|
3783
|
+
super();
|
|
3784
|
+
const [presetName, opts] = typeof presetNameOrOptions === "string" ? [presetNameOrOptions, options] : ["default", presetNameOrOptions];
|
|
3785
|
+
this.configure(presetName);
|
|
3786
|
+
if (opts) this.set(opts);
|
|
3787
|
+
}
|
|
3788
|
+
/**
|
|
3789
|
+
* chainable*
|
|
3790
|
+
*
|
|
3791
|
+
* Set parser options (in the same format as in constructor). Probably, you
|
|
3792
|
+
* will never need it, but you can change options after constructor call.
|
|
3793
|
+
*
|
|
3794
|
+
* ##### Example
|
|
3795
|
+
*
|
|
3796
|
+
* ```javascript
|
|
3797
|
+
* md.set({ html: true, breaks: true })
|
|
3798
|
+
* .set({ typographer: true });
|
|
3799
|
+
* ```
|
|
3800
|
+
*
|
|
3801
|
+
* __Note:__ To achieve the best possible performance, don't modify a
|
|
3802
|
+
* `markdown-exit` instance options on the fly. If you need multiple configurations
|
|
3803
|
+
* it's best to create multiple instances and initialize each with separate
|
|
3804
|
+
* config.
|
|
3805
|
+
*/
|
|
3806
|
+
set(options) {
|
|
3807
|
+
assign(this.options, options);
|
|
3808
|
+
return this;
|
|
3809
|
+
}
|
|
3810
|
+
/**
|
|
3811
|
+
* chainable*, *internal*
|
|
3812
|
+
*
|
|
3813
|
+
* Batch load of all options and compenent settings. This is internal method,
|
|
3814
|
+
* and you probably will not need it. But if you with - see available presets
|
|
3815
|
+
* and data structure [here](https://github.com/serkodev/markdown-exit/tree/main/packages/markdown-exit/src/presets)
|
|
3816
|
+
*
|
|
3817
|
+
* We strongly recommend to use presets instead of direct config loads. That
|
|
3818
|
+
* will give better compatibility with next versions.
|
|
3819
|
+
*/
|
|
3820
|
+
configure(presets) {
|
|
3821
|
+
if (typeof presets === "string") {
|
|
3822
|
+
const presetName = presets;
|
|
3823
|
+
presets = config[presetName];
|
|
3824
|
+
if (!presets) throw new Error(`Wrong \`markdown-exit\` preset "${presetName}", check name`);
|
|
3825
|
+
}
|
|
3826
|
+
if (!presets) throw new Error("Wrong `markdown-exit` preset, can't be empty");
|
|
3827
|
+
if (presets.options) this.set(presets.options);
|
|
3828
|
+
if (presets.components) for (const name of Object.keys(presets.components)) {
|
|
3829
|
+
const component = presets.components[name];
|
|
3830
|
+
if (component.rules) this[name].ruler.enableOnly(component.rules);
|
|
3831
|
+
if (component.rules2) this[name].ruler2?.enableOnly(component.rules2);
|
|
3832
|
+
}
|
|
3833
|
+
return this;
|
|
3834
|
+
}
|
|
3835
|
+
/**
|
|
3836
|
+
* chainable*
|
|
3837
|
+
*
|
|
3838
|
+
* Enable list or rules. It will automatically find appropriate components,
|
|
3839
|
+
* containing rules with given names. If rule not found, and `ignoreInvalid`
|
|
3840
|
+
* not set - throws exception.
|
|
3841
|
+
*
|
|
3842
|
+
* ##### Example
|
|
3843
|
+
*
|
|
3844
|
+
* ```javascript
|
|
3845
|
+
* md.enable(['sub', 'sup'])
|
|
3846
|
+
* .disable('smartquotes');
|
|
3847
|
+
* ```
|
|
3848
|
+
*
|
|
3849
|
+
* @param list rule name or list of rule names to enable
|
|
3850
|
+
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
|
3851
|
+
*/
|
|
3852
|
+
enable(list$1, ignoreInvalid) {
|
|
3853
|
+
let result = [];
|
|
3854
|
+
if (!Array.isArray(list$1)) list$1 = [list$1];
|
|
3855
|
+
for (const chain of [
|
|
3856
|
+
"core",
|
|
3857
|
+
"block",
|
|
3858
|
+
"inline"
|
|
3859
|
+
]) result = result.concat(this[chain].ruler.enable(list$1, true));
|
|
3860
|
+
result = result.concat(this.inline.ruler2.enable(list$1, true));
|
|
3861
|
+
const missed = list$1.filter((name) => !result.includes(name));
|
|
3862
|
+
if (missed.length && !ignoreInvalid) throw new Error(`MarkdownExit. Failed to enable unknown rule(s): ${missed}`);
|
|
3863
|
+
return this;
|
|
3864
|
+
}
|
|
3865
|
+
/**
|
|
3866
|
+
* chainable*
|
|
3867
|
+
*
|
|
3868
|
+
* The same as {@link MarkdownExit.enable}, but turn specified rules off.
|
|
3869
|
+
*
|
|
3870
|
+
* @param list rule name or list of rule names to disable.
|
|
3871
|
+
* @param ignoreInvalid set `true` to ignore errors when rule not found.
|
|
3872
|
+
*/
|
|
3873
|
+
disable(list$1, ignoreInvalid) {
|
|
3874
|
+
let result = [];
|
|
3875
|
+
if (!Array.isArray(list$1)) list$1 = [list$1];
|
|
3876
|
+
for (const chain of [
|
|
3877
|
+
"core",
|
|
3878
|
+
"block",
|
|
3879
|
+
"inline"
|
|
3880
|
+
]) result = result.concat(this[chain].ruler.disable(list$1, true));
|
|
3881
|
+
result = result.concat(this.inline.ruler2.disable(list$1, true));
|
|
3882
|
+
const missed = list$1.filter((name) => !result.includes(name));
|
|
3883
|
+
if (missed.length && !ignoreInvalid) throw new Error(`MarkdownExit. Failed to disable unknown rule(s): ${missed}`);
|
|
3884
|
+
return this;
|
|
3885
|
+
}
|
|
3886
|
+
use(plugin, ...params) {
|
|
3887
|
+
plugin.apply(plugin, [this, ...params]);
|
|
3888
|
+
return this;
|
|
3889
|
+
}
|
|
3890
|
+
/**
|
|
3891
|
+
* Render markdown string into html. It does all magic for you :).
|
|
3892
|
+
*
|
|
3893
|
+
* `env` can be used to inject additional metadata (`{}` by default).
|
|
3894
|
+
* But you will not need it with high probability. See also comment
|
|
3895
|
+
* in {@link MarkdownExit.parse}.
|
|
3896
|
+
*
|
|
3897
|
+
* @param src source string
|
|
3898
|
+
* @param env environment sandbox
|
|
3899
|
+
*/
|
|
3900
|
+
render(src, env = {}) {
|
|
3901
|
+
return this.renderer.render(this.parse(src, env), this.options, env);
|
|
3902
|
+
}
|
|
3903
|
+
/**
|
|
3904
|
+
* Async version of {@link MarkdownExit.render}. Runs all render rules in parallel
|
|
3905
|
+
* (Promise.all) and preserves output order.
|
|
3906
|
+
*/
|
|
3907
|
+
renderAsync(src, env = {}) {
|
|
3908
|
+
return this.renderer.renderAsync(this.parse(src, env), this.options, env);
|
|
3909
|
+
}
|
|
3910
|
+
/**
|
|
3911
|
+
* Similar to {@link MarkdownExit.render} but for single paragraph content. Result
|
|
3912
|
+
* will NOT be wrapped into `<p>` tags.
|
|
3913
|
+
*
|
|
3914
|
+
* @param src source string
|
|
3915
|
+
* @param env environment sandbox
|
|
3916
|
+
*/
|
|
3917
|
+
renderInline(src, env = {}) {
|
|
3918
|
+
return this.renderer.render(this.parseInline(src, env), this.options, env);
|
|
3919
|
+
}
|
|
3920
|
+
/**
|
|
3921
|
+
* Async version of {@link MarkdownExit.renderInline}. Runs all render rules in parallel
|
|
3922
|
+
* (Promise.all) and preserves output order.
|
|
3923
|
+
*/
|
|
3924
|
+
renderInlineAsync(src, env = {}) {
|
|
3925
|
+
return this.renderer.renderAsync(this.parseInline(src, env), this.options, env);
|
|
3926
|
+
}
|
|
3927
|
+
};
|
|
3928
|
+
function createMarkdownExit(presetNameOrOptions, options) {
|
|
3929
|
+
return new MarkdownExit(presetNameOrOptions, options);
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
//#endregion
|
|
3933
|
+
//#region src/index.ts
|
|
3934
|
+
/**
|
|
3935
|
+
* Make class callable without `new` operator.
|
|
3936
|
+
*/
|
|
3937
|
+
function createCallableClass(Class) {
|
|
3938
|
+
function callable(...args) {
|
|
3939
|
+
return new Class(...args);
|
|
3940
|
+
}
|
|
3941
|
+
Object.setPrototypeOf(callable, MarkdownExit);
|
|
3942
|
+
callable.prototype = MarkdownExit.prototype;
|
|
3943
|
+
callable.prototype.constructor = callable;
|
|
3944
|
+
return callable;
|
|
3945
|
+
}
|
|
3946
|
+
const MarkdownExitConstructor = createCallableClass(MarkdownExit);
|
|
3947
|
+
var src_default = MarkdownExitConstructor;
|
|
3948
|
+
|
|
3949
|
+
//#endregion
|
|
3950
|
+
export { MarkdownExit, Parser, Renderer, Ruler, StateBlock, StateCore, StateInline, Token, createMarkdownExit, src_default as default, defaultOptions };
|