stream-markdown-parser 0.0.31 → 0.0.33

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.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.2-beta.5/node_modules/markdown-it-ts/dist/chunk-Bp6m_JJh.js
604
+ //#region ../../node_modules/.pnpm/markdown-it-ts@0.0.2-beta.8/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.2-beta.5/node_modules/markdown-it-ts/dist/index.js
2190
+ //#region ../../node_modules/.pnpm/markdown-it-ts@0.0.2-beta.8/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,
@@ -2865,13 +2865,46 @@ function normalize(state) {
2865
2865
  str = str.replace(NULL_RE, "�");
2866
2866
  state.src = str;
2867
2867
  }
2868
+ const RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/;
2869
+ const SCOPED_ABBR_TEST_RE = /\((?:c|tm|r)\)/i;
2870
+ const SCOPED_ABBR_RE = /\((c|tm|r)\)/gi;
2871
+ const SCOPED_ABBR = {
2872
+ c: "©",
2873
+ r: "®",
2874
+ tm: "™"
2875
+ };
2876
+ function replaceFn(_match, name) {
2877
+ return SCOPED_ABBR[name.toLowerCase()];
2878
+ }
2879
+ function replace_scoped(inlineTokens) {
2880
+ let inside_autolink = 0;
2881
+ for (let i = inlineTokens.length - 1; i >= 0; i--) {
2882
+ const token = inlineTokens[i];
2883
+ if (token.type === "text" && !inside_autolink) token.content = token.content.replace(SCOPED_ABBR_RE, replaceFn);
2884
+ if (token.type === "link_open" && token.info === "auto") inside_autolink--;
2885
+ if (token.type === "link_close" && token.info === "auto") inside_autolink++;
2886
+ }
2887
+ }
2888
+ function replace_rare(inlineTokens) {
2889
+ let inside_autolink = 0;
2890
+ for (let i = inlineTokens.length - 1; i >= 0; i--) {
2891
+ const token = inlineTokens[i];
2892
+ if (token.type === "text" && !inside_autolink) {
2893
+ 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–");
2894
+ }
2895
+ if (token.type === "link_open" && token.info === "auto") inside_autolink--;
2896
+ if (token.type === "link_close" && token.info === "auto") inside_autolink++;
2897
+ }
2898
+ }
2868
2899
  function replacements(state) {
2869
2900
  if (!state.md?.options?.typographer) return;
2870
- (state.tokens || []).forEach((tk) => {
2871
- if (tk.type === "inline" && Array.isArray(tk.children)) tk.children.forEach((ch) => {
2872
- if (ch.type === "text" && typeof ch.content === "string") ch.content = ch.content.replace(/\.\.\./g, "…").replace(/---/g, "—").replace(/--/g, "–");
2873
- });
2874
- });
2901
+ for (let blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
2902
+ const blk = state.tokens[blkIdx];
2903
+ if (blk.type !== "inline") continue;
2904
+ const blkContent = blk.content || (Array.isArray(blk.children) ? blk.children.map((c) => c.type === "text" ? c.content : "").join("") : "");
2905
+ if (SCOPED_ABBR_TEST_RE.test(blkContent)) replace_scoped(blk.children || []);
2906
+ if (RARE_RE.test(blkContent)) replace_rare(blk.children || []);
2907
+ }
2875
2908
  }
