stream-markdown-parser 0.0.65 → 0.0.67
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/dist/index.d.ts.map +1 -1
- package/dist/index.js +595 -86
- package/dist/index.js.map +1 -1
- package/package.json +14 -16
package/dist/index.js
CHANGED
|
@@ -601,7 +601,7 @@ var require_markdown_it_task_checkbox = /* @__PURE__ */ __commonJS({ "../../node
|
|
|
601
601
|
}) });
|
|
602
602
|
|
|
603
603
|
//#endregion
|
|
604
|
-
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.
|
|
604
|
+
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.5/node_modules/markdown-it-ts/dist/chunk-Bp6m_JJh.js
|
|
605
605
|
var import_markdown_it_task_checkbox = /* @__PURE__ */ __toESM(require_markdown_it_task_checkbox(), 1);
|
|
606
606
|
var __defProp = Object.defineProperty;
|
|
607
607
|
var __export = (all) => {
|
|
@@ -2187,7 +2187,7 @@ var require_punycode = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pu
|
|
|
2187
2187
|
}) });
|
|
2188
2188
|
|
|
2189
2189
|
//#endregion
|
|
2190
|
-
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.
|
|
2190
|
+
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.5/node_modules/markdown-it-ts/dist/index.js
|
|
2191
2191
|
var import_punycode = /* @__PURE__ */ __toESM(require_punycode(), 1);
|
|
2192
2192
|
var utils_exports = /* @__PURE__ */ __export({
|
|
2193
2193
|
arrayReplaceAt: () => arrayReplaceAt,
|
|
@@ -2199,6 +2199,7 @@ var utils_exports = /* @__PURE__ */ __export({
|
|
|
2199
2199
|
has: () => has,
|
|
2200
2200
|
isMdAsciiPunct: () => isMdAsciiPunct,
|
|
2201
2201
|
isPunctChar: () => isPunctChar,
|
|
2202
|
+
isPunctCode: () => isPunctCode,
|
|
2202
2203
|
isSpace: () => isSpace$7,
|
|
2203
2204
|
isString: () => isString,
|
|
2204
2205
|
isValidEntityCode: () => isValidEntityCode$1,
|
|
@@ -2253,6 +2254,15 @@ function isWhiteSpace(code$1) {
|
|
|
2253
2254
|
function isPunctChar(ch) {
|
|
2254
2255
|
return regex_default$3.test(ch) || regex_default$5.test(ch);
|
|
2255
2256
|
}
|
|
2257
|
+
const PUNCT_CHAR_CACHE = /* @__PURE__ */ new Map();
|
|
2258
|
+
function isPunctCode(ch) {
|
|
2259
|
+
if (isMdAsciiPunct(ch)) return true;
|
|
2260
|
+
const cached = PUNCT_CHAR_CACHE.get(ch);
|
|
2261
|
+
if (cached !== void 0) return cached;
|
|
2262
|
+
const value = isPunctChar(String.fromCharCode(ch));
|
|
2263
|
+
PUNCT_CHAR_CACHE.set(ch, value);
|
|
2264
|
+
return value;
|
|
2265
|
+
}
|
|
2256
2266
|
function isMdAsciiPunct(ch) {
|
|
2257
2267
|
switch (ch) {
|
|
2258
2268
|
case 33:
|
|
@@ -2780,12 +2790,31 @@ function inline(state) {
|
|
|
2780
2790
|
}
|
|
2781
2791
|
}
|
|
2782
2792
|
}
|
|
2793
|
+
const CJK_CHAR_RE = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
|
|
2794
|
+
const ASCII_DOMAIN_START_RE = /[0-9a-z]/i;
|
|
2783
2795
|
function isLinkOpen$1(str) {
|
|
2784
2796
|
return /^<a[>\s]/i.test(str);
|
|
2785
2797
|
}
|
|
2786
2798
|
function isLinkClose$1(str) {
|
|
2787
2799
|
return /^<\/a\s*>/i.test(str);
|
|
2788
2800
|
}
|
|
2801
|
+
function trimCjkPrefixFromFuzzyLink(linkify$2, link$1) {
|
|
2802
|
+
if (link$1.schema || link$1.index !== 0 || !link$1.raw) return link$1;
|
|
2803
|
+
for (let offset = 1; offset < link$1.raw.length; offset++) {
|
|
2804
|
+
const prevChar = link$1.raw[offset - 1];
|
|
2805
|
+
const nextChar = link$1.raw[offset];
|
|
2806
|
+
if (!CJK_CHAR_RE.test(prevChar) || !ASCII_DOMAIN_START_RE.test(nextChar)) continue;
|
|
2807
|
+
const suffix = link$1.raw.slice(offset);
|
|
2808
|
+
const candidate = linkify$2.match(suffix)?.[0];
|
|
2809
|
+
if (!candidate || candidate.index !== 0 || candidate.lastIndex !== suffix.length) continue;
|
|
2810
|
+
return {
|
|
2811
|
+
...candidate,
|
|
2812
|
+
index: link$1.index + offset,
|
|
2813
|
+
lastIndex: link$1.index + offset + candidate.lastIndex
|
|
2814
|
+
};
|
|
2815
|
+
}
|
|
2816
|
+
return link$1;
|
|
2817
|
+
}
|
|
2789
2818
|
function linkify(state) {
|
|
2790
2819
|
const blockTokens = state.tokens;
|
|
2791
2820
|
if (!state.md?.options?.linkify) return;
|
|
@@ -2812,7 +2841,7 @@ function linkify(state) {
|
|
|
2812
2841
|
if (htmlLinkLevel > 0) continue;
|
|
2813
2842
|
if (currentToken.type !== "text" || !state.md.linkify.test(currentToken.content)) continue;
|
|
2814
2843
|
const text$1 = currentToken.content;
|
|
2815
|
-
let links = state.md.linkify.match(text$1) || [];
|
|
2844
|
+
let links = (state.md.linkify.match(text$1) || []).map((link$1) => trimCjkPrefixFromFuzzyLink(state.md.linkify, link$1));
|
|
2816
2845
|
if (links.length === 0) continue;
|
|
2817
2846
|
const nodes = [];
|
|
2818
2847
|
let level = currentToken.level;
|
|
@@ -3121,26 +3150,23 @@ function smartquotes(state) {
|
|
|
3121
3150
|
}
|
|
3122
3151
|
}
|
|
3123
3152
|
function text_join(state) {
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
out.push(textToken$1);
|
|
3139
|
-
} else out.push(ch);
|
|
3140
|
-
}
|
|
3141
|
-
tk.children = out;
|
|
3153
|
+
const blockTokens = state.tokens || [];
|
|
3154
|
+
const length = blockTokens.length;
|
|
3155
|
+
for (let j = 0; j < length; j++) {
|
|
3156
|
+
const blockToken = blockTokens[j];
|
|
3157
|
+
if (blockToken.type !== "inline" || !Array.isArray(blockToken.children)) continue;
|
|
3158
|
+
const tokens = blockToken.children;
|
|
3159
|
+
const max = tokens.length;
|
|
3160
|
+
for (let curr$1 = 0; curr$1 < max; curr$1++) if (tokens[curr$1].type === "text_special") tokens[curr$1].type = "text";
|
|
3161
|
+
let last = 0;
|
|
3162
|
+
let curr = 0;
|
|
3163
|
+
for (; 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;
|
|
3164
|
+
else {
|
|
3165
|
+
if (curr !== last) tokens[last] = tokens[curr];
|
|
3166
|
+
last++;
|
|
3142
3167
|
}
|
|
3143
|
-
|
|
3168
|
+
if (curr !== last) tokens.length = last;
|
|
3169
|
+
}
|
|
3144
3170
|
}
|
|
3145
3171
|
function isSpace$6(code$1) {
|
|
3146
3172
|
switch (code$1) {
|
|
@@ -5271,7 +5297,6 @@ var StateInline = class {
|
|
|
5271
5297
|
token.content = this.pending;
|
|
5272
5298
|
token.level = this.pendingLevel;
|
|
5273
5299
|
this.tokens.push(token);
|
|
5274
|
-
this.tokens_meta.push(null);
|
|
5275
5300
|
this.pending = "";
|
|
5276
5301
|
return token;
|
|
5277
5302
|
}
|
|
@@ -5281,7 +5306,6 @@ var StateInline = class {
|
|
|
5281
5306
|
push(type, tag, nesting) {
|
|
5282
5307
|
if (this.pending) this.pushPending();
|
|
5283
5308
|
const token = new Token(type, tag, nesting);
|
|
5284
|
-
token.level = this.level;
|
|
5285
5309
|
let token_meta = null;
|
|
5286
5310
|
if (nesting < 0) {
|
|
5287
5311
|
this.level--;
|
|
@@ -5308,13 +5332,12 @@ var StateInline = class {
|
|
|
5308
5332
|
let pos = start;
|
|
5309
5333
|
while (pos < posMax && src.charCodeAt(pos) === marker) pos++;
|
|
5310
5334
|
const count = pos - start;
|
|
5311
|
-
if (count < 1) return null;
|
|
5312
5335
|
const lastChar = start > 0 ? src.charCodeAt(start - 1) : 32;
|
|
5313
5336
|
const nextChar = pos < posMax ? src.charCodeAt(pos) : 32;
|
|
5314
|
-
const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
|
|
5315
|
-
const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
|
|
5316
5337
|
const isLastWhiteSpace = isWhiteSpace(lastChar);
|
|
5317
5338
|
const isNextWhiteSpace = isWhiteSpace(nextChar);
|
|
5339
|
+
const isLastPunctChar = isPunctCode(lastChar);
|
|
5340
|
+
const isNextPunctChar = isPunctCode(nextChar);
|
|
5318
5341
|
const left_flanking = !isNextWhiteSpace && (!isNextPunctChar || isLastWhiteSpace || isLastPunctChar);
|
|
5319
5342
|
const right_flanking = !isLastWhiteSpace && (!isLastPunctChar || isNextWhiteSpace || isNextPunctChar);
|
|
5320
5343
|
return {
|
|
@@ -5506,8 +5529,7 @@ var ParserCore = class {
|
|
|
5506
5529
|
return new State(src, this.resolveParser(md), env);
|
|
5507
5530
|
}
|
|
5508
5531
|
process(state) {
|
|
5509
|
-
|
|
5510
|
-
const rules = this.cachedCoreRules;
|
|
5532
|
+
const rules = this.cachedCoreRules ?? (this.cachedCoreRules = this.ruler.getRules(""));
|
|
5511
5533
|
for (let i = 0; i < rules.length; i++) rules[i](state);
|
|
5512
5534
|
}
|
|
5513
5535
|
parse(src, env = {}, md) {
|
|
@@ -5617,21 +5639,64 @@ function ensureSyncResult(value, ruleName) {
|
|
|
5617
5639
|
return value;
|
|
5618
5640
|
}
|
|
5619
5641
|
const resolveResult = (value) => isPromiseLike(value) ? value : Promise.resolve(value);
|
|
5642
|
+
function parseFenceInfo(info) {
|
|
5643
|
+
if (!info) return {
|
|
5644
|
+
langName: "",
|
|
5645
|
+
langAttrs: ""
|
|
5646
|
+
};
|
|
5647
|
+
let markerEnd = 0;
|
|
5648
|
+
while (markerEnd < info.length) {
|
|
5649
|
+
const ch = info.charCodeAt(markerEnd);
|
|
5650
|
+
if (ch === 32 || ch === 9 || ch === 10) break;
|
|
5651
|
+
markerEnd++;
|
|
5652
|
+
}
|
|
5653
|
+
if (markerEnd >= info.length) return {
|
|
5654
|
+
langName: info,
|
|
5655
|
+
langAttrs: ""
|
|
5656
|
+
};
|
|
5657
|
+
let attrsStart = markerEnd;
|
|
5658
|
+
while (attrsStart < info.length) {
|
|
5659
|
+
const ch = info.charCodeAt(attrsStart);
|
|
5660
|
+
if (ch !== 32 && ch !== 9 && ch !== 10) break;
|
|
5661
|
+
attrsStart++;
|
|
5662
|
+
}
|
|
5663
|
+
return {
|
|
5664
|
+
langName: info.slice(0, markerEnd),
|
|
5665
|
+
langAttrs: attrsStart < info.length ? info.slice(attrsStart) : ""
|
|
5666
|
+
};
|
|
5667
|
+
}
|
|
5620
5668
|
function renderFence(token, highlighted, info, langName, options, self) {
|
|
5621
5669
|
if (highlighted.startsWith("<pre")) return `${highlighted}\n`;
|
|
5622
5670
|
if (info) {
|
|
5623
|
-
const classIndex =
|
|
5624
|
-
const tmpAttrs = token.attrs ? token.attrs.
|
|
5671
|
+
const classIndex = token.attrIndex("class");
|
|
5672
|
+
const tmpAttrs = token.attrs ? token.attrs.slice() : [];
|
|
5625
5673
|
const langClass = `${options.langPrefix || "language-"}${langName}`;
|
|
5626
5674
|
if (classIndex < 0) tmpAttrs.push(["class", langClass]);
|
|
5627
|
-
else tmpAttrs[classIndex][
|
|
5675
|
+
else tmpAttrs[classIndex] = tmpAttrs[classIndex].slice();
|
|
5676
|
+
if (classIndex >= 0) tmpAttrs[classIndex][1] += ` ${langClass}`;
|
|
5628
5677
|
const tmpToken = {
|
|
5629
5678
|
...token,
|
|
5630
5679
|
attrs: tmpAttrs
|
|
5631
5680
|
};
|
|
5632
|
-
return `<pre><code${self.renderAttrs(tmpToken)}>${highlighted}</code></pre>\n`;
|
|
5681
|
+
return `<pre><code${tmpAttrs.length > 0 ? self.renderAttrs(tmpToken) : ""}>${highlighted}</code></pre>\n`;
|
|
5633
5682
|
}
|
|
5634
|
-
return `<pre><code${self.renderAttrs(token)}>${highlighted}</code></pre>\n`;
|
|
5683
|
+
return `<pre><code${token.attrs && token.attrs.length > 0 ? self.renderAttrs(token) : ""}>${highlighted}</code></pre>\n`;
|
|
5684
|
+
}
|
|
5685
|
+
function renderCodeInlineToken(token, self) {
|
|
5686
|
+
return `<code${token.attrs && token.attrs.length > 0 ? self.renderAttrs(token) : ""}>${escapeHtml(token.content)}</code>`;
|
|
5687
|
+
}
|
|
5688
|
+
function renderCodeBlockToken(token, self) {
|
|
5689
|
+
return `<pre${token.attrs && token.attrs.length > 0 ? self.renderAttrs(token) : ""}><code>${escapeHtml(token.content)}</code></pre>\n`;
|
|
5690
|
+
}
|
|
5691
|
+
function renderFenceSyncToken(token, options, self) {
|
|
5692
|
+
const info = token.info ? unescapeAll(token.info).trim() : "";
|
|
5693
|
+
const { langName, langAttrs } = parseFenceInfo(info);
|
|
5694
|
+
const highlight = options.highlight;
|
|
5695
|
+
const fallback = escapeHtml(token.content);
|
|
5696
|
+
if (!highlight) return renderFence(token, fallback, info, langName, options, self);
|
|
5697
|
+
const highlighted = highlight(token.content, langName, langAttrs);
|
|
5698
|
+
if (isPromiseLike(highlighted)) throw new TypeError("Renderer rule \"fence\" returned a Promise. Use renderAsync() instead.");
|
|
5699
|
+
return renderFence(token, highlighted || fallback, info, langName, options, self);
|
|
5635
5700
|
}
|
|
5636
5701
|
const DEFAULT_RENDERER_OPTIONS = {
|
|
5637
5702
|
langPrefix: "language-",
|
|
@@ -5641,39 +5706,29 @@ const DEFAULT_RENDERER_OPTIONS = {
|
|
|
5641
5706
|
const hasOwn = Object.prototype.hasOwnProperty;
|
|
5642
5707
|
const defaultRules = {
|
|
5643
5708
|
code_inline(tokens, idx, _options, _env, self) {
|
|
5644
|
-
|
|
5645
|
-
return `<code${self.renderAttrs(token)}>${escapeHtml(token.content)}</code>`;
|
|
5709
|
+
return renderCodeInlineToken(tokens[idx], self);
|
|
5646
5710
|
},
|
|
5647
5711
|
code_block(tokens, idx, _options, _env, self) {
|
|
5648
|
-
|
|
5649
|
-
return `<pre${self.renderAttrs(token)}><code>${escapeHtml(token.content)}</code></pre>\n`;
|
|
5712
|
+
return renderCodeBlockToken(tokens[idx], self);
|
|
5650
5713
|
},
|
|
5651
5714
|
fence(tokens, idx, options, _env, self) {
|
|
5652
5715
|
const token = tokens[idx];
|
|
5653
5716
|
const info = token.info ? unescapeAll(token.info).trim() : "";
|
|
5654
|
-
|
|
5655
|
-
let langAttrs = "";
|
|
5656
|
-
if (info) {
|
|
5657
|
-
const parts = info.split(/(\s+)/g);
|
|
5658
|
-
langName = parts[0];
|
|
5659
|
-
langAttrs = parts.slice(2).join("");
|
|
5660
|
-
}
|
|
5717
|
+
const { langName, langAttrs } = parseFenceInfo(info);
|
|
5661
5718
|
const highlight = options.highlight;
|
|
5662
|
-
const fallback =
|
|
5663
|
-
if (!highlight) return renderFence(token, fallback
|
|
5719
|
+
const fallback = escapeHtml(token.content);
|
|
5720
|
+
if (!highlight) return renderFence(token, fallback, info, langName, options, self);
|
|
5664
5721
|
const highlighted = highlight(token.content, langName, langAttrs);
|
|
5665
|
-
if (isPromiseLike(highlighted)) return highlighted.then((res) => renderFence(token, res || fallback
|
|
5666
|
-
return renderFence(token, highlighted || fallback
|
|
5722
|
+
if (isPromiseLike(highlighted)) return highlighted.then((res) => renderFence(token, res || fallback, info, langName, options, self));
|
|
5723
|
+
return renderFence(token, highlighted || fallback, info, langName, options, self);
|
|
5667
5724
|
},
|
|
5668
5725
|
image(tokens, idx, options, env, self) {
|
|
5669
5726
|
const token = tokens[idx];
|
|
5670
5727
|
const altText = self.renderInlineAsText(token.children || [], options, env);
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
else token.attrs = [["alt", altText]];
|
|
5676
|
-
}
|
|
5728
|
+
const altIndex = token.attrIndex("alt");
|
|
5729
|
+
if (altIndex >= 0 && token.attrs) token.attrs[altIndex][1] = altText;
|
|
5730
|
+
else if (token.attrs) token.attrs.push(["alt", altText]);
|
|
5731
|
+
else token.attrs = [["alt", altText]];
|
|
5677
5732
|
return self.renderToken(tokens, idx, options);
|
|
5678
5733
|
},
|
|
5679
5734
|
hardbreak(_tokens, _idx, options) {
|
|
@@ -5717,36 +5772,65 @@ var Renderer = class {
|
|
|
5717
5772
|
const merged = this.mergeOptions(options);
|
|
5718
5773
|
const envRef = env ?? {};
|
|
5719
5774
|
const rules = this.rules;
|
|
5720
|
-
const
|
|
5775
|
+
const codeBlockRule = rules.code_block;
|
|
5776
|
+
const fenceRule = rules.fence;
|
|
5777
|
+
const htmlBlockRule = rules.html_block;
|
|
5778
|
+
let result = "";
|
|
5721
5779
|
for (let i = 0; i < tokens.length; i++) {
|
|
5722
5780
|
const token = tokens[i];
|
|
5723
5781
|
if (token.type === "inline") {
|
|
5724
|
-
|
|
5782
|
+
result += this.renderInlineTokens(token.children || [], merged, envRef);
|
|
5725
5783
|
continue;
|
|
5726
5784
|
}
|
|
5785
|
+
switch (token.type) {
|
|
5786
|
+
case "code_block":
|
|
5787
|
+
if (codeBlockRule === defaultRules.code_block) {
|
|
5788
|
+
result += renderCodeBlockToken(token, this);
|
|
5789
|
+
continue;
|
|
5790
|
+
}
|
|
5791
|
+
break;
|
|
5792
|
+
case "fence":
|
|
5793
|
+
if (fenceRule === defaultRules.fence) {
|
|
5794
|
+
result += renderFenceSyncToken(token, merged, this);
|
|
5795
|
+
continue;
|
|
5796
|
+
}
|
|
5797
|
+
break;
|
|
5798
|
+
case "html_block":
|
|
5799
|
+
if (htmlBlockRule === defaultRules.html_block) {
|
|
5800
|
+
result += token.content;
|
|
5801
|
+
continue;
|
|
5802
|
+
}
|
|
5803
|
+
break;
|
|
5804
|
+
default: break;
|
|
5805
|
+
}
|
|
5727
5806
|
const rule = rules[token.type];
|
|
5728
|
-
if (rule)
|
|
5729
|
-
|
|
5807
|
+
if (!rule) {
|
|
5808
|
+
result += this.renderToken(tokens, i, merged);
|
|
5809
|
+
continue;
|
|
5810
|
+
}
|
|
5811
|
+
const rendered = rule(tokens, i, merged, envRef, this);
|
|
5812
|
+
if (typeof rendered === "string") result += rendered;
|
|
5813
|
+
else result += ensureSyncResult(rendered, token.type);
|
|
5730
5814
|
}
|
|
5731
|
-
return
|
|
5815
|
+
return result;
|
|
5732
5816
|
}
|
|
5733
5817
|
async renderAsync(tokens, options, env) {
|
|
5734
5818
|
if (!Array.isArray(tokens)) throw new TypeError("render expects token array as first argument");
|
|
5735
5819
|
const merged = this.mergeOptions(options);
|
|
5736
5820
|
const envRef = env ?? {};
|
|
5737
5821
|
const rules = this.rules;
|
|
5738
|
-
|
|
5822
|
+
let result = "";
|
|
5739
5823
|
for (let i = 0; i < tokens.length; i++) {
|
|
5740
5824
|
const token = tokens[i];
|
|
5741
5825
|
if (token.type === "inline") {
|
|
5742
|
-
|
|
5826
|
+
result += await this.renderInlineTokensAsync(token.children || [], merged, envRef);
|
|
5743
5827
|
continue;
|
|
5744
5828
|
}
|
|
5745
5829
|
const rule = rules[token.type];
|
|
5746
|
-
if (rule)
|
|
5747
|
-
else
|
|
5830
|
+
if (rule) result += await resolveResult(rule(tokens, i, merged, envRef, this));
|
|
5831
|
+
else result += this.renderToken(tokens, i, merged);
|
|
5748
5832
|
}
|
|
5749
|
-
return
|
|
5833
|
+
return result;
|
|
5750
5834
|
}
|
|
5751
5835
|
renderInline(tokens, options, env) {
|
|
5752
5836
|
const merged = this.mergeOptions(options);
|
|
@@ -5778,7 +5862,7 @@ var Renderer = class {
|
|
|
5778
5862
|
let result = "";
|
|
5779
5863
|
if (token.block && token.nesting !== -1 && idx > 0 && tokens[idx - 1].hidden) result += "\n";
|
|
5780
5864
|
result += token.nesting === -1 ? `</${token.tag}` : `<${token.tag}`;
|
|
5781
|
-
result += this.renderAttrs(token);
|
|
5865
|
+
if (token.attrs && token.attrs.length > 0) result += this.renderAttrs(token);
|
|
5782
5866
|
if (token.nesting === 0 && options.xhtmlOut) result += " /";
|
|
5783
5867
|
let needLineFeed = false;
|
|
5784
5868
|
if (token.block) {
|
|
@@ -5824,25 +5908,77 @@ var Renderer = class {
|
|
|
5824
5908
|
renderInlineTokens(tokens, options, env) {
|
|
5825
5909
|
if (!tokens || tokens.length === 0) return "";
|
|
5826
5910
|
const rules = this.rules;
|
|
5827
|
-
const
|
|
5911
|
+
const textRule = rules.text;
|
|
5912
|
+
const textSpecialRule = rules.text_special;
|
|
5913
|
+
const softbreakRule = rules.softbreak;
|
|
5914
|
+
const hardbreakRule = rules.hardbreak;
|
|
5915
|
+
const htmlInlineRule = rules.html_inline;
|
|
5916
|
+
const codeInlineRule = rules.code_inline;
|
|
5917
|
+
const inlineBreak = options.xhtmlOut ? "<br />\n" : "<br>\n";
|
|
5918
|
+
const softbreak = options.breaks ? inlineBreak : "\n";
|
|
5919
|
+
let result = "";
|
|
5828
5920
|
for (let i = 0; i < tokens.length; i++) {
|
|
5829
5921
|
const token = tokens[i];
|
|
5922
|
+
switch (token.type) {
|
|
5923
|
+
case "text":
|
|
5924
|
+
if (textRule === defaultRules.text) {
|
|
5925
|
+
result += escapeHtml(token.content);
|
|
5926
|
+
continue;
|
|
5927
|
+
}
|
|
5928
|
+
break;
|
|
5929
|
+
case "text_special":
|
|
5930
|
+
if (textSpecialRule === defaultRules.text_special) {
|
|
5931
|
+
result += escapeHtml(token.content);
|
|
5932
|
+
continue;
|
|
5933
|
+
}
|
|
5934
|
+
break;
|
|
5935
|
+
case "softbreak":
|
|
5936
|
+
if (softbreakRule === defaultRules.softbreak) {
|
|
5937
|
+
result += softbreak;
|
|
5938
|
+
continue;
|
|
5939
|
+
}
|
|
5940
|
+
break;
|
|
5941
|
+
case "hardbreak":
|
|
5942
|
+
if (hardbreakRule === defaultRules.hardbreak) {
|
|
5943
|
+
result += inlineBreak;
|
|
5944
|
+
continue;
|
|
5945
|
+
}
|
|
5946
|
+
break;
|
|
5947
|
+
case "html_inline":
|
|
5948
|
+
if (htmlInlineRule === defaultRules.html_inline) {
|
|
5949
|
+
result += token.content;
|
|
5950
|
+
continue;
|
|
5951
|
+
}
|
|
5952
|
+
break;
|
|
5953
|
+
case "code_inline":
|
|
5954
|
+
if (codeInlineRule === defaultRules.code_inline) {
|
|
5955
|
+
result += renderCodeInlineToken(token, this);
|
|
5956
|
+
continue;
|
|
5957
|
+
}
|
|
5958
|
+
break;
|
|
5959
|
+
default: break;
|
|
5960
|
+
}
|
|
5830
5961
|
const rule = rules[token.type];
|
|
5831
|
-
if (rule)
|
|
5832
|
-
|
|
5962
|
+
if (!rule) {
|
|
5963
|
+
result += this.renderToken(tokens, i, options);
|
|
5964
|
+
continue;
|
|
5965
|
+
}
|
|
5966
|
+
const rendered = rule(tokens, i, options, env, this);
|
|
5967
|
+
if (typeof rendered === "string") result += rendered;
|
|
5968
|
+
else result += ensureSyncResult(rendered, token.type);
|
|
5833
5969
|
}
|
|
5834
|
-
return
|
|
5970
|
+
return result;
|
|
5835
5971
|
}
|
|
5836
5972
|
async renderInlineTokensAsync(tokens, options, env) {
|
|
5837
5973
|
if (!tokens || tokens.length === 0) return "";
|
|
5838
5974
|
const rules = this.rules;
|
|
5839
|
-
|
|
5975
|
+
let result = "";
|
|
5840
5976
|
for (let i = 0; i < tokens.length; i++) {
|
|
5841
5977
|
const rule = rules[tokens[i].type];
|
|
5842
|
-
if (rule)
|
|
5843
|
-
else
|
|
5978
|
+
if (rule) result += await resolveResult(rule(tokens, i, options, env, this));
|
|
5979
|
+
else result += this.renderToken(tokens, i, options);
|
|
5844
5980
|
}
|
|
5845
|
-
return
|
|
5981
|
+
return result;
|
|
5846
5982
|
}
|
|
5847
5983
|
renderInlineAsTextInternal(tokens, options, env) {
|
|
5848
5984
|
if (!tokens || tokens.length === 0) return "";
|
|
@@ -5999,6 +6135,7 @@ function makeEmptyStats() {
|
|
|
5999
6135
|
total: 0,
|
|
6000
6136
|
cacheHits: 0,
|
|
6001
6137
|
appendHits: 0,
|
|
6138
|
+
tailHits: 0,
|
|
6002
6139
|
fullParses: 0,
|
|
6003
6140
|
resets: 0,
|
|
6004
6141
|
chunkedParses: 0,
|
|
@@ -6014,6 +6151,10 @@ var StreamParser = class {
|
|
|
6014
6151
|
DEFAULT_SKIP_CACHE_LINES = 1e4;
|
|
6015
6152
|
MAX_CHUNKS_FOR_FALLBACK = 24;
|
|
6016
6153
|
MAX_CHUNKED_DOC_CHARS = 12e4;
|
|
6154
|
+
MIN_LIST_LINES_FOR_MERGE = 80;
|
|
6155
|
+
MIN_LIST_CHARS_FOR_MERGE = 800;
|
|
6156
|
+
MIN_TABLE_LINES_FOR_MERGE = 48;
|
|
6157
|
+
MIN_TABLE_CHARS_FOR_MERGE = 1200;
|
|
6017
6158
|
constructor(core) {
|
|
6018
6159
|
this.core = core;
|
|
6019
6160
|
}
|
|
@@ -6086,8 +6227,10 @@ var StreamParser = class {
|
|
|
6086
6227
|
src,
|
|
6087
6228
|
tokens: tokens$1,
|
|
6088
6229
|
env: workingEnv,
|
|
6089
|
-
lineCount: srcLineCount
|
|
6230
|
+
lineCount: srcLineCount,
|
|
6231
|
+
lastSegment: void 0
|
|
6090
6232
|
};
|
|
6233
|
+
this.updateCacheLineCount(this.cache, srcLineCount);
|
|
6091
6234
|
this.stats.total += 1;
|
|
6092
6235
|
this.stats.chunkedParses = (this.stats.chunkedParses || 0) + 1;
|
|
6093
6236
|
this.stats.lastMode = "chunked";
|
|
@@ -6099,8 +6242,10 @@ var StreamParser = class {
|
|
|
6099
6242
|
src,
|
|
6100
6243
|
tokens,
|
|
6101
6244
|
env: workingEnv,
|
|
6102
|
-
lineCount: srcLineCount
|
|
6245
|
+
lineCount: srcLineCount,
|
|
6246
|
+
lastSegment: void 0
|
|
6103
6247
|
};
|
|
6248
|
+
this.updateCacheLineCount(this.cache, srcLineCount);
|
|
6104
6249
|
this.stats.total += 1;
|
|
6105
6250
|
this.stats.fullParses += 1;
|
|
6106
6251
|
this.stats.lastMode = "full";
|
|
@@ -6116,19 +6261,22 @@ var StreamParser = class {
|
|
|
6116
6261
|
if (cached.src.length < threshold && src.length < threshold * 1.5 && !src.startsWith(cached.src)) {
|
|
6117
6262
|
const fallbackEnv$1 = envProvided ?? cached.env;
|
|
6118
6263
|
const nextTokens$1 = this.core.parse(src, fallbackEnv$1, md).tokens;
|
|
6264
|
+
const lineCount = countLines(src);
|
|
6119
6265
|
this.cache = {
|
|
6120
6266
|
src,
|
|
6121
6267
|
tokens: nextTokens$1,
|
|
6122
6268
|
env: fallbackEnv$1,
|
|
6123
|
-
lineCount
|
|
6269
|
+
lineCount,
|
|
6270
|
+
lastSegment: void 0
|
|
6124
6271
|
};
|
|
6272
|
+
this.updateCacheLineCount(this.cache, lineCount);
|
|
6125
6273
|
this.stats.total += 1;
|
|
6126
6274
|
this.stats.fullParses += 1;
|
|
6127
6275
|
this.stats.lastMode = "full";
|
|
6128
6276
|
return nextTokens$1;
|
|
6129
6277
|
}
|
|
6130
6278
|
const appended = this.getAppendedSegment(cached.src, src);
|
|
6131
|
-
if (appended) {
|
|
6279
|
+
if (appended && !this.shouldPreferTailReparseForAppend(cached)) {
|
|
6132
6280
|
const cachedLineCount = cached.lineCount ?? countLines(cached.src);
|
|
6133
6281
|
let ctxLines = 3;
|
|
6134
6282
|
if (appended.length > 5e3) ctxLines = 8;
|
|
@@ -6233,8 +6381,9 @@ var StreamParser = class {
|
|
|
6233
6381
|
if (appendedLineCount === null) appendedLineCount = countLines(appended);
|
|
6234
6382
|
return appendedLineCount;
|
|
6235
6383
|
};
|
|
6384
|
+
const canDirectParseAppend = this.canDirectlyParseAppend(cached);
|
|
6236
6385
|
let shouldAttemptContext = false;
|
|
6237
|
-
switch (ctxStrategy) {
|
|
6386
|
+
if (!canDirectParseAppend) switch (ctxStrategy) {
|
|
6238
6387
|
case "lines":
|
|
6239
6388
|
shouldAttemptContext = getAppendedLineCount() >= CONTEXT_PARSE_MIN_LINES;
|
|
6240
6389
|
break;
|
|
@@ -6287,6 +6436,7 @@ var StreamParser = class {
|
|
|
6287
6436
|
}
|
|
6288
6437
|
} catch {}
|
|
6289
6438
|
}
|
|
6439
|
+
const appendStart = cached.tokens.length;
|
|
6290
6440
|
if (appendedState.tokens.length > 0) {
|
|
6291
6441
|
const cachedTail = cached.tokens;
|
|
6292
6442
|
const a = appendedState.tokens;
|
|
@@ -6318,12 +6468,30 @@ var StreamParser = class {
|
|
|
6318
6468
|
}
|
|
6319
6469
|
cached.src = src;
|
|
6320
6470
|
cached.lineCount = cachedLineCount + (appendedLineCount ?? countLines(appended));
|
|
6471
|
+
if (cached.tokens.length > appendStart) {
|
|
6472
|
+
const appendedLastSegment = this.getLastSegment(cached.tokens.slice(appendStart), src);
|
|
6473
|
+
if (appendedLastSegment) cached.lastSegment = {
|
|
6474
|
+
tokenStart: appendStart + appendedLastSegment.tokenStart,
|
|
6475
|
+
tokenEnd: appendStart + appendedLastSegment.tokenEnd,
|
|
6476
|
+
lineStart: appendedLastSegment.lineStart,
|
|
6477
|
+
lineEnd: appendedLastSegment.lineEnd,
|
|
6478
|
+
srcOffset: appendedLastSegment.srcOffset
|
|
6479
|
+
};
|
|
6480
|
+
else cached.lastSegment = void 0;
|
|
6481
|
+
} else cached.lastSegment = void 0;
|
|
6321
6482
|
this.stats.total += 1;
|
|
6322
6483
|
this.stats.appendHits += 1;
|
|
6323
6484
|
this.stats.lastMode = "append";
|
|
6324
6485
|
return cached.tokens;
|
|
6325
6486
|
}
|
|
6326
6487
|
const fallbackEnv = envProvided ?? cached.env;
|
|
6488
|
+
const tailReparsed = this.tryTailSegmentReparse(src, cached, fallbackEnv, md);
|
|
6489
|
+
if (tailReparsed) {
|
|
6490
|
+
this.stats.total += 1;
|
|
6491
|
+
this.stats.tailHits += 1;
|
|
6492
|
+
this.stats.lastMode = "tail";
|
|
6493
|
+
return tailReparsed;
|
|
6494
|
+
}
|
|
6327
6495
|
const chunkedEnabled = !!md.options?.streamChunkedFallback;
|
|
6328
6496
|
const chunkAdaptive = md.options?.streamChunkAdaptive !== false;
|
|
6329
6497
|
const targetChunks = md.options?.streamChunkTargetChunks ?? 8;
|
|
@@ -6365,8 +6533,10 @@ var StreamParser = class {
|
|
|
6365
6533
|
src,
|
|
6366
6534
|
tokens,
|
|
6367
6535
|
env: fallbackEnv,
|
|
6368
|
-
lineCount: srcLineCount2
|
|
6536
|
+
lineCount: srcLineCount2,
|
|
6537
|
+
lastSegment: void 0
|
|
6369
6538
|
};
|
|
6539
|
+
this.updateCacheLineCount(this.cache, srcLineCount2);
|
|
6370
6540
|
this.stats.total += 1;
|
|
6371
6541
|
this.stats.chunkedParses = (this.stats.chunkedParses || 0) + 1;
|
|
6372
6542
|
this.stats.lastMode = "chunked";
|
|
@@ -6378,8 +6548,10 @@ var StreamParser = class {
|
|
|
6378
6548
|
src,
|
|
6379
6549
|
tokens: nextTokens,
|
|
6380
6550
|
env: fallbackEnv,
|
|
6381
|
-
lineCount: srcLineCount2
|
|
6551
|
+
lineCount: srcLineCount2,
|
|
6552
|
+
lastSegment: void 0
|
|
6382
6553
|
};
|
|
6554
|
+
this.updateCacheLineCount(this.cache, srcLineCount2);
|
|
6383
6555
|
this.stats.total += 1;
|
|
6384
6556
|
this.stats.fullParses += 1;
|
|
6385
6557
|
this.stats.lastMode = "full";
|
|
@@ -6408,8 +6580,46 @@ var StreamParser = class {
|
|
|
6408
6580
|
if (prevWithoutTrailingNewline.slice(lastBreak + 1).trim().length > 0) return null;
|
|
6409
6581
|
}
|
|
6410
6582
|
if (this.endsInsideOpenFence(prev)) return null;
|
|
6583
|
+
if (this.mayContainReferenceDefinition(segment)) return null;
|
|
6411
6584
|
return segment;
|
|
6412
6585
|
}
|
|
6586
|
+
tryTailSegmentReparse(src, cached, env, md) {
|
|
6587
|
+
const lastSegment = this.ensureLastSegment(cached);
|
|
6588
|
+
if (!lastSegment) return null;
|
|
6589
|
+
if (lastSegment.srcOffset <= 0 && lastSegment.tokenStart <= 0) return null;
|
|
6590
|
+
const stablePrefix = cached.src.slice(0, lastSegment.srcOffset);
|
|
6591
|
+
if (!src.startsWith(stablePrefix)) return null;
|
|
6592
|
+
const prevTail = cached.src.slice(lastSegment.srcOffset);
|
|
6593
|
+
const nextTail = src.slice(lastSegment.srcOffset);
|
|
6594
|
+
if (nextTail === prevTail) return null;
|
|
6595
|
+
const appended = src.startsWith(cached.src) ? src.slice(cached.src.length) : null;
|
|
6596
|
+
if (appended) {
|
|
6597
|
+
const merged = this.tryContainerTailAppendMerge(src, cached, env, md, lastSegment, appended);
|
|
6598
|
+
if (merged) return merged;
|
|
6599
|
+
}
|
|
6600
|
+
if (this.mayContainReferenceDefinition(prevTail) || this.mayContainReferenceDefinition(nextTail)) return null;
|
|
6601
|
+
try {
|
|
6602
|
+
const tailState = this.core.parse(nextTail, env, md);
|
|
6603
|
+
const localLastSegment = this.getLastSegment(tailState.tokens, nextTail);
|
|
6604
|
+
if (lastSegment.lineStart > 0) this.shiftTokenLines(tailState.tokens, lastSegment.lineStart);
|
|
6605
|
+
cached.src = src;
|
|
6606
|
+
cached.env = env;
|
|
6607
|
+
cached.tokens.length = lastSegment.tokenStart;
|
|
6608
|
+
cached.tokens.push(...tailState.tokens);
|
|
6609
|
+
cached.lineCount = countLines(src);
|
|
6610
|
+
if (localLastSegment) cached.lastSegment = {
|
|
6611
|
+
tokenStart: lastSegment.tokenStart + localLastSegment.tokenStart,
|
|
6612
|
+
tokenEnd: lastSegment.tokenStart + localLastSegment.tokenEnd,
|
|
6613
|
+
lineStart: lastSegment.lineStart + localLastSegment.lineStart,
|
|
6614
|
+
lineEnd: lastSegment.lineStart + localLastSegment.lineEnd,
|
|
6615
|
+
srcOffset: lastSegment.srcOffset + localLastSegment.srcOffset
|
|
6616
|
+
};
|
|
6617
|
+
else cached.lastSegment = null;
|
|
6618
|
+
return cached.tokens;
|
|
6619
|
+
} catch {
|
|
6620
|
+
return null;
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6413
6623
|
getTailLines(src, lineCount) {
|
|
6414
6624
|
if (lineCount <= 0) return "";
|
|
6415
6625
|
let remaining = lineCount;
|
|
@@ -6461,6 +6671,293 @@ var StreamParser = class {
|
|
|
6461
6671
|
getStats() {
|
|
6462
6672
|
return { ...this.stats };
|
|
6463
6673
|
}
|
|
6674
|
+
updateCacheLineCount(cache, lineCount) {
|
|
6675
|
+
cache.lineCount = lineCount ?? countLines(cache.src);
|
|
6676
|
+
cache.lastSegment = void 0;
|
|
6677
|
+
}
|
|
6678
|
+
ensureLastSegment(cache) {
|
|
6679
|
+
if (cache.lastSegment !== void 0) return cache.lastSegment;
|
|
6680
|
+
cache.lastSegment = this.getLastSegment(cache.tokens, cache.src);
|
|
6681
|
+
return cache.lastSegment;
|
|
6682
|
+
}
|
|
6683
|
+
getLastSegment(tokens, src) {
|
|
6684
|
+
if (tokens.length === 0) return null;
|
|
6685
|
+
let lineStart = Number.POSITIVE_INFINITY;
|
|
6686
|
+
let lineEnd = -1;
|
|
6687
|
+
let depth = 0;
|
|
6688
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
6689
|
+
const token = tokens[i];
|
|
6690
|
+
if (token.map) {
|
|
6691
|
+
if (token.map[0] < lineStart) lineStart = token.map[0];
|
|
6692
|
+
if (token.map[1] > lineEnd) lineEnd = token.map[1];
|
|
6693
|
+
}
|
|
6694
|
+
if (token.nesting < 0) {
|
|
6695
|
+
depth += -token.nesting;
|
|
6696
|
+
continue;
|
|
6697
|
+
}
|
|
6698
|
+
if (token.nesting > 0) {
|
|
6699
|
+
depth -= token.nesting;
|
|
6700
|
+
if (token.level === 0 && depth <= 0) {
|
|
6701
|
+
const resolvedStart = Number.isFinite(lineStart) ? lineStart : token.map?.[0] ?? 0;
|
|
6702
|
+
const resolvedEnd = lineEnd >= resolvedStart ? lineEnd : token.map?.[1] ?? resolvedStart;
|
|
6703
|
+
return {
|
|
6704
|
+
tokenStart: i,
|
|
6705
|
+
tokenEnd: tokens.length,
|
|
6706
|
+
lineStart: resolvedStart,
|
|
6707
|
+
lineEnd: resolvedEnd,
|
|
6708
|
+
srcOffset: this.getLineStartOffset(src, resolvedStart)
|
|
6709
|
+
};
|
|
6710
|
+
}
|
|
6711
|
+
continue;
|
|
6712
|
+
}
|
|
6713
|
+
if (token.level === 0 && depth === 0) {
|
|
6714
|
+
const resolvedStart = Number.isFinite(lineStart) ? lineStart : token.map?.[0] ?? 0;
|
|
6715
|
+
const resolvedEnd = lineEnd >= resolvedStart ? lineEnd : token.map?.[1] ?? resolvedStart;
|
|
6716
|
+
return {
|
|
6717
|
+
tokenStart: i,
|
|
6718
|
+
tokenEnd: tokens.length,
|
|
6719
|
+
lineStart: resolvedStart,
|
|
6720
|
+
lineEnd: resolvedEnd,
|
|
6721
|
+
srcOffset: this.getLineStartOffset(src, resolvedStart)
|
|
6722
|
+
};
|
|
6723
|
+
}
|
|
6724
|
+
}
|
|
6725
|
+
return null;
|
|
6726
|
+
}
|
|
6727
|
+
getLineStartOffset(src, line) {
|
|
6728
|
+
if (line <= 0) return 0;
|
|
6729
|
+
let remaining = line;
|
|
6730
|
+
let pos = -1;
|
|
6731
|
+
while (remaining > 0) {
|
|
6732
|
+
pos = src.indexOf("\n", pos + 1);
|
|
6733
|
+
if (pos === -1) return src.length;
|
|
6734
|
+
remaining--;
|
|
6735
|
+
}
|
|
6736
|
+
return pos + 1;
|
|
6737
|
+
}
|
|
6738
|
+
mayContainReferenceDefinition(src) {
|
|
6739
|
+
if (!src.includes("]:")) return false;
|
|
6740
|
+
return /(?:^|\n)[ \t]{0,3}\[[^\]\n]+\]:/.test(src);
|
|
6741
|
+
}
|
|
6742
|
+
canDirectlyParseAppend(cache) {
|
|
6743
|
+
if (!this.endsWithBlankLine(cache.src)) return false;
|
|
6744
|
+
const lastSegment = this.ensureLastSegment(cache);
|
|
6745
|
+
if (!lastSegment) return false;
|
|
6746
|
+
switch (cache.tokens[lastSegment.tokenStart]?.type) {
|
|
6747
|
+
case "paragraph_open":
|
|
6748
|
+
case "heading_open":
|
|
6749
|
+
case "fence":
|
|
6750
|
+
case "code_block":
|
|
6751
|
+
case "html_block":
|
|
6752
|
+
case "hr":
|
|
6753
|
+
case "table_open": return true;
|
|
6754
|
+
default: return false;
|
|
6755
|
+
}
|
|
6756
|
+
}
|
|
6757
|
+
tryContainerTailAppendMerge(src, cached, env, md, lastSegment, appended) {
|
|
6758
|
+
if (!appended || this.mayContainReferenceDefinition(appended)) return null;
|
|
6759
|
+
const lastToken = cached.tokens[lastSegment.tokenStart];
|
|
6760
|
+
switch (lastToken?.type) {
|
|
6761
|
+
case "bullet_list_open":
|
|
6762
|
+
case "ordered_list_open": return this.tryListTailAppendMerge(src, cached, env, md, lastSegment, appended, lastToken);
|
|
6763
|
+
case "table_open": return this.tryTableTailAppendMerge(src, cached, env, md, lastSegment, appended, lastToken);
|
|
6764
|
+
default: return null;
|
|
6765
|
+
}
|
|
6766
|
+
}
|
|
6767
|
+
tryListTailAppendMerge(src, cached, env, md, lastSegment, appended, listOpen) {
|
|
6768
|
+
if (cached.src.length === 0 || cached.src.charCodeAt(cached.src.length - 1) !== 10) return null;
|
|
6769
|
+
const segmentLineSpan = lastSegment.lineEnd - lastSegment.lineStart;
|
|
6770
|
+
const segmentChars = cached.src.length - lastSegment.srcOffset;
|
|
6771
|
+
if (segmentLineSpan < this.MIN_LIST_LINES_FOR_MERGE && segmentChars < this.MIN_LIST_CHARS_FOR_MERGE) return null;
|
|
6772
|
+
const closeType = listOpen.type === "bullet_list_open" ? "bullet_list_close" : "ordered_list_close";
|
|
6773
|
+
let parsed;
|
|
6774
|
+
try {
|
|
6775
|
+
parsed = this.core.parse(appended, env, md).tokens;
|
|
6776
|
+
} catch {
|
|
6777
|
+
return null;
|
|
6778
|
+
}
|
|
6779
|
+
if (!this.isSingleTopLevelContainer(parsed, listOpen.type, closeType, listOpen.markup)) return null;
|
|
6780
|
+
const inserted = parsed.slice(1, -1);
|
|
6781
|
+
if (inserted.length === 0) return null;
|
|
6782
|
+
const lineOffset = cached.lineCount ?? countLines(cached.src);
|
|
6783
|
+
if (lineOffset > 0) this.shiftTokenLines(inserted, lineOffset);
|
|
6784
|
+
const existingMode = this.getListParagraphMode(cached.tokens, lastSegment.tokenStart, cached.tokens.length, listOpen.level);
|
|
6785
|
+
const appendedMode = this.getListParagraphMode(parsed, 0, parsed.length, 0);
|
|
6786
|
+
if (existingMode === "loose" || appendedMode === "loose" || this.endsWithBlankLine(cached.src) || (parsed[0]?.map?.[0] ?? 0) > 0) {
|
|
6787
|
+
this.setListParagraphVisibility(cached.tokens, lastSegment.tokenStart, cached.tokens.length, listOpen.level, false);
|
|
6788
|
+
this.setListParagraphVisibility(inserted, 0, inserted.length, listOpen.level, false);
|
|
6789
|
+
}
|
|
6790
|
+
cached.tokens.splice(cached.tokens.length - 1, 0, ...inserted);
|
|
6791
|
+
cached.src = src;
|
|
6792
|
+
cached.env = env;
|
|
6793
|
+
cached.lineCount = countLines(src);
|
|
6794
|
+
if (listOpen.map) listOpen.map[1] = this.getDocLineCount(src);
|
|
6795
|
+
cached.lastSegment = {
|
|
6796
|
+
tokenStart: lastSegment.tokenStart,
|
|
6797
|
+
tokenEnd: cached.tokens.length,
|
|
6798
|
+
lineStart: lastSegment.lineStart,
|
|
6799
|
+
lineEnd: this.getDocLineCount(src),
|
|
6800
|
+
srcOffset: lastSegment.srcOffset
|
|
6801
|
+
};
|
|
6802
|
+
return cached.tokens;
|
|
6803
|
+
}
|
|
6804
|
+
tryTableTailAppendMerge(src, cached, env, md, lastSegment, appended, tableOpen) {
|
|
6805
|
+
if (cached.src.length === 0 || cached.src.charCodeAt(cached.src.length - 1) !== 10) return null;
|
|
6806
|
+
if (/(?:^|\n)[ \t]*\n/.test(appended)) return null;
|
|
6807
|
+
const segmentLineSpan = lastSegment.lineEnd - lastSegment.lineStart;
|
|
6808
|
+
const segmentChars = cached.src.length - lastSegment.srcOffset;
|
|
6809
|
+
if (segmentLineSpan < this.MIN_TABLE_LINES_FOR_MERGE && segmentChars < this.MIN_TABLE_CHARS_FOR_MERGE) return null;
|
|
6810
|
+
const tableContext = this.getTableHeaderContext(cached.src.slice(lastSegment.srcOffset));
|
|
6811
|
+
if (!tableContext) return null;
|
|
6812
|
+
const syntheticSrc = `${tableContext}${appended}`;
|
|
6813
|
+
let parsed;
|
|
6814
|
+
try {
|
|
6815
|
+
parsed = this.core.parse(syntheticSrc, env, md).tokens;
|
|
6816
|
+
} catch {
|
|
6817
|
+
return null;
|
|
6818
|
+
}
|
|
6819
|
+
if (!this.isSingleTopLevelContainer(parsed, "table_open", "table_close")) return null;
|
|
6820
|
+
if ((parsed[0]?.map?.[1] ?? -1) !== this.getDocLineCount(syntheticSrc)) return null;
|
|
6821
|
+
const parsedSection = this.getTableBodySection(parsed, 0, parsed.length, 0);
|
|
6822
|
+
const cachedSection = this.getTableBodySection(cached.tokens, lastSegment.tokenStart, cached.tokens.length, tableOpen.level);
|
|
6823
|
+
if (!parsedSection || !cachedSection || parsedSection.tbodyOpenIndex < 0 || parsedSection.tbodyCloseIndex < 0) return null;
|
|
6824
|
+
const inserted = cachedSection.tbodyOpenIndex >= 0 ? parsed.slice(parsedSection.tbodyOpenIndex + 1, parsedSection.tbodyCloseIndex) : parsed.slice(parsedSection.tbodyOpenIndex, parsedSection.tbodyCloseIndex + 1);
|
|
6825
|
+
if (inserted.length === 0) return null;
|
|
6826
|
+
const lineOffset = lastSegment.lineEnd - 2;
|
|
6827
|
+
if (lineOffset !== 0) this.shiftTokenLines(inserted, lineOffset);
|
|
6828
|
+
const insertAt = cachedSection.tbodyCloseIndex >= 0 ? cachedSection.tbodyCloseIndex : cachedSection.tableCloseIndex;
|
|
6829
|
+
cached.tokens.splice(insertAt, 0, ...inserted);
|
|
6830
|
+
cached.src = src;
|
|
6831
|
+
cached.env = env;
|
|
6832
|
+
cached.lineCount = countLines(src);
|
|
6833
|
+
const nextDocLineCount = this.getDocLineCount(src);
|
|
6834
|
+
if (tableOpen.map) tableOpen.map[1] = nextDocLineCount;
|
|
6835
|
+
if (cachedSection.tbodyOpenIndex >= 0) {
|
|
6836
|
+
const tbodyOpen = cached.tokens[cachedSection.tbodyOpenIndex];
|
|
6837
|
+
if (tbodyOpen?.map) tbodyOpen.map[1] = nextDocLineCount;
|
|
6838
|
+
}
|
|
6839
|
+
cached.lastSegment = {
|
|
6840
|
+
tokenStart: lastSegment.tokenStart,
|
|
6841
|
+
tokenEnd: cached.tokens.length,
|
|
6842
|
+
lineStart: lastSegment.lineStart,
|
|
6843
|
+
lineEnd: nextDocLineCount,
|
|
6844
|
+
srcOffset: lastSegment.srcOffset
|
|
6845
|
+
};
|
|
6846
|
+
return cached.tokens;
|
|
6847
|
+
}
|
|
6848
|
+
getTableHeaderContext(src) {
|
|
6849
|
+
const firstBreak = src.indexOf("\n");
|
|
6850
|
+
if (firstBreak < 0) return null;
|
|
6851
|
+
const secondBreak = src.indexOf("\n", firstBreak + 1);
|
|
6852
|
+
if (secondBreak < 0) return null;
|
|
6853
|
+
return src.slice(0, secondBreak + 1);
|
|
6854
|
+
}
|
|
6855
|
+
getTableBodySection(tokens, start, end, tableLevel) {
|
|
6856
|
+
if (start < 0 || start >= end || tokens[start]?.type !== "table_open") return null;
|
|
6857
|
+
let tableCloseIndex = -1;
|
|
6858
|
+
for (let i = end - 1; i > start; i--) {
|
|
6859
|
+
const token = tokens[i];
|
|
6860
|
+
if (token.type === "table_close" && token.level === tableLevel) {
|
|
6861
|
+
tableCloseIndex = i;
|
|
6862
|
+
break;
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
if (tableCloseIndex < 0) return null;
|
|
6866
|
+
let tbodyOpenIndex = -1;
|
|
6867
|
+
let tbodyCloseIndex = -1;
|
|
6868
|
+
for (let i = start + 1; i < tableCloseIndex; i++) {
|
|
6869
|
+
const token = tokens[i];
|
|
6870
|
+
if (token.type === "tbody_open" && token.level === tableLevel + 1) {
|
|
6871
|
+
tbodyOpenIndex = i;
|
|
6872
|
+
break;
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6875
|
+
if (tbodyOpenIndex >= 0) {
|
|
6876
|
+
for (let i = tableCloseIndex - 1; i > tbodyOpenIndex; i--) {
|
|
6877
|
+
const token = tokens[i];
|
|
6878
|
+
if (token.type === "tbody_close" && token.level === tableLevel + 1) {
|
|
6879
|
+
tbodyCloseIndex = i;
|
|
6880
|
+
break;
|
|
6881
|
+
}
|
|
6882
|
+
}
|
|
6883
|
+
if (tbodyCloseIndex < 0) return null;
|
|
6884
|
+
}
|
|
6885
|
+
return {
|
|
6886
|
+
tableCloseIndex,
|
|
6887
|
+
tbodyOpenIndex,
|
|
6888
|
+
tbodyCloseIndex
|
|
6889
|
+
};
|
|
6890
|
+
}
|
|
6891
|
+
isSingleTopLevelContainer(tokens, openType, closeType, markup) {
|
|
6892
|
+
if (tokens.length < 2) return false;
|
|
6893
|
+
const first = tokens[0];
|
|
6894
|
+
const last = tokens[tokens.length - 1];
|
|
6895
|
+
if (first.type !== openType || last.type !== closeType || first.level !== 0 || last.level !== 0) return false;
|
|
6896
|
+
if (markup !== void 0 && first.markup !== markup) return false;
|
|
6897
|
+
let depth = 0;
|
|
6898
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
6899
|
+
const token = tokens[i];
|
|
6900
|
+
if (token.level === 0 && i > 0 && i < tokens.length - 1 && depth === 0) return false;
|
|
6901
|
+
if (token.nesting > 0) depth += token.nesting;
|
|
6902
|
+
else if (token.nesting < 0) depth += token.nesting;
|
|
6903
|
+
}
|
|
6904
|
+
return depth === 0;
|
|
6905
|
+
}
|
|
6906
|
+
getListParagraphMode(tokens, start, end, listLevel) {
|
|
6907
|
+
let sawHidden = false;
|
|
6908
|
+
let sawVisible = false;
|
|
6909
|
+
const paragraphLevel = listLevel + 2;
|
|
6910
|
+
for (let i = start; i < end; i++) {
|
|
6911
|
+
const token = tokens[i];
|
|
6912
|
+
if (token.type !== "paragraph_open" || token.level !== paragraphLevel) continue;
|
|
6913
|
+
if (token.hidden) sawHidden = true;
|
|
6914
|
+
else sawVisible = true;
|
|
6915
|
+
if (sawHidden && sawVisible) return "loose";
|
|
6916
|
+
}
|
|
6917
|
+
if (sawVisible) return "loose";
|
|
6918
|
+
if (sawHidden) return "tight";
|
|
6919
|
+
return "none";
|
|
6920
|
+
}
|
|
6921
|
+
setListParagraphVisibility(tokens, start, end, listLevel, hidden) {
|
|
6922
|
+
const paragraphLevel = listLevel + 2;
|
|
6923
|
+
for (let i = start; i < end; i++) {
|
|
6924
|
+
const token = tokens[i];
|
|
6925
|
+
if ((token.type === "paragraph_open" || token.type === "paragraph_close") && token.level === paragraphLevel) token.hidden = hidden;
|
|
6926
|
+
}
|
|
6927
|
+
}
|
|
6928
|
+
shouldPreferTailReparseForAppend(cache) {
|
|
6929
|
+
const lastSegment = this.ensureLastSegment(cache);
|
|
6930
|
+
if (!lastSegment) return false;
|
|
6931
|
+
switch (cache.tokens[lastSegment.tokenStart]?.type) {
|
|
6932
|
+
case "bullet_list_open":
|
|
6933
|
+
case "ordered_list_open":
|
|
6934
|
+
case "blockquote_open":
|
|
6935
|
+
case "table_open": return true;
|
|
6936
|
+
case "paragraph_open":
|
|
6937
|
+
case "code_block":
|
|
6938
|
+
case "html_block": return !this.endsWithBlankLine(cache.src);
|
|
6939
|
+
default: return false;
|
|
6940
|
+
}
|
|
6941
|
+
}
|
|
6942
|
+
endsWithBlankLine(src) {
|
|
6943
|
+
const len = src.length;
|
|
6944
|
+
if (len < 2 || src.charCodeAt(len - 1) !== 10) return false;
|
|
6945
|
+
let pos = len - 2;
|
|
6946
|
+
while (pos >= 0) {
|
|
6947
|
+
const ch = src.charCodeAt(pos);
|
|
6948
|
+
if (ch === 32 || ch === 9) {
|
|
6949
|
+
pos--;
|
|
6950
|
+
continue;
|
|
6951
|
+
}
|
|
6952
|
+
return ch === 10;
|
|
6953
|
+
}
|
|
6954
|
+
return true;
|
|
6955
|
+
}
|
|
6956
|
+
getDocLineCount(src) {
|
|
6957
|
+
const lines = countLines(src);
|
|
6958
|
+
if (src.length === 0) return 0;
|
|
6959
|
+
return src.charCodeAt(src.length - 1) === 10 ? lines : lines + 1;
|
|
6960
|
+
}
|
|
6464
6961
|
shiftTokenLines(tokens, offset) {
|
|
6465
6962
|
if (offset === 0) return;
|
|
6466
6963
|
const stack = [...tokens];
|
|
@@ -6746,6 +7243,7 @@ function markdownIt(presetName, options) {
|
|
|
6746
7243
|
total: 0,
|
|
6747
7244
|
cacheHits: 0,
|
|
6748
7245
|
appendHits: 0,
|
|
7246
|
+
tailHits: 0,
|
|
6749
7247
|
fullParses: 0,
|
|
6750
7248
|
resets: 0,
|
|
6751
7249
|
chunkedParses: 0,
|
|
@@ -10247,6 +10745,7 @@ function parseTextToken(token) {
|
|
|
10247
10745
|
const STRONG_PAIR_RE = /\*\*([\s\S]*?)\*\*/;
|
|
10248
10746
|
const STRIKETHROUGH_RE = /[^~]*~{2,}[^~]+/;
|
|
10249
10747
|
const HAS_STRONG_RE = /\*\*/;
|
|
10748
|
+
const ESCAPED_PUNCTUATION_RE = /\\([\\()[\]`$|*_\-!])/g;
|
|
10250
10749
|
function countUnescapedAsterisks(str) {
|
|
10251
10750
|
let count = 0;
|
|
10252
10751
|
let i = 0;
|
|
@@ -10597,6 +11096,17 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10597
11096
|
result.push(currentTextNode);
|
|
10598
11097
|
}
|
|
10599
11098
|
}
|
|
11099
|
+
function hasEscapedMarkup(token, escapedPrefix) {
|
|
11100
|
+
return String(token.markup ?? "").startsWith(escapedPrefix);
|
|
11101
|
+
}
|
|
11102
|
+
function stripTrailingMidStateMarker(content, token) {
|
|
11103
|
+
let nextContent = content;
|
|
11104
|
+
const rawTokenContent = String(token.content ?? "");
|
|
11105
|
+
if (nextContent.endsWith("\\") && !hasEscapedMarkup(token, "\\\\") && !rawTokenContent.endsWith("\\\\")) nextContent = nextContent.slice(0, -1);
|
|
11106
|
+
if (nextContent.endsWith("(") && !hasEscapedMarkup(token, "\\(") && !rawTokenContent.endsWith("\\(")) nextContent = nextContent.slice(0, -1);
|
|
11107
|
+
if (/\*+$/.test(nextContent) && !hasEscapedMarkup(token, "\\*") && !rawTokenContent.endsWith("\\*")) nextContent = nextContent.replace(/\*+$/, "");
|
|
11108
|
+
return nextContent;
|
|
11109
|
+
}
|
|
10600
11110
|
while (i < tokens.length) {
|
|
10601
11111
|
const token = tokens[i];
|
|
10602
11112
|
handleToken(token);
|
|
@@ -10791,12 +11301,12 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10791
11301
|
content
|
|
10792
11302
|
});
|
|
10793
11303
|
if (currentTextNode) {
|
|
10794
|
-
currentTextNode.content += textNode.content
|
|
11304
|
+
currentTextNode.content += stripTrailingMidStateMarker(textNode.content, token);
|
|
10795
11305
|
currentTextNode.raw += textNode.raw;
|
|
10796
11306
|
return;
|
|
10797
11307
|
}
|
|
10798
11308
|
const maybeMath = preToken?.tag === "br" && tokens[i - 2]?.content === "[";
|
|
10799
|
-
if (!nextToken) textNode.content = textNode.content
|
|
11309
|
+
if (!nextToken) textNode.content = stripTrailingMidStateMarker(textNode.content, token);
|
|
10800
11310
|
currentTextNode = textNode;
|
|
10801
11311
|
currentTextNode.center = maybeMath;
|
|
10802
11312
|
result.push(currentTextNode);
|
|
@@ -10804,8 +11314,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10804
11314
|
function handleTextToken(token) {
|
|
10805
11315
|
let index = result.length - 1;
|
|
10806
11316
|
const rawContent = String(token.content ?? "");
|
|
10807
|
-
let content = rawContent;
|
|
10808
|
-
if (rawContent.includes("\\")) content = rawContent.replace(/\\/g, "");
|
|
11317
|
+
let content = rawContent.replace(ESCAPED_PUNCTUATION_RE, "$1");
|
|
10809
11318
|
if (token.content === "<" || content === "1" && tokens[i - 1]?.tag === "br") {
|
|
10810
11319
|
i++;
|
|
10811
11320
|
return;
|
|
@@ -10829,7 +11338,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10829
11338
|
i++;
|
|
10830
11339
|
return;
|
|
10831
11340
|
}
|
|
10832
|
-
if (content === "`" || content === "|" || content === "$" || /^\*+$/.test(content)) {
|
|
11341
|
+
if ((content === "`" || content === "|" || content === "$") && !hasEscapedMarkup(token, `\\${content}`) || /^\*+$/.test(content) && !hasEscapedMarkup(token, "\\*")) {
|
|
10833
11342
|
i++;
|
|
10834
11343
|
return;
|
|
10835
11344
|
}
|