2876
2909
  var CoreRuler = class {
2877
2910
  rules = [];
@@ -4639,24 +4672,12 @@ var entity_default = entity;
4639
4672
  * Inline rule: escape
4640
4673
  * Process escaped characters
4641
4674
  */
4642
- const ESCAPED = [
4643
- 92,
4644
- 96,
4645
- 42,
4646
- 95,
4647
- 123,
4648
- 125,
4649
- 91,
4650
- 93,
4651
- 40,
4652
- 41,
4653
- 35,
4654
- 43,
4655
- 45,
4656
- 46,
4657
- 33,
4658
- 124
4659
- ];
4675
+ const ESCAPED = (() => {
4676
+ const table$1 = new Array(256).fill(0);
4677
+ const chars = "\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-";
4678
+ for (let i = 0; i < 32; i++) table$1[chars.charCodeAt(i)] = 1;
4679
+ return table$1;
4680
+ })();
4660
4681
  function escape(state, silent) {
4661
4682
  const { pos, posMax, src } = state;
4662
4683
  if (src.charCodeAt(pos) !== 92) return false;
@@ -4668,12 +4689,25 @@ function escape(state, silent) {
4668
4689
  state.pos += 2;
4669
4690
  return true;
4670
4691
  }
4671
- if (ch < 128 && ESCAPED.includes(ch)) {
4672
- if (!silent) state.pending += src[pos_next];
4673
- state.pos += 2;
4674
- return true;
4692
+ let escapedStr = src[pos_next];
4693
+ let nextPos = pos_next;
4694
+ if (ch >= 55296 && ch <= 56319 && pos_next + 1 < posMax) {
4695
+ const ch2 = src.charCodeAt(pos_next + 1);
4696
+ if (ch2 >= 56320 && ch2 <= 57343) {
4697
+ escapedStr += src[pos_next + 1];
4698
+ nextPos++;
4699
+ }
4675
4700
  }
4676
- return false;
4701
+ const origStr = src[pos] + escapedStr;
4702
+ if (!silent) {
4703
+ const token = state.push("text_special", "", 0);
4704
+ if (ch < 256 && ESCAPED[ch]) token.content = escapedStr;
4705
+ else token.content = origStr;
4706
+ token.markup = origStr;
4707
+ token.info = "escape";
4708
+ }
4709
+ state.pos = nextPos + 1;
4710
+ return true;
4677
4711
  }
4678
4712
  var escape_default = escape;
4679
4713
  function fragments_join(state) {
@@ -5584,6 +5618,36 @@ function unescapeAll(str) {
5584
5618
  return match;
5585
5619
  });
5586
5620
  }
5621
+ function isPromiseLike(value) {
5622
+ return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
5623
+ }
5624
+ function ensureSyncResult(value, ruleName) {
5625
+ if (isPromiseLike(value)) throw new TypeError(`Renderer rule "${ruleName}" returned a Promise. Use renderAsync() instead.`);
5626
+ return value;
5627
+ }
5628
+ const resolveResult = (value) => isPromiseLike(value) ? value : Promise.resolve(value);
5629
+ function renderFence(token, highlighted, info, langName, options, self) {
5630
+ if (highlighted.startsWith("<pre")) return `${highlighted}\n`;
5631
+ if (info) {
5632
+ const classIndex = typeof token.attrIndex === "function" ? token.attrIndex("class") : -1;
5633
+ const tmpAttrs = token.attrs ? token.attrs.map((attr) => attr.slice()) : [];
5634
+ const langClass = `${options.langPrefix || "language-"}${langName}`;
5635
+ if (classIndex < 0) tmpAttrs.push(["class", langClass]);
5636
+ else tmpAttrs[classIndex][1] += ` ${langClass}`;
5637
+ const tmpToken = {
5638
+ ...token,
5639
+ attrs: tmpAttrs
5640
+ };
5641
+ return `<pre><code${self.renderAttrs(tmpToken)}>${highlighted}</code></pre>\n`;
5642
+ }
5643
+ return `<pre><code${self.renderAttrs(token)}>${highlighted}</code></pre>\n`;
5644
+ }
5645
+ const DEFAULT_RENDERER_OPTIONS = {
5646
+ langPrefix: "language-",
5647
+ xhtmlOut: false,
5648
+ breaks: false
5649
+ };
5650
+ const hasOwn = Object.prototype.hasOwnProperty;
5587
5651
  const defaultRules = {
5588
5652
  code_inline(tokens, idx, _options, _env, self) {
5589
5653
  const token = tokens[idx];
@@ -5604,21 +5668,11 @@ const defaultRules = {
5604
5668
  langAttrs = parts.slice(2).join("");
5605
5669
  }
5606
5670
  const highlight = options.highlight;
5607
- const highlighted = highlight ? highlight(token.content, langName, langAttrs) || escapeHtml(token.content) : escapeHtml(token.content);
5608
- if (highlighted.startsWith("<pre")) return `${highlighted}\n`;
5609
- if (info) {
5610
- const classIndex = typeof token.attrIndex === "function" ? token.attrIndex("class") : -1;
5611
- const tmpAttrs = token.attrs ? token.attrs.map((attr) => attr.slice()) : [];
5612
- const langClass = `${options.langPrefix || "language-"}${langName}`;
5613
- if (classIndex < 0) tmpAttrs.push(["class", langClass]);
5614
- else tmpAttrs[classIndex][1] += ` ${langClass}`;
5615
- const tmpToken = {
5616
- ...token,
5617
- attrs: tmpAttrs
5618
- };
5619
- return `<pre><code${self.renderAttrs(tmpToken)}>${highlighted}</code></pre>\n`;
5620
- }
5621
- return `<pre><code${self.renderAttrs(token)}>${highlighted}</code></pre>\n`;
5671
+ const fallback = () => escapeHtml(token.content);
5672
+ if (!highlight) return renderFence(token, fallback(), info, langName, options, self);
5673
+ const highlighted = highlight(token.content, langName, langAttrs);
5674
+ if (isPromiseLike(highlighted)) return highlighted.then((res) => renderFence(token, res || fallback(), info, langName, options, self));
5675
+ return renderFence(token, highlighted || fallback(), info, langName, options, self);
5622
5676
  },
5623
5677
  image(tokens, idx, options, env, self) {
5624
5678
  const token = tokens[idx];
@@ -5640,6 +5694,9 @@ const defaultRules = {
5640
5694
  text(tokens, idx) {
5641
5695
  return escapeHtml(tokens[idx].content);
5642
5696
  },
5697
+ text_special(tokens, idx) {
5698
+ return escapeHtml(tokens[idx].content);
5699
+ },
5643
5700
  html_block(tokens, idx) {
5644
5701
  return tokens[idx].content;
5645
5702
  },
@@ -5647,84 +5704,93 @@ const defaultRules = {
5647
5704
  return tokens[idx].content;
5648
5705
  }
5649
5706
  };
5650
- function mergeOptions(base$1, override) {
5651
- return {
5652
- langPrefix: "language-",
5653
- xhtmlOut: false,
5654
- breaks: false,
5655
- ...base$1,
5656
- ...override
5657
- };
5658
- }
5659
5707
  var Renderer = class {
5660
5708
  rules;
5661
5709
  baseOptions;
5710
+ normalizedBase;
5711
+ bufferPool;
5662
5712
  constructor(options = {}) {
5663
5713
  this.baseOptions = { ...options };
5714
+ this.normalizedBase = this.buildNormalizedBase();
5664
5715
  this.rules = { ...defaultRules };
5716
+ this.bufferPool = [];
5665
5717
  }
5666
5718
  set(options) {
5667
5719
  this.baseOptions = {
5668
5720
  ...this.baseOptions,
5669
5721
  ...options
5670
5722
  };
5723
+ this.normalizedBase = this.buildNormalizedBase();
5671
5724
  return this;
5672
5725
  }
5673
5726
  render(tokens, options = {}, env = {}) {
5674
5727
  if (!Array.isArray(tokens)) throw new TypeError("render expects token array as first argument");
5675
- const merged = mergeOptions(this.baseOptions, options);
5676
- let result = "";
5728
+ const merged = this.mergeOptions(options);
5729
+ const chunks = this.acquireBuffer();
5677
5730
  for (let i = 0; i < tokens.length; i++) {
5678
5731
  const token = tokens[i];
5679
5732
  if (token.type === "inline") {
5680
- result += this.renderInline(token.children || [], merged, env);
5733
+ this.pushInlineTokens(token.children || [], merged, env, chunks);
5681
5734
  continue;
5682
5735
  }
5683
5736
  const rule = this.rules[token.type];
5684
- if (rule) result += rule(tokens, i, merged, env, this);
5685
- else result += this.renderToken(tokens, i, merged);
5737
+ if (rule) chunks.push(ensureSyncResult(rule(tokens, i, merged, env, this), token.type));
5738
+ else chunks.push(this.renderToken(tokens, i, merged));
5686
5739
  }
5687
- return result;
5740
+ const output = chunks.join("");
5741
+ this.releaseBuffer(chunks);
5742
+ return output;
5688
5743
  }
5689
- renderInline(tokens, options = {}, env = {}) {
5690
- const merged = mergeOptions(this.baseOptions, options);
5691
- let result = "";
5744
+ async renderAsync(tokens, options = {}, env = {}) {
5745
+ if (!Array.isArray(tokens)) throw new TypeError("render expects token array as first argument");
5746
+ const merged = this.mergeOptions(options);
5747
+ const chunks = this.acquireBuffer();
5692
5748
  for (let i = 0; i < tokens.length; i++) {
5693
5749
  const token = tokens[i];
5750
+ if (token.type === "inline") {
5751
+ await this.pushInlineTokensAsync(token.children || [], merged, env, chunks);
5752
+ continue;
5753
+ }
5694
5754
  const rule = this.rules[token.type];
5695
- if (rule) result += rule(tokens, i, merged, env, this);
5696
- else result += this.renderToken(tokens, i, merged);
5755
+ if (rule) chunks.push(await resolveResult(rule(tokens, i, merged, env, this)));
5756
+ else chunks.push(this.renderToken(tokens, i, merged));
5697
5757
  }
5698
- return result;
5758
+ const output = chunks.join("");
5759
+ this.releaseBuffer(chunks);
5760
+ return output;
5761
+ }
5762
+ renderInline(tokens, options = {}, env = {}) {
5763
+ const merged = this.mergeOptions(options);
5764
+ const chunks = this.acquireBuffer();
5765
+ this.pushInlineTokens(tokens, merged, env, chunks);
5766
+ const output = chunks.join("");
5767
+ this.releaseBuffer(chunks);
5768
+ return output;
5769
+ }
5770
+ async renderInlineAsync(tokens, options = {}, env = {}) {
5771
+ const merged = this.mergeOptions(options);
5772
+ const chunks = this.acquireBuffer();
5773
+ await this.pushInlineTokensAsync(tokens, merged, env, chunks);
5774
+ const output = chunks.join("");
5775
+ this.releaseBuffer(chunks);
5776
+ return output;
5699
5777
  }
5700
5778
  renderInlineAsText(tokens, options = {}, env = {}) {
5701
- const merged = mergeOptions(this.baseOptions, options);
5702
- let result = "";
5703
- for (let i = 0; i < tokens.length; i++) {
5704
- const token = tokens[i];
5705
- switch (token.type) {
5706
- case "text":
5707
- result += token.content;
5708
- break;
5709
- case "image":
5710
- result += this.renderInlineAsText(token.children || [], merged, env);
5711
- break;
5712
- case "html_inline":
5713
- case "html_block":
5714
- result += token.content;
5715
- break;
5716
- case "softbreak":
5717
- case "hardbreak":
5718
- result += "\n";
5719
- break;
5720
- default: break;
5721
- }
5722
- }
5723
- return result;
5779
+ const merged = this.mergeOptions(options);
5780
+ const chunks = this.acquireBuffer();
5781
+ this.renderInlineAsTextInternal(tokens, merged, env, chunks);
5782
+ const output = chunks.join("");
5783
+ this.releaseBuffer(chunks);
5784
+ return output;
5724
5785
  }
5725
5786
  renderAttrs(token) {
5726
5787
  if (!token.attrs || token.attrs.length === 0) return "";
5727
- return token.attrs.map(([name, value]) => ` ${escapeHtml(name)}="${escapeHtml(value)}"`).join("");
5788
+ let result = "";
5789
+ for (let i = 0; i < token.attrs.length; i++) {
5790
+ const attr = token.attrs[i];
5791
+ result += ` ${escapeHtml(attr[0])}="${escapeHtml(attr[1])}"`;
5792
+ }
5793
+ return result;
5728
5794
  }
5729
5795
  renderToken(tokens, idx, options) {
5730
5796
  const token = tokens[idx];
@@ -5746,6 +5812,86 @@ var Renderer = class {
5746
5812
  result += needLineFeed ? ">\n" : ">";
5747
5813
  return result;
5748
5814
  }
5815
+ mergeOptions(overrides) {
5816
+ const base$1 = this.normalizedBase;
5817
+ if (!overrides) return base$1;
5818
+ let merged = null;
5819
+ const ensureMerged = () => {
5820
+ if (!merged) merged = { ...base$1 };
5821
+ return merged;
5822
+ };
5823
+ if (hasOwn.call(overrides, "highlight") && overrides.highlight !== base$1.highlight) ensureMerged().highlight = overrides.highlight;
5824
+ if (hasOwn.call(overrides, "langPrefix")) {
5825
+ const value = overrides.langPrefix;
5826
+ if (value !== base$1.langPrefix) ensureMerged().langPrefix = value;
5827
+ }
5828
+ if (hasOwn.call(overrides, "xhtmlOut")) {
5829
+ const value = overrides.xhtmlOut;
5830
+ if (value !== base$1.xhtmlOut) ensureMerged().xhtmlOut = value;
5831
+ }
5832
+ if (hasOwn.call(overrides, "breaks")) {
5833
+ const value = overrides.breaks;
5834
+ if (value !== base$1.breaks) ensureMerged().breaks = value;
5835
+ }
5836
+ return merged || base$1;
5837
+ }
5838
+ buildNormalizedBase() {
5839
+ return Object.freeze({
5840
+ ...DEFAULT_RENDERER_OPTIONS,
5841
+ ...this.baseOptions
5842
+ });
5843
+ }
5844
+ pushInlineTokens(tokens, options, env, buffer) {
5845
+ for (let i = 0; i < tokens.length; i++) {
5846
+ const token = tokens[i];
5847
+ const rule = this.rules[token.type];
5848
+ if (rule) buffer.push(ensureSyncResult(rule(tokens, i, options, env, this), token.type));
5849
+ else buffer.push(this.renderToken(tokens, i, options));
5850
+ }
5851
+ }
5852
+ async pushInlineTokensAsync(tokens, options, env, buffer) {
5853
+ for (let i = 0; i < tokens.length; i++) {
5854
+ const token = tokens[i];
5855
+ const rule = this.rules[token.type];
5856
+ if (rule) buffer.push(await resolveResult(rule(tokens, i, options, env, this)));
5857
+ else buffer.push(this.renderToken(tokens, i, options));
5858
+ }
5859
+ }
5860
+ renderInlineAsTextInternal(tokens, options, env, buffer) {
5861
+ for (let i = 0; i < tokens.length; i++) {
5862
+ const token = tokens[i];
5863
+ switch (token.type) {
5864
+ case "text":
5865
+ case "text_special":
5866
+ buffer.push(token.content);
5867
+ break;
5868
+ case "image":
5869
+ this.renderInlineAsTextInternal(token.children || [], options, env, buffer);
5870
+ break;
5871
+ case "html_inline":
5872
+ case "html_block":
5873
+ buffer.push(token.content);
5874
+ break;
5875
+ case "softbreak":
5876
+ case "hardbreak":
5877
+ buffer.push("\n");
5878
+ break;
5879
+ default: break;
5880
+ }
5881
+ }
5882
+ }
5883
+ acquireBuffer() {
5884
+ const buf = this.bufferPool.pop();
5885
+ if (buf) {
5886
+ buf.length = 0;
5887
+ return buf;
5888
+ }
5889
+ return [];
5890
+ }
5891
+ releaseBuffer(buffer) {
5892
+ buffer.length = 0;
5893
+ this.bufferPool.push(buffer);
5894
+ }
5749
5895
  };
5750
5896
  var renderer_default = Renderer;
5751
5897
  const DEFAULTS = {
@@ -6005,12 +6151,100 @@ var StreamParser = class {
6005
6151
  }
6006
6152
  const appended = this.getAppendedSegment(cached.src, src);
6007
6153
  if (appended) {
6008
- const appendedState = this.core.parse(appended, cached.env, md);
6009
- const lineOffset = cached.lineCount ?? countLines(cached.src);
6010
- if (lineOffset > 0) this.shiftTokenLines(appendedState.tokens, lineOffset);
6011
- cached.tokens.push(...appendedState.tokens);
6154
+ const cachedLineCount = cached.lineCount ?? countLines(cached.src);
6155
+ let ctxLines = 3;
6156
+ if (appended.length > 5e3) ctxLines = 8;
6157
+ else if (appended.length > 1e3) ctxLines = 6;
6158
+ else if (appended.length > 200) ctxLines = 4;
6159
+ ctxLines = Math.min(ctxLines, cachedLineCount);
6160
+ let appendedState = null;
6161
+ const ctxStrategy = md.options?.streamContextParseStrategy ?? "chars";
6162
+ const CONTEXT_PARSE_MIN_CHARS = md.options?.streamContextParseMinChars ?? 200;
6163
+ const CONTEXT_PARSE_MIN_LINES = md.options?.streamContextParseMinLines ?? 2;
6164
+ function appendedHasBlockConstructs(s) {
6165
+ return /(?:^|\n)\s{0,3}(?:#{1,6}\s|>\s|[-*+]\s|\d+\.\s|```|~~~| {4,})/.test(s);
6166
+ }
6167
+ let shouldAttemptContext = false;
6168
+ switch (ctxStrategy) {
6169
+ case "lines":
6170
+ shouldAttemptContext = countLines(appended) >= CONTEXT_PARSE_MIN_LINES;
6171
+ break;
6172
+ case "constructs": {
6173
+ const appendedLines = countLines(appended);
6174
+ shouldAttemptContext = appendedHasBlockConstructs(appended) || appendedLines >= CONTEXT_PARSE_MIN_LINES || appended.length >= CONTEXT_PARSE_MIN_CHARS;
6175
+ break;
6176
+ }
6177
+ case "chars":
6178
+ default: shouldAttemptContext = appended.length >= CONTEXT_PARSE_MIN_CHARS;
6179
+ }
6180
+ if (ctxLines > 0 && shouldAttemptContext) {
6181
+ const cachedLines = cached.src.split("\n");
6182
+ const ctxStart = Math.max(0, cachedLines.length - ctxLines);
6183
+ const ctxSrc = cachedLines.slice(ctxStart).join("\n") + appended;
6184
+ try {
6185
+ const ctxTokens = this.core.parse(ctxSrc, cached.env, md).tokens;
6186
+ const idx = ctxTokens.findIndex((t) => t.map && typeof t.map[1] === "number" && t.map[1] >= ctxLines);
6187
+ if (idx !== -1) {
6188
+ const appendedTokens = ctxTokens.slice(idx);
6189
+ const shiftBy = cachedLineCount - ctxLines;
6190
+ if (shiftBy !== 0) this.shiftTokenLines(appendedTokens, shiftBy);
6191
+ appendedState = { tokens: appendedTokens };
6192
+ }
6193
+ } catch {
6194
+ appendedState = null;
6195
+ }
6196
+ } else appendedState = null;
6197
+ if (!appendedState) {
6198
+ const simpleState = this.core.parse(appended, cached.env, md);
6199
+ const lineOffset = cachedLineCount;
6200
+ if (lineOffset > 0) this.shiftTokenLines(simpleState.tokens, lineOffset);
6201
+ appendedState = simpleState;
6202
+ }
6203
+ if (cached.tokens.length > 0 && appendedState.tokens.length > 0) {
6204
+ const lastCached = cached.tokens[cached.tokens.length - 1];
6205
+ const firstApp = appendedState.tokens[0];
6206
+ try {
6207
+ if (lastCached.type === "inline" && firstApp.type === "inline") {
6208
+ if (firstApp.children && firstApp.children.length > 0) {
6209
+ if (!lastCached.children) lastCached.children = [];
6210
+ lastCached.children.push(...firstApp.children);
6211
+ }
6212
+ lastCached.content = (lastCached.content || "") + (firstApp.content || "");
6213
+ appendedState.tokens.shift();
6214
+ }
6215
+ } catch {}
6216
+ }
6217
+ if (appendedState.tokens.length > 0) {
6218
+ const cachedTail = cached.tokens;
6219
+ const a = appendedState.tokens;
6220
+ const maxCheck = Math.min(cachedTail.length, a.length);
6221
+ function tokenEquals(x, y) {
6222
+ if (!x || !y) return false;
6223
+ if (x.type !== y.type) return false;
6224
+ if (x.type === "inline") return (x.content || "") === (y.content || "");
6225
+ return true;
6226
+ }
6227
+ let dup = 0;
6228
+ for (let n = maxCheck; n > 0; n--) {
6229
+ let ok = true;
6230
+ for (let i = 0; i < n; i++) {
6231
+ const tailToken = cachedTail[cachedTail.length - n + i];
6232
+ const prefToken = a[i];
6233
+ if (!tokenEquals(tailToken, prefToken)) {
6234
+ ok = false;
6235
+ break;
6236
+ }
6237
+ }
6238
+ if (ok) {
6239
+ dup = n;
6240
+ break;
6241
+ }
6242
+ }
6243
+ if (dup > 0) a.splice(0, dup);
6244
+ if (a.length > 0) cached.tokens.push(...a);
6245
+ }
6012
6246
  cached.src = src;
6013
- cached.lineCount = lineOffset + countLines(appended);
6247
+ cached.lineCount = cachedLineCount + countLines(appended);
6014
6248
  this.stats.total += 1;
6015
6249
  this.stats.appendHits += 1;
6016
6250
  this.stats.lastMode = "append";
@@ -6331,6 +6565,10 @@ function markdownIt(presetName, options) {
6331
6565
  const tokens = this.parse(src, env);
6332
6566
  return getRenderer().render(tokens, this.options, env);
6333
6567
  },
6568
+ async renderAsync(src, env = {}) {
6569
+ const tokens = this.parse(src, env);
6570
+ return getRenderer().renderAsync(tokens, this.options, env);
6571
+ },
6334
6572
  renderInline(src, env = {}) {
6335
6573
  const tokens = this.parseInline(src, env);
6336
6574
  return getRenderer().render(tokens, this.options, env);
@@ -6722,37 +6960,6 @@ function applyFixHtmlInlineTokens(md) {
6722
6960
  });
6723
6961
  }
6724
6962
 
6725
- //#endregion
6726
- //#region src/plugins/fixLinkInline.ts
6727
- const LINK_PREFIX_RE = /^\[([^\]]*)\]\(([^)\s]*)/;
6728
- function applyFixLinkInline(md) {
6729
- const rule = (state, silent) => {
6730
- const s = state;
6731
- const start = s.pos;
6732
- if (s.src[start] !== "[") return false;
6733
- if (start > 0 && s.src[start - 1] === "!") return false;
6734
- const rest = s.src.slice(start);
6735
- const m = LINK_PREFIX_RE.exec(rest);
6736
- if (!m) return false;
6737
- if (silent) return true;
6738
- const text$1 = m[1] ?? "";
6739
- const href = m[2] ?? "";
6740
- if (text$1.includes("*") || text$1.includes(":")) return false;
6741
- const idxClose = rest.indexOf(")");
6742
- const hasClosingParen = idxClose !== -1;
6743
- const open = s.push("link_open", "a", 1);
6744
- open.attrs = [["href", href]];
6745
- const txt = s.push("text", "", 0);
6746
- txt.content = text$1;
6747
- if (hasClosingParen) {
6748
- s.push("link_close", "a", -1);
6749
- s.pos += idxClose + 1;
6750
- } else s.pos += m[0].length;
6751
- return true;
6752
- };
6753
- md.inline.ruler.before("link", "fix_link_inline", rule);
6754
- }
6755
-
6756
6963
  //#endregion
6757
6964
  //#region src/plugins/fixLinkTokens.ts
6758
6965
  function textToken(content) {
@@ -6811,11 +7018,17 @@ function pushEmClose(arr, type) {
6811
7018
  }
6812
7019
  }
6813
7020
  function createLinkToken(text$1, href, loading) {
7021
+ let title = "";
7022
+ if (href.includes("\"")) {
7023
+ const temps = href.split("\"");
7024
+ href = temps[0].trim();
7025
+ title = temps[1].trim();
7026
+ }
6814
7027
  return {
6815
7028
  type: "link",
6816
7029
  loading,
6817
7030
  href,
6818
- title: "",
7031
+ title,
6819
7032
  text: text$1,
6820
7033
  children: [{
6821
7034
  type: "text",
@@ -6972,7 +7185,9 @@ function fixLinkToken(tokens) {
6972
7185
  if (curToken.type === "link_close" && curToken.nesting === -1 && tokens[i + 1]?.type === "text" && tokens[i - 1]?.type === "text") {
6973
7186
  let loading = true;
6974
7187
  const text$1 = tokens[i - 1].content || "";
6975
- let href = tokens[i - 2].attrs?.[0]?.[1] || "";
7188
+ const attrs = tokens[i - 2].attrs || [];
7189
+ let href = attrs.find((a) => a[0] === "href")?.[1] || "";
7190
+ const title = attrs.find((a) => a[0] === "title")?.[1] || "";
6976
7191
  let count = 3;
6977
7192
  let deleteCount = 2;
6978
7193
  const emphasisMatch = (tokens[i - 3]?.content || "").match(/^(\*+)$/);
@@ -6988,8 +7203,8 @@ function fixLinkToken(tokens) {
6988
7203
  if (m === -1) {
6989
7204
  href += tokens[i + 1]?.content?.slice(0, m) || "";
6990
7205
  tokens[i + 1].content = "";
7206
+ count += 1;
6991
7207
  } else loading = false;
6992
- count += 1;
6993
7208
  } else if (tokens[i + 1].type === "text" && tokens[i + 1]?.content?.startsWith("](")) {
6994
7209
  count += 1;
6995
7210
  for (let j = i + 1; j < tokens.length; j++) {
@@ -7009,12 +7224,12 @@ function fixLinkToken(tokens) {
7009
7224
  }
7010
7225
  count += 1;
7011
7226
  }
7012
- }
7227
+ } else loading = false;
7013
7228
  replacerTokens.push({
7014
7229
  type: "link",
7015
7230
  loading,
7016
7231
  href,
7017
- title: "",
7232
+ title,
7018
7233
  text: text$1,
7019
7234
  children: [{
7020
7235
  type: "text",
@@ -7171,11 +7386,89 @@ function applyFixStrongTokens(md) {
7171
7386
  });
7172
7387
  }
7173
7388
  function fixStrongTokens(tokens) {
7174
- const fixedTokens = [...tokens];
7175
- if (tokens.length < 4) return fixedTokens;
7389
+ let strongIndex = 0;
7390
+ const cleansStrong = /* @__PURE__ */ new Set();
7391
+ const cleansEm = /* @__PURE__ */ new Set();
7392
+ let emIndex = 0;
7393
+ for (let i$1 = 0; i$1 < tokens.length; i$1++) {
7394
+ const t = tokens[i$1];
7395
+ const type = t.type;
7396
+ if (type === "strong_open") {
7397
+ strongIndex++;
7398
+ const markup = String(t.markup ?? "");
7399
+ let j = i$1 - 1;
7400
+ while (j >= 0 && tokens[j].type === "text" && tokens[j].content === "") j--;
7401
+ const preToken = tokens[j];
7402
+ let k = i$1 + 1;
7403
+ while (k < tokens.length && tokens[k].type === "text" && tokens[k].content === "") k++;
7404
+ const postToken = tokens[k];
7405
+ if (markup === "__" && (preToken?.content?.endsWith("_") || postToken?.content?.startsWith("_") || postToken?.markup?.includes("_"))) {
7406
+ t.type = "text";
7407
+ t.tag = "";
7408
+ t.content = markup;
7409
+ t.raw = markup;
7410
+ t.markup = "";
7411
+ t.attrs = null;
7412
+ t.map = null;
7413
+ t.info = "";
7414
+ t.meta = null;
7415
+ cleansStrong.add(strongIndex);
7416
+ }
7417
+ } else if (type === "strong_close") {
7418
+ if (cleansStrong.has(strongIndex) && t.markup === "__") {
7419
+ t.type = "text";
7420
+ t.content = t.markup;
7421
+ t.raw = String(t.markup ?? "");
7422
+ t.tag = "";
7423
+ t.markup = "";
7424
+ t.attrs = null;
7425
+ t.map = null;
7426
+ t.info = "";
7427
+ t.meta = null;
7428
+ }
7429
+ strongIndex--;
7430
+ if (strongIndex < 0) strongIndex = 0;
7431
+ } else if (type === "em_open") {
7432
+ emIndex++;
7433
+ const markup = String(t.markup ?? "");
7434
+ let j = i$1 - 1;
7435
+ while (j >= 0 && tokens[j].type === "text" && tokens[j].content === "") j--;
7436
+ const preToken = tokens[j];
7437
+ let k = i$1 + 1;
7438
+ while (k < tokens.length && tokens[k].type === "text" && tokens[k].content === "") k++;
7439
+ const postToken = tokens[k];
7440
+ if (markup === "_" && (preToken?.content?.endsWith("_") || postToken?.content?.startsWith("_") || postToken?.markup?.includes("_"))) {
7441
+ t.type = "text";
7442
+ t.tag = "";
7443
+ t.content = markup;
7444
+ t.raw = markup;
7445
+ t.markup = "";
7446
+ t.attrs = null;
7447
+ t.map = null;
7448
+ t.info = "";
7449
+ t.meta = null;
7450
+ cleansEm.add(emIndex);
7451
+ }
7452
+ } else if (type === "em_close") {
7453
+ if (cleansEm.has(emIndex) && t.markup === "_") {
7454
+ t.type = "text";
7455
+ t.content = t.markup;
7456
+ t.raw = String(t.markup ?? "");
7457
+ t.tag = "";
7458
+ t.markup = "";
7459
+ t.attrs = null;
7460
+ t.map = null;
7461
+ t.info = "";
7462
+ t.meta = null;
7463
+ }
7464
+ emIndex--;
7465
+ if (emIndex < 0) emIndex = 0;
7466
+ }
7467
+ }
7468
+ if (tokens.length < 5) return tokens;
7176
7469
  const i = tokens.length - 4;
7177
7470
  const token = tokens[i];
7178
- if (!token) return fixedTokens;
7471
+ const fixedTokens = [...tokens];
7179
7472
  const nextToken = tokens[i + 1];
7180
7473
  const tokenContent = String(token.content ?? "");
7181
7474
  if (token.type === "link_open" && tokens[i - 1]?.type === "em_open" && tokens[i - 2]?.type === "text" && tokens[i - 2].content?.endsWith("*")) {
@@ -7190,7 +7483,8 @@ function fixStrongTokens(tokens) {
7190
7483
  content: "",
7191
7484
  markup: "**",
7192
7485
  info: "",
7193
- meta: null
7486
+ meta: null,
7487
+ raw: ""
7194
7488
  },
7195
7489
  tokens[i],
7196
7490
  tokens[i + 1],
@@ -7204,7 +7498,8 @@ function fixStrongTokens(tokens) {
7204
7498
  content: "",
7205
7499
  markup: "**",
7206
7500
  info: "",
7207
- meta: null
7501
+ meta: null,
7502
+ raw: ""
7208
7503
  }
7209
7504
  ];
7210
7505
  if (textContent) replaceTokens.unshift({
@@ -7226,11 +7521,13 @@ function fixStrongTokens(tokens) {
7226
7521
  content: "",
7227
7522
  markup: "**",
7228
7523
  info: "",
7229
- meta: null
7524
+ meta: null,
7525
+ raw: ""
7230
7526
  },
7231
7527
  {
7232
7528
  type: "text",
7233
- content: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : ""
7529
+ content: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : "",
7530
+ raw: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : ""
7234
7531
  },
7235
7532
  {
7236
7533
  type: "strong_close",
@@ -7241,7 +7538,8 @@ function fixStrongTokens(tokens) {
7241
7538
  content: "",
7242
7539
  markup: "**",
7243
7540
  info: "",
7244
- meta: null
7541
+ meta: null,
7542
+ raw: ""
7245
7543
  }
7246
7544
  ];
7247
7545
  const beforeText = tokenContent.slice(0, -1);
@@ -7458,7 +7756,6 @@ var findMatchingClose_default = findMatchingClose;
7458
7756
  //#endregion
7459
7757
  //#region src/plugins/isMathLike.ts
7460
7758
  const TEX_BRACE_COMMANDS = [
7461
- "mathbf",
7462
7759
  "boldsymbol",
7463
7760
  "mathbb",
7464
7761
  "mathcal",
@@ -7483,7 +7780,7 @@ const PREFIX_CLASS = "(?:\\\\|\\u0008)";
7483
7780
  const TEX_CMD_WITH_BRACES_RE = new RegExp(`${PREFIX_CLASS}(?:${ESCAPED_TEX_BRACE_COMMANDS})\\s*\\{[^}]+\\}`, "i");
7484
7781
  const TEX_BRACE_CMD_START_RE = new RegExp(`(?:${PREFIX_CLASS})?(?:${ESCAPED_TEX_BRACE_COMMANDS})\s*\{`, "i");
7485
7782
  const TEX_SPECIFIC_RE = /\\(?:text|frac|left|right|times)/;
7486
- const OPS_RE = /* @__PURE__ */ new RegExp("(?<!\\+)\\+(?!\\+)|[=\\-*/^<>]|\\\\times|\\\\pm|\\\\cdot|\\\\le|\\\\ge|\\\\neq");
7783
+ const OPS_RE = /* @__PURE__ */ new RegExp("(?:^|[^+])\\+(?!\\+)|[=\\-*/^<>]|\\\\times|\\\\pm|\\\\cdot|\\\\le|\\\\ge|\\\\neq");
7487
7784
  const HYPHENATED_MULTIWORD_RE = /\b[A-Z]{2,}-[A-Z]{2,}\b/i;
7488
7785
  const FUNC_CALL_RE = /[A-Z]+\s*\([^)]+\)/i;
7489
7786
  const WORDS_RE = /\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/;
@@ -7495,7 +7792,6 @@ function isMathLike(s) {
7495
7792
  if (DATE_TIME_RE.test(stripped)) return false;
7496
7793
  if (stripped.includes("**")) return false;
7497
7794
  if (stripped.length > 2e3) return true;
7498
- if (/[./]\s*\D|\D\s*[./]/.test(s)) return false;
7499
7795
  const texCmd = TEX_CMD_RE.test(norm);
7500
7796
  const texCmdWithBraces = TEX_CMD_WITH_BRACES_RE.test(norm);
7501
7797
  const texBraceStart = TEX_BRACE_CMD_START_RE.test(norm);
@@ -7504,7 +7800,7 @@ function isMathLike(s) {
7504
7800
  const ops = OPS_RE.test(norm) && !HYPHENATED_MULTIWORD_RE.test(norm);
7505
7801
  const funcCall = FUNC_CALL_RE.test(norm);
7506
7802
  const words = WORDS_RE.test(norm);
7507
- const pureWord = /^\([a-z]\)$/i.test(stripped) || /^[a-z]$/i.test(stripped);
7803
+ const pureWord = /^\([a-z]\)$/i.test(stripped) || /^(?:[a-z]|pi)$/i.test(stripped);
7508
7804
  const chemicalLike = /^(?:[A-Z][a-z]?(?:_\{?\d+\}?|\^\{?\d+\}?)?)+$/.test(stripped);
7509
7805
  return texCmd || texCmdWithBraces || texBraceStart || texSpecific || superSub || ops || funcCall || words || pureWord || chemicalLike;
7510
7806
  }
@@ -7516,6 +7812,12 @@ const KATEX_COMMANDS = [
7516
7812
  "cdots",
7517
7813
  "quad",
7518
7814
  "in",
7815
+ "displaystyle",
7816
+ "int_",
7817
+ "lim",
7818
+ "lim_",
7819
+ "ce",
7820
+ "pu",
7519
7821
  "end",
7520
7822
  "infty",
7521
7823
  "perp",
@@ -7526,11 +7828,11 @@ const KATEX_COMMANDS = [
7526
7828
  "leftarrow",
7527
7829
  "math",
7528
7830
  "mathrm",
7529
- "mathbf",
7530
7831
  "mathit",
7531
7832
  "mathbb",
7532
7833
  "mathcal",
7533
7834
  "mathfrak",
7835
+ "implies",
7534
7836
  "alpha",
7535
7837
  "beta",
7536
7838
  "gamma",
@@ -7538,8 +7840,8 @@ const KATEX_COMMANDS = [
7538
7840
  "epsilon",
7539
7841
  "lambda",
7540
7842
  "sum",
7843
+ "sum_",
7541
7844
  "prod",
7542
- "int",
7543
7845
  "sqrt",
7544
7846
  "fbox",
7545
7847
  "boxed",
@@ -7561,19 +7863,25 @@ const KATEX_COMMANDS = [
7561
7863
  "log",
7562
7864
  "ln",
7563
7865
  "exp",
7564
- "lim",
7565
7866
  "frac",
7566
7867
  "text",
7567
7868
  "left",
7568
7869
  "right"
7569
7870
  ];
7871
+ const ANY_COMMANDS = [
7872
+ "cdot",
7873
+ "mathbf{",
7874
+ "partial",
7875
+ "mu_{"
7876
+ ];
7570
7877
  const ESCAPED_KATEX_COMMANDS = KATEX_COMMANDS.slice().sort((a, b) => b.length - a.length).map((c) => c.replace(/[.*+?^${}()|[\\]\\\]/g, "\\$&")).join("|");
7571
7878
  const CONTROL_CHARS_CLASS = "[ \r\b\f\v]";
7879
+ const ESCAPED_MKATWX_COMMANDS = new RegExp(`([^\\\\])(${ANY_COMMANDS.map((c) => c).join("|")})+`, "g");
7572
7880
  const SPAN_CURLY_RE = /span\{([^}]+)\}/;
7573
7881
  const OPERATORNAME_SPAN_RE = /\\operatorname\{span\}\{((?:[^{}]|\{[^}]*\})+)\}/;
7574
7882
  const SINGLE_BACKSLASH_NEWLINE_RE = /(^|[^\\])\\\r?\n/g;
7575
7883
  const ENDING_SINGLE_BACKSLASH_RE = /(^|[^\\])\\$/g;
7576
- const DEFAULT_MATH_RE = new RegExp(`${CONTROL_CHARS_CLASS}|(?<!\\\\|\\w)(${ESCAPED_KATEX_COMMANDS})\\b`, "g");
7884
+ const DEFAULT_MATH_RE = new RegExp(`(${CONTROL_CHARS_CLASS})|(${ESCAPED_KATEX_COMMANDS})\\b`, "g");
7577
7885
  const MATH_RE_CACHE = /* @__PURE__ */ new Map();
7578
7886
  const BRACE_CMD_RE_CACHE = /* @__PURE__ */ new Map();
7579
7887
  function getMathRegex(commands) {
@@ -7584,7 +7892,7 @@ function getMathRegex(commands) {
7584
7892
  const cached = MATH_RE_CACHE.get(key);
7585
7893
  if (cached) return cached;
7586
7894
  const commandPattern = `(?:${arr.map((c) => c.replace(/[.*+?^${}()|[\\]\\"\]/g, "\\$&")).join("|")})`;
7587
- const re = new RegExp(`${CONTROL_CHARS_CLASS}|(?<!\\\\|\\w)(${commandPattern})\\b`, "g");
7895
+ const re = new RegExp(`(${CONTROL_CHARS_CLASS})|(${commandPattern})\\b`, "g");
7588
7896
  MATH_RE_CACHE.set(key, re);
7589
7897
  return re;
7590
7898
  }
@@ -7617,9 +7925,13 @@ function normalizeStandaloneBackslashT(s, opts) {
7617
7925
  const escapeExclamation = opts?.escapeExclamation ?? true;
7618
7926
  const useDefault = opts?.commands == null;
7619
7927
  const re = getMathRegex(useDefault ? void 0 : commands);
7620
- let out = s.replace(re, (m, cmd) => {
7621
- if (CONTROL_MAP[m] !== void 0) return `\\${CONTROL_MAP[m]}`;
7622
- if (cmd && commands.includes(cmd)) return `\\${cmd}`;
7928
+ let out = s.replace(re, (m, control, cmd, offset, str) => {
7929
+ if (control !== void 0 && CONTROL_MAP[control] !== void 0) return `\\${CONTROL_MAP[control]}`;
7930
+ if (cmd && commands.includes(cmd)) {
7931
+ const prev = str && typeof offset === "number" ? str[offset - 1] : void 0;
7932
+ if (prev === "\\" || prev && /\w/.test(prev)) return m;
7933
+ return `\\${cmd}`;
7934
+ }
7623
7935
  return m;
7624
7936
  });
7625
7937
  if (escapeExclamation) out = out.replace(/(^|[^\\])!/g, "$1\\!");
@@ -7629,6 +7941,7 @@ function normalizeStandaloneBackslashT(s, opts) {
7629
7941
  result = result.replace(SPAN_CURLY_RE, "span\\{$1\\}").replace(OPERATORNAME_SPAN_RE, "\\operatorname{span}\\{$1\\}");
7630
7942
  result = result.replace(SINGLE_BACKSLASH_NEWLINE_RE, "$1\\\\\n");
7631
7943
  result = result.replace(ENDING_SINGLE_BACKSLASH_RE, "$1\\\\");
7944
+ result = result.replace(ESCAPED_MKATWX_COMMANDS, "$1\\$2");
7632
7945
  return result;
7633
7946
  }
7634
7947
  function applyMath(md, mathOpts) {
@@ -7756,13 +8069,11 @@ function applyMath(md, mathOpts) {
7756
8069
  const isBeforeClose = raw.startsWith("*");
7757
8070
  if (isBeforeClose) s.push("strong_close", "", 0);
7758
8071
  if (raw) {
7759
- const textContentToken = s.push("text", "", 0);
7760
- textContentToken.content = (raw == null ? "" : String(raw)).replace(/^\*+/, "");
8072
+ s.pos = endIdx + close.length;
8073
+ searchPos = s.pos;
8074
+ preMathPos = searchPos;
7761
8075
  }
7762
8076
  if (!isBeforeClose) s.push("strong_close", "", 0);
7763
- s.pos = src.length;
7764
- searchPos = src.length;
7765
- preMathPos = searchPos;
7766
8077
  continue;
7767
8078
  } else {
7768
8079
  const token = s.push("math_inline", "math", 0);
@@ -7795,11 +8106,12 @@ function applyMath(md, mathOpts) {
7795
8106
  ["$$", "$$"]
7796
8107
  ];
7797
8108
  const startPos = s.bMarks[startLine] + s.tShift[startLine];
7798
- const lineText = s.src.slice(startPos, s.eMarks[startLine]).trim();
8109
+ let lineText = s.src.slice(startPos, s.eMarks[startLine]).trim();
7799
8110
  let matched = false;
7800
8111
  let openDelim = "";
7801
8112
  let closeDelim = "";
7802
- for (const [open, close] of delimiters) if (lineText.startsWith(open)) if (open.includes("[")) {
8113
+ let skipFirstLine = false;
8114
+ for (const [open, close] of delimiters) if (lineText.startsWith(open)) if (open.includes("[")) if (mathOpts?.strictDelimiters) {
7803
8115
  if (lineText.replace("\\", "") === "[") {
7804
8116
  if (startLine + 1 < endLine) {
7805
8117
  matched = true;
@@ -7809,12 +8121,47 @@ function applyMath(md, mathOpts) {
7809
8121
  }
7810
8122
  continue;
7811
8123
  }
8124
+ } else if (lineText.replace("\\", "") === "[") {
8125
+ if (startLine + 1 < endLine) {
8126
+ matched = true;
8127
+ openDelim = open;
8128
+ closeDelim = close;
8129
+ break;
8130
+ }
8131
+ continue;
7812
8132
  } else {
8133
+ const lastToken = s.tokens[s.tokens.length - 1];
8134
+ if (lastToken && lastToken.type === "list_item_open" && lastToken.mark === "-" && lineText.slice(open.length, lineText.indexOf("]")).trim() === "x") continue;
8135
+ if (lineText.replace("\\", "").startsWith("[") && !lineText.includes("](")) {
8136
+ const closeIndex = lineText.indexOf("]");
8137
+ if (lineText.slice(closeIndex).trim() !== "]") continue;
8138
+ if (isMathLike(lineText.slice(open.length, closeIndex))) {
8139
+ matched = true;
8140
+ openDelim = open;
8141
+ closeDelim = close;
8142
+ break;
8143
+ }
8144
+ continue;
8145
+ }
8146
+ }
8147
+ else {
7813
8148
  matched = true;
7814
8149
  openDelim = open;
7815
8150
  closeDelim = close;
7816
8151
  break;
7817
8152
  }
8153
+ else if (lineText.endsWith(open) && !lineText.slice(0, lineText.length - open.length).trim().includes(open) && startLine + 1 < endLine) {
8154
+ s.push("text", "", 0).content = lineText.slice(0, lineText.length - open.length);
8155
+ const nextLineStartPos = s.bMarks[startLine + 1] + s.tShift[startLine + 1];
8156
+ lineText = s.src.slice(nextLineStartPos, s.eMarks[startLine + 1]).trim();
8157
+ if (open === "$$") {
8158
+ skipFirstLine = true;
8159
+ matched = true;
8160
+ openDelim = open;
8161
+ closeDelim = close;
8162
+ break;
8163
+ }
8164
+ }
7818
8165
  if (!matched) return false;
7819
8166
  if (silent) return true;
7820
8167
  if (lineText.includes(closeDelim) && lineText.indexOf(closeDelim) > openDelim.length) {
@@ -7841,7 +8188,7 @@ function applyMath(md, mathOpts) {
7841
8188
  found = true;
7842
8189
  nextLine = startLine;
7843
8190
  } else {
7844
- if (firstLineContent) content = firstLineContent;
8191
+ if (firstLineContent && !skipFirstLine) content = firstLineContent;
7845
8192
  for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
7846
8193
  const lineStart = s.bMarks[nextLine] + s.tShift[nextLine];
7847
8194
  const lineEnd = s.eMarks[nextLine];
@@ -7859,6 +8206,7 @@ function applyMath(md, mathOpts) {
7859
8206
  }
7860
8207
  }
7861
8208
  if (strict && !found) return false;
8209
+ if (!isMathLike(content)) return false;
7862
8210
  const token = s.push("math_block", "math", 0);
7863
8211
  token.content = normalizeStandaloneBackslashT(content);
7864
8212
  token.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]";
@@ -7913,7 +8261,6 @@ function factory(opts = {}) {
7913
8261
  ...opts.mathOptions ?? {}
7914
8262
  });
7915
8263
  if (opts.enableContainers ?? true) applyContainers(md);
7916
- applyFixLinkInline(md);
7917
8264
  applyFixLinkTokens(md);
7918
8265
  applyFixStrongTokens(md);
7919
8266
  applyFixListItem(md);
@@ -8405,10 +8752,6 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8405
8752
  if (!tokens || tokens.length === 0) return [];
8406
8753
  const result = [];
8407
8754
  let currentTextNode = null;
8408
- const hasSuspiciousCodeInline = tokens.some((t) => t.type === "code_inline" && /[^\x00-\x7F]/.test(String(t.content ?? "")));
8409
- const hasBackticksInRaw = typeof raw === "string" && /`/.test(raw);
8410
- const hasMathInlineUsingBackticks = tokens.some((t) => t.type === "math_inline" && /`/.test(String(t.raw ?? t.content ?? "")));
8411
- if (hasBackticksInRaw && (hasSuspiciousCodeInline || hasMathInlineUsingBackticks)) return parseFromRawWithCodeAndStrong(String(raw ?? ""));
8412
8755
  let i = 0;
8413
8756
  const requireClosingStrong = options?.requireClosingStrong;
8414
8757
  function resetCurrentTextNode() {
@@ -8489,7 +8832,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8489
8832
  type: "strong_open",
8490
8833
  tag: "strong",
8491
8834
  content: "",
8492
- markup: "*",
8835
+ markup: "**",
8493
8836
  info: "",
8494
8837
  meta: null
8495
8838
  },
@@ -8505,7 +8848,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8505
8848
  type: "strong_close",
8506
8849
  tag: "strong",
8507
8850
  content: "",
8508
- markup: "*",
8851
+ markup: "**",
8509
8852
  info: "",
8510
8853
  meta: null
8511
8854
  }
@@ -8538,6 +8881,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8538
8881
  };
8539
8882
  result.push(currentTextNode);
8540
8883
  }
8884
+ const closeIndex = content.indexOf("*", idx + 1);
8541
8885
  const { node } = parseEmphasisToken([
8542
8886
  {
8543
8887
  type: "em_open",
@@ -8550,7 +8894,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8550
8894
  {
8551
8895
  type: "text",
8552
8896
  tag: "",
8553
- content: content.slice(idx).replace(/\*/g, ""),
8897
+ content: content.slice(idx, closeIndex > -1 ? closeIndex + 1 : void 0).replace(/\*/g, ""),
8554
8898
  markup: "",
8555
8899
  info: "",
8556
8900
  meta: null
@@ -8564,6 +8908,14 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8564
8908
  meta: null
8565
8909
  }
8566
8910
  ], 0, options);
8911
+ if (closeIndex !== -1 && closeIndex < content.length - 1) {
8912
+ const afterContent = content.slice(closeIndex + 1);
8913
+ if (afterContent) handleToken({
8914
+ type: "text",
8915
+ content: afterContent,
8916
+ raw: afterContent
8917
+ });
8918
+ }
8567
8919
  resetCurrentTextNode();
8568
8920
  pushNode(node);
8569
8921
  i++;
@@ -8785,6 +9137,17 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8785
9137
  pushNode(parseFootnoteRefToken(token));
8786
9138
  i++;
8787
9139
  break;
9140
+ case "footnote_anchor": {
9141
+ resetCurrentTextNode();
9142
+ const meta = token.meta ?? {};
9143
+ pushParsed({
9144
+ type: "footnote_anchor",
9145
+ id: String(meta.label ?? token.content ?? ""),
9146
+ raw: String(token.content ?? "")
9147
+ });
9148
+ i++;
9149
+ break;
9150
+ }
8788
9151
  case "hardbreak":
8789
9152
  resetCurrentTextNode();
8790
9153
  pushNode(parseHardbreakToken());
@@ -8822,7 +9185,6 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8822
9185
  i++;
8823
9186
  return;
8824
9187
  }
8825
- if (content.startsWith(")") && result[result.length - 1]?.type === "link") content = content.slice(1);
8826
9188
  if (Array.from(content.matchAll(/\$/g)).length === 1 && content.endsWith("$")) content = content.slice(0, -1);
8827
9189
  if (content.endsWith("undefined") && !raw?.endsWith("undefined")) content = content.slice(0, -9);
8828
9190
  for (; index >= 0; index--) {
@@ -8920,8 +9282,24 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8920
9282
  });
8921
9283
  i += 1;
8922
9284
  } else {
8923
- pushText(text$1, text$1);
8924
- i += 3;
9285
+ i += 2;
9286
+ while (i < tokens.length && tokens[i].type !== "link_close") {
9287
+ text$1 += String(tokens[i]?.content || "");
9288
+ i++;
9289
+ }
9290
+ const loading = tokens[i].type !== "link_close";
9291
+ pushParsed({
9292
+ type: "link",
9293
+ href: String(hrefAttr$1),
9294
+ title: null,
9295
+ text: text$1,
9296
+ children: [{
9297
+ type: "text",
9298
+ content: text$1,
9299
+ raw: text$1
9300
+ }],
9301
+ loading
9302
+ });
8925
9303
  }
8926
9304
  return;
8927
9305
  }
@@ -9182,78 +9560,6 @@ function normalizeSingleLinkResult(raw, nodes) {
9182
9560
  if (preferred) return [preferred];
9183
9561
  return nodes;
9184
9562
  }
9185
- function parseFromRawWithCodeAndStrong(raw) {
9186
- const root = [];
9187
- const stack = [{
9188
- type: "root",
9189
- children: root
9190
- }];
9191
- let i = 0;
9192
- function cur() {
9193
- return stack[stack.length - 1].children;
9194
- }
9195
- function pushText(s) {
9196
- if (!s) return;
9197
- const last = cur()[cur().length - 1];
9198
- if (last && last.type === "text") {
9199
- last.content += s;
9200
- last.raw += s;
9201
- } else cur().push({
9202
- type: "text",
9203
- content: s,
9204
- raw: s
9205
- });
9206
- }
9207
- while (i < raw.length) {
9208
- if (raw[i] === "*" && raw[i + 1] === "*") {
9209
- const isClosing = stack.length > 1 && stack[stack.length - 1].type === "strong";
9210
- i += 2;
9211
- if (isClosing) {
9212
- const nodeChildren = stack.pop().children;
9213
- cur().push({
9214
- type: "strong",
9215
- children: nodeChildren,
9216
- raw: `**${nodeChildren.map((n) => n.raw ?? "").join("")}**`
9217
- });
9218
- } else stack.push({
9219
- type: "strong",
9220
- children: []
9221
- });
9222
- continue;
9223
- }
9224
- if (raw[i] === "`") {
9225
- let runLen = 1;
9226
- let k = i + 1;
9227
- while (k < raw.length && raw[k] === "`") {
9228
- runLen++;
9229
- k++;
9230
- }
9231
- const closingSeq = "`".repeat(runLen);
9232
- const codeStart = i + runLen;
9233
- const close = raw.indexOf(closingSeq, codeStart);
9234
- if (close === -1) {
9235
- pushText(raw.slice(i));
9236
- break;
9237
- }
9238
- const code$1 = raw.slice(codeStart, close);
9239
- cur().push({
9240
- type: "inline_code",
9241
- code: code$1,
9242
- raw: code$1
9243
- });
9244
- i = close + runLen;
9245
- continue;
9246
- }
9247
- let next = raw.indexOf("`", i);
9248
- const nextStrong = raw.indexOf("**", i);
9249
- if (nextStrong !== -1 && (next === -1 || nextStrong < next)) next = nextStrong;
9250
- if (next === -1) next = raw.length;
9251
- pushText(raw.slice(i, next));
9252
- i = next;
9253
- }
9254
- while (stack.length > 1) pushText(`**${stack.pop().children.map((n) => n.raw ?? n.content ?? "").join("")}`);
9255
- return root;
9256
- }
9257
9563
 
9258
9564
  //#endregion
9259
9565
  //#region src/parser/node-parsers/blockquote-parser.ts
@@ -9347,6 +9653,8 @@ function parseFootnote(tokens, index, options) {
9347
9653
  let j = index + 1;
9348
9654
  while (j < tokens.length && tokens[j].type !== "footnote_close") if (tokens[j].type === "paragraph_open") {
9349
9655
  const contentToken = tokens[j + 1];
9656
+ const children = contentToken.children || [];
9657
+ if (tokens[j + 2].type === "footnote_anchor") children.push(tokens[j + 2]);
9350
9658
  footnoteChildren.push({
9351
9659
  type: "paragraph",
9352
9660
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }),
@@ -9778,7 +10086,7 @@ function parseParagraph(tokens, index, options) {
9778
10086
  //#endregion
9779
10087
  //#region src/parser/index.ts
9780
10088
  function parseMarkdownToStructure(markdown, md, options = {}) {
9781
- let safeMarkdown = (markdown ?? "").toString().replace(/([^\\])\right/g, "$1\\right");
10089
+ let safeMarkdown = (markdown ?? "").toString().replace(/([^\\])\r(ight|ho)/g, "$1\\r$2").replace(/([^\\])\n(abla|eq|ot|exists)/g, "$1\\n$2");
9782
10090
  if (safeMarkdown.endsWith("- *")) safeMarkdown = safeMarkdown.replace(/- \*$/, "- \\*");
9783
10091
  if (/\n\s*-\s*$/.test(safeMarkdown)) safeMarkdown = safeMarkdown.replace(/\n\s*-\s*$/, "\n");
9784
10092
  else if (/\n[[(]\n*$/.test(safeMarkdown)) safeMarkdown = safeMarkdown.replace(/(\n\[|\n\()+\n*$/g, "\n");
@@ -9874,6 +10182,17 @@ function processTokens(tokens, options) {
9874
10182
  i = newIndex;
9875
10183
  break;
9876
10184
  }
10185
+ case "footnote_anchor": {
10186
+ const meta = token.meta ?? {};
10187
+ const id = String(meta.label ?? token.content ?? "");
10188
+ result.push({
10189
+ type: "footnote_anchor",
10190
+ id,
10191
+ raw: String(token.content ?? "")
10192
+ });
10193
+ i++;
10194
+ break;
10195
+ }
9877
10196
  case "container_open": {
9878
10197
  const match = /^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/.exec(String(token.info ?? ""));
9879
10198
  if (match) {