stream-markdown-parser 0.0.31 → 0.0.32

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);
@@ -6568,6 +6806,7 @@ function applyContainers(md) {
6568
6806
  contentLines.push(s.src.slice(sPos, ePos));
6569
6807
  }
6570
6808
  s.push("paragraph_open", "p", 1);
6809
+ debugger;
6571
6810
  const inlineToken = s.push("inline", "", 0);
6572
6811
  inlineToken.content = contentLines.join("\n");
6573
6812
  inlineToken.map = [startLine + 1, nextLine];
@@ -6722,37 +6961,6 @@ function applyFixHtmlInlineTokens(md) {
6722
6961
  });
6723
6962
  }
6724
6963
 
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
6964
  //#endregion
6757
6965
  //#region src/plugins/fixLinkTokens.ts
6758
6966
  function textToken(content) {
@@ -6811,11 +7019,17 @@ function pushEmClose(arr, type) {
6811
7019
  }
6812
7020
  }
6813
7021
  function createLinkToken(text$1, href, loading) {
7022
+ let title = "";
7023
+ if (href.includes("\"")) {
7024
+ const temps = href.split("\"");
7025
+ href = temps[0].trim();
7026
+ title = temps[1].trim();
7027
+ }
6814
7028
  return {
6815
7029
  type: "link",
6816
7030
  loading,
6817
7031
  href,
6818
- title: "",
7032
+ title,
6819
7033
  text: text$1,
6820
7034
  children: [{
6821
7035
  type: "text",
@@ -6972,7 +7186,9 @@ function fixLinkToken(tokens) {
6972
7186
  if (curToken.type === "link_close" && curToken.nesting === -1 && tokens[i + 1]?.type === "text" && tokens[i - 1]?.type === "text") {
6973
7187
  let loading = true;
6974
7188
  const text$1 = tokens[i - 1].content || "";
6975
- let href = tokens[i - 2].attrs?.[0]?.[1] || "";
7189
+ const attrs = tokens[i - 2].attrs || [];
7190
+ let href = attrs.find((a) => a[0] === "href")?.[1] || "";
7191
+ const title = attrs.find((a) => a[0] === "title")?.[1] || "";
6976
7192
  let count = 3;
6977
7193
  let deleteCount = 2;
6978
7194
  const emphasisMatch = (tokens[i - 3]?.content || "").match(/^(\*+)$/);
@@ -6988,8 +7204,8 @@ function fixLinkToken(tokens) {
6988
7204
  if (m === -1) {
6989
7205
  href += tokens[i + 1]?.content?.slice(0, m) || "";
6990
7206
  tokens[i + 1].content = "";
7207
+ count += 1;
6991
7208
  } else loading = false;
6992
- count += 1;
6993
7209
  } else if (tokens[i + 1].type === "text" && tokens[i + 1]?.content?.startsWith("](")) {
6994
7210
  count += 1;
6995
7211
  for (let j = i + 1; j < tokens.length; j++) {
@@ -7009,12 +7225,12 @@ function fixLinkToken(tokens) {
7009
7225
  }
7010
7226
  count += 1;
7011
7227
  }
7012
- }
7228
+ } else loading = false;
7013
7229
  replacerTokens.push({
7014
7230
  type: "link",
7015
7231
  loading,
7016
7232
  href,
7017
- title: "",
7233
+ title,
7018
7234
  text: text$1,
7019
7235
  children: [{
7020
7236
  type: "text",
@@ -7171,11 +7387,89 @@ function applyFixStrongTokens(md) {
7171
7387
  });
7172
7388
  }
7173
7389
  function fixStrongTokens(tokens) {
7174
- const fixedTokens = [...tokens];
7175
- if (tokens.length < 4) return fixedTokens;
7390
+ let strongIndex = 0;
7391
+ const cleansStrong = /* @__PURE__ */ new Set();
7392
+ const cleansEm = /* @__PURE__ */ new Set();
7393
+ let emIndex = 0;
7394
+ for (let i$1 = 0; i$1 < tokens.length; i$1++) {
7395
+ const t = tokens[i$1];
7396
+ const type = t.type;
7397
+ if (type === "strong_open") {
7398
+ strongIndex++;
7399
+ const markup = String(t.markup ?? "");
7400
+ let j = i$1 - 1;
7401
+ while (j >= 0 && tokens[j].type === "text" && tokens[j].content === "") j--;
7402
+ const preToken = tokens[j];
7403
+ let k = i$1 + 1;
7404
+ while (k < tokens.length && tokens[k].type === "text" && tokens[k].content === "") k++;
7405
+ const postToken = tokens[k];
7406
+ if (markup === "__" && (preToken?.content?.endsWith("_") || postToken?.content?.startsWith("_") || postToken?.markup?.includes("_"))) {
7407
+ t.type = "text";
7408
+ t.tag = "";
7409
+ t.content = markup;
7410
+ t.raw = markup;
7411
+ t.markup = "";
7412
+ t.attrs = null;
7413
+ t.map = null;
7414
+ t.info = "";
7415
+ t.meta = null;
7416
+ cleansStrong.add(strongIndex);
7417
+ }
7418
+ } else if (type === "strong_close") {
7419
+ if (cleansStrong.has(strongIndex) && t.markup === "__") {
7420
+ t.type = "text";
7421
+ t.content = t.markup;
7422
+ t.raw = String(t.markup ?? "");
7423
+ t.tag = "";
7424
+ t.markup = "";
7425
+ t.attrs = null;
7426
+ t.map = null;
7427
+ t.info = "";
7428
+ t.meta = null;
7429
+ }
7430
+ strongIndex--;
7431
+ if (strongIndex < 0) strongIndex = 0;
7432
+ } else if (type === "em_open") {
7433
+ emIndex++;
7434
+ const markup = String(t.markup ?? "");
7435
+ let j = i$1 - 1;
7436
+ while (j >= 0 && tokens[j].type === "text" && tokens[j].content === "") j--;
7437
+ const preToken = tokens[j];
7438
+ let k = i$1 + 1;
7439
+ while (k < tokens.length && tokens[k].type === "text" && tokens[k].content === "") k++;
7440
+ const postToken = tokens[k];
7441
+ if (markup === "_" && (preToken?.content?.endsWith("_") || postToken?.content?.startsWith("_") || postToken?.markup?.includes("_"))) {
7442
+ t.type = "text";
7443
+ t.tag = "";
7444
+ t.content = markup;
7445
+ t.raw = markup;
7446
+ t.markup = "";
7447
+ t.attrs = null;
7448
+ t.map = null;
7449
+ t.info = "";
7450
+ t.meta = null;
7451
+ cleansEm.add(emIndex);
7452
+ }
7453
+ } else if (type === "em_close") {
7454
+ if (cleansEm.has(emIndex) && t.markup === "_") {
7455
+ t.type = "text";
7456
+ t.content = t.markup;
7457
+ t.raw = String(t.markup ?? "");
7458
+ t.tag = "";
7459
+ t.markup = "";
7460
+ t.attrs = null;
7461
+ t.map = null;
7462
+ t.info = "";
7463
+ t.meta = null;
7464
+ }
7465
+ emIndex--;
7466
+ if (emIndex < 0) emIndex = 0;
7467
+ }
7468
+ }
7469
+ if (tokens.length < 5) return tokens;
7176
7470
  const i = tokens.length - 4;
7177
7471
  const token = tokens[i];
7178
- if (!token) return fixedTokens;
7472
+ const fixedTokens = [...tokens];
7179
7473
  const nextToken = tokens[i + 1];
7180
7474
  const tokenContent = String(token.content ?? "");
7181
7475
  if (token.type === "link_open" && tokens[i - 1]?.type === "em_open" && tokens[i - 2]?.type === "text" && tokens[i - 2].content?.endsWith("*")) {
@@ -7190,7 +7484,8 @@ function fixStrongTokens(tokens) {
7190
7484
  content: "",
7191
7485
  markup: "**",
7192
7486
  info: "",
7193
- meta: null
7487
+ meta: null,
7488
+ raw: ""
7194
7489
  },
7195
7490
  tokens[i],
7196
7491
  tokens[i + 1],
@@ -7204,7 +7499,8 @@ function fixStrongTokens(tokens) {
7204
7499
  content: "",
7205
7500
  markup: "**",
7206
7501
  info: "",
7207
- meta: null
7502
+ meta: null,
7503
+ raw: ""
7208
7504
  }
7209
7505
  ];
7210
7506
  if (textContent) replaceTokens.unshift({
@@ -7226,11 +7522,13 @@ function fixStrongTokens(tokens) {
7226
7522
  content: "",
7227
7523
  markup: "**",
7228
7524
  info: "",
7229
- meta: null
7525
+ meta: null,
7526
+ raw: ""
7230
7527
  },
7231
7528
  {
7232
7529
  type: "text",
7233
- content: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : ""
7530
+ content: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : "",
7531
+ raw: _nextToken?.type === "text" ? String(_nextToken.content ?? "") : ""
7234
7532
  },
7235
7533
  {
7236
7534
  type: "strong_close",
@@ -7241,7 +7539,8 @@ function fixStrongTokens(tokens) {
7241
7539
  content: "",
7242
7540
  markup: "**",
7243
7541
  info: "",
7244
- meta: null
7542
+ meta: null,
7543
+ raw: ""
7245
7544
  }
7246
7545
  ];
7247
7546
  const beforeText = tokenContent.slice(0, -1);
@@ -7458,7 +7757,6 @@ var findMatchingClose_default = findMatchingClose;
7458
7757
  //#endregion
7459
7758
  //#region src/plugins/isMathLike.ts
7460
7759
  const TEX_BRACE_COMMANDS = [
7461
- "mathbf",
7462
7760
  "boldsymbol",
7463
7761
  "mathbb",
7464
7762
  "mathcal",
@@ -7483,7 +7781,7 @@ const PREFIX_CLASS = "(?:\\\\|\\u0008)";
7483
7781
  const TEX_CMD_WITH_BRACES_RE = new RegExp(`${PREFIX_CLASS}(?:${ESCAPED_TEX_BRACE_COMMANDS})\\s*\\{[^}]+\\}`, "i");
7484
7782
  const TEX_BRACE_CMD_START_RE = new RegExp(`(?:${PREFIX_CLASS})?(?:${ESCAPED_TEX_BRACE_COMMANDS})\s*\{`, "i");
7485
7783
  const TEX_SPECIFIC_RE = /\\(?:text|frac|left|right|times)/;
7486
- const OPS_RE = /* @__PURE__ */ new RegExp("(?<!\\+)\\+(?!\\+)|[=\\-*/^<>]|\\\\times|\\\\pm|\\\\cdot|\\\\le|\\\\ge|\\\\neq");
7784
+ const OPS_RE = /* @__PURE__ */ new RegExp("(?:^|[^+])\\+(?!\\+)|[=\\-*/^<>]|\\\\times|\\\\pm|\\\\cdot|\\\\le|\\\\ge|\\\\neq");
7487
7785
  const HYPHENATED_MULTIWORD_RE = /\b[A-Z]{2,}-[A-Z]{2,}\b/i;
7488
7786
  const FUNC_CALL_RE = /[A-Z]+\s*\([^)]+\)/i;
7489
7787
  const WORDS_RE = /\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/;
@@ -7495,7 +7793,6 @@ function isMathLike(s) {
7495
7793
  if (DATE_TIME_RE.test(stripped)) return false;
7496
7794
  if (stripped.includes("**")) return false;
7497
7795
  if (stripped.length > 2e3) return true;
7498
- if (/[./]\s*\D|\D\s*[./]/.test(s)) return false;
7499
7796
  const texCmd = TEX_CMD_RE.test(norm);
7500
7797
  const texCmdWithBraces = TEX_CMD_WITH_BRACES_RE.test(norm);
7501
7798
  const texBraceStart = TEX_BRACE_CMD_START_RE.test(norm);
@@ -7504,7 +7801,7 @@ function isMathLike(s) {
7504
7801
  const ops = OPS_RE.test(norm) && !HYPHENATED_MULTIWORD_RE.test(norm);
7505
7802
  const funcCall = FUNC_CALL_RE.test(norm);
7506
7803
  const words = WORDS_RE.test(norm);
7507
- const pureWord = /^\([a-z]\)$/i.test(stripped) || /^[a-z]$/i.test(stripped);
7804
+ const pureWord = /^\([a-z]\)$/i.test(stripped) || /^(?:[a-z]|pi)$/i.test(stripped);
7508
7805
  const chemicalLike = /^(?:[A-Z][a-z]?(?:_\{?\d+\}?|\^\{?\d+\}?)?)+$/.test(stripped);
7509
7806
  return texCmd || texCmdWithBraces || texBraceStart || texSpecific || superSub || ops || funcCall || words || pureWord || chemicalLike;
7510
7807
  }
@@ -7516,6 +7813,12 @@ const KATEX_COMMANDS = [
7516
7813
  "cdots",
7517
7814
  "quad",
7518
7815
  "in",
7816
+ "displaystyle",
7817
+ "int_",
7818
+ "lim",
7819
+ "lim_",
7820
+ "ce",
7821
+ "pu",
7519
7822
  "end",
7520
7823
  "infty",
7521
7824
  "perp",
@@ -7526,7 +7829,6 @@ const KATEX_COMMANDS = [
7526
7829
  "leftarrow",
7527
7830
  "math",
7528
7831
  "mathrm",
7529
- "mathbf",
7530
7832
  "mathit",
7531
7833
  "mathbb",
7532
7834
  "mathcal",
@@ -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) {
@@ -7795,11 +8108,12 @@ function applyMath(md, mathOpts) {
7795
8108
  ["$$", "$$"]
7796
8109
  ];
7797
8110
  const startPos = s.bMarks[startLine] + s.tShift[startLine];
7798
- const lineText = s.src.slice(startPos, s.eMarks[startLine]).trim();
8111
+ let lineText = s.src.slice(startPos, s.eMarks[startLine]).trim();
7799
8112
  let matched = false;
7800
8113
  let openDelim = "";
7801
8114
  let closeDelim = "";
7802
- for (const [open, close] of delimiters) if (lineText.startsWith(open)) if (open.includes("[")) {
8115
+ let skipFirstLine = false;
8116
+ for (const [open, close] of delimiters) if (lineText.startsWith(open)) if (open.includes("[")) if (mathOpts?.strictDelimiters) {
7803
8117
  if (lineText.replace("\\", "") === "[") {
7804
8118
  if (startLine + 1 < endLine) {
7805
8119
  matched = true;
@@ -7809,12 +8123,47 @@ function applyMath(md, mathOpts) {
7809
8123
  }
7810
8124
  continue;
7811
8125
  }
8126
+ } else if (lineText.replace("\\", "") === "[") {
8127
+ if (startLine + 1 < endLine) {
8128
+ matched = true;
8129
+ openDelim = open;
8130
+ closeDelim = close;
8131
+ break;
8132
+ }
8133
+ continue;
7812
8134
  } else {
8135
+ const lastToken = s.tokens[s.tokens.length - 1];
8136
+ if (lastToken && lastToken.type === "list_item_open" && lastToken.mark === "-" && lineText.slice(open.length, lineText.indexOf("]")).trim() === "x") continue;
8137
+ if (lineText.replace("\\", "").startsWith("[") && !lineText.includes("](")) {
8138
+ const closeIndex = lineText.indexOf("]");
8139
+ if (lineText.slice(closeIndex).trim() !== "]") continue;
8140
+ if (isMathLike(lineText.slice(open.length, closeIndex))) {
8141
+ matched = true;
8142
+ openDelim = open;
8143
+ closeDelim = close;
8144
+ break;
8145
+ }
8146
+ continue;
8147
+ }
8148
+ }
8149
+ else {
7813
8150
  matched = true;
7814
8151
  openDelim = open;
7815
8152
  closeDelim = close;
7816
8153
  break;
7817
8154
  }
8155
+ else if (lineText.endsWith(open) && !lineText.slice(0, lineText.length - open.length).trim().includes(open) && startLine + 1 < endLine) {
8156
+ s.push("text", "", 0).content = lineText.slice(0, lineText.length - open.length);
8157
+ const nextLineStartPos = s.bMarks[startLine + 1] + s.tShift[startLine + 1];
8158
+ lineText = s.src.slice(nextLineStartPos, s.eMarks[startLine + 1]).trim();
8159
+ if (open === "$$") {
8160
+ skipFirstLine = true;
8161
+ matched = true;
8162
+ openDelim = open;
8163
+ closeDelim = close;
8164
+ break;
8165
+ }
8166
+ }
7818
8167
  if (!matched) return false;
7819
8168
  if (silent) return true;
7820
8169
  if (lineText.includes(closeDelim) && lineText.indexOf(closeDelim) > openDelim.length) {
@@ -7841,7 +8190,7 @@ function applyMath(md, mathOpts) {
7841
8190
  found = true;
7842
8191
  nextLine = startLine;
7843
8192
  } else {
7844
- if (firstLineContent) content = firstLineContent;
8193
+ if (firstLineContent && !skipFirstLine) content = firstLineContent;
7845
8194
  for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
7846
8195
  const lineStart = s.bMarks[nextLine] + s.tShift[nextLine];
7847
8196
  const lineEnd = s.eMarks[nextLine];
@@ -7859,6 +8208,7 @@ function applyMath(md, mathOpts) {
7859
8208
  }
7860
8209
  }
7861
8210
  if (strict && !found) return false;
8211
+ if (!isMathLike(content)) return false;
7862
8212
  const token = s.push("math_block", "math", 0);
7863
8213
  token.content = normalizeStandaloneBackslashT(content);
7864
8214
  token.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]";
@@ -7913,7 +8263,6 @@ function factory(opts = {}) {
7913
8263
  ...opts.mathOptions ?? {}
7914
8264
  });
7915
8265
  if (opts.enableContainers ?? true) applyContainers(md);
7916
- applyFixLinkInline(md);
7917
8266
  applyFixLinkTokens(md);
7918
8267
  applyFixStrongTokens(md);
7919
8268
  applyFixListItem(md);
@@ -8405,10 +8754,6 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8405
8754
  if (!tokens || tokens.length === 0) return [];
8406
8755
  const result = [];
8407
8756
  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
8757
  let i = 0;
8413
8758
  const requireClosingStrong = options?.requireClosingStrong;
8414
8759
  function resetCurrentTextNode() {
@@ -8489,7 +8834,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8489
8834
  type: "strong_open",
8490
8835
  tag: "strong",
8491
8836
  content: "",
8492
- markup: "*",
8837
+ markup: "**",
8493
8838
  info: "",
8494
8839
  meta: null
8495
8840
  },
@@ -8505,7 +8850,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8505
8850
  type: "strong_close",
8506
8851
  tag: "strong",
8507
8852
  content: "",
8508
- markup: "*",
8853
+ markup: "**",
8509
8854
  info: "",
8510
8855
  meta: null
8511
8856
  }
@@ -8538,6 +8883,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8538
8883
  };
8539
8884
  result.push(currentTextNode);
8540
8885
  }
8886
+ const closeIndex = content.indexOf("*", idx + 1);
8541
8887
  const { node } = parseEmphasisToken([
8542
8888
  {
8543
8889
  type: "em_open",
@@ -8550,7 +8896,7 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8550
8896
  {
8551
8897
  type: "text",
8552
8898
  tag: "",
8553
- content: content.slice(idx).replace(/\*/g, ""),
8899
+ content: content.slice(idx, closeIndex > -1 ? closeIndex + 1 : void 0).replace(/\*/g, ""),
8554
8900
  markup: "",
8555
8901
  info: "",
8556
8902
  meta: null
@@ -8564,6 +8910,14 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8564
8910
  meta: null
8565
8911
  }
8566
8912
  ], 0, options);
8913
+ if (closeIndex !== -1 && closeIndex < content.length - 1) {
8914
+ const afterContent = content.slice(closeIndex + 1);
8915
+ if (afterContent) handleToken({
8916
+ type: "text",
8917
+ content: afterContent,
8918
+ raw: afterContent
8919
+ });
8920
+ }
8567
8921
  resetCurrentTextNode();
8568
8922
  pushNode(node);
8569
8923
  i++;
@@ -8785,6 +9139,16 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8785
9139
  pushNode(parseFootnoteRefToken(token));
8786
9140
  i++;
8787
9141
  break;
9142
+ case "footnote_anchor":
9143
+ resetCurrentTextNode();
9144
+ const meta = token.meta ?? {};
9145
+ pushParsed({
9146
+ type: "footnote_anchor",
9147
+ id: String(meta.label ?? token.content ?? ""),
9148
+ raw: String(token.content ?? "")
9149
+ });
9150
+ i++;
9151
+ break;
8788
9152
  case "hardbreak":
8789
9153
  resetCurrentTextNode();
8790
9154
  pushNode(parseHardbreakToken());
@@ -8822,7 +9186,6 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8822
9186
  i++;
8823
9187
  return;
8824
9188
  }
8825
- if (content.startsWith(")") && result[result.length - 1]?.type === "link") content = content.slice(1);
8826
9189
  if (Array.from(content.matchAll(/\$/g)).length === 1 && content.endsWith("$")) content = content.slice(0, -1);
8827
9190
  if (content.endsWith("undefined") && !raw?.endsWith("undefined")) content = content.slice(0, -9);
8828
9191
  for (; index >= 0; index--) {
@@ -8920,8 +9283,24 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
8920
9283
  });
8921
9284
  i += 1;
8922
9285
  } else {
8923
- pushText(text$1, text$1);
8924
- i += 3;
9286
+ i += 2;
9287
+ while (i < tokens.length && tokens[i].type !== "link_close") {
9288
+ text$1 += String(tokens[i]?.content || "");
9289
+ i++;
9290
+ }
9291
+ let loading = tokens[i].type !== "link_close";
9292
+ pushParsed({
9293
+ type: "link",
9294
+ href: String(hrefAttr$1),
9295
+ title: null,
9296
+ text: text$1,
9297
+ children: [{
9298
+ type: "text",
9299
+ content: text$1,
9300
+ raw: text$1
9301
+ }],
9302
+ loading
9303
+ });
8925
9304
  }
8926
9305
  return;
8927
9306
  }
@@ -9182,78 +9561,6 @@ function normalizeSingleLinkResult(raw, nodes) {
9182
9561
  if (preferred) return [preferred];
9183
9562
  return nodes;
9184
9563
  }
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
9564
 
9258
9565
  //#endregion
9259
9566
  //#region src/parser/node-parsers/blockquote-parser.ts
@@ -9347,6 +9654,8 @@ function parseFootnote(tokens, index, options) {
9347
9654
  let j = index + 1;
9348
9655
  while (j < tokens.length && tokens[j].type !== "footnote_close") if (tokens[j].type === "paragraph_open") {
9349
9656
  const contentToken = tokens[j + 1];
9657
+ const children = contentToken.children || [];
9658
+ if (tokens[j + 2].type === "footnote_anchor") children.push(tokens[j + 2]);
9350
9659
  footnoteChildren.push({
9351
9660
  type: "paragraph",
9352
9661
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }),
@@ -9778,7 +10087,7 @@ function parseParagraph(tokens, index, options) {
9778
10087
  //#endregion
9779
10088
  //#region src/parser/index.ts
9780
10089
  function parseMarkdownToStructure(markdown, md, options = {}) {
9781
- let safeMarkdown = (markdown ?? "").toString().replace(/([^\\])\right/g, "$1\\right");
10090
+ let safeMarkdown = (markdown ?? "").toString().replace(/([^\\])\r(ight|ho)/g, "$1\\r$2").replace(/([^\\])\n(abla|eq|ot|exists)/g, "$1\\n$2");
9782
10091
  if (safeMarkdown.endsWith("- *")) safeMarkdown = safeMarkdown.replace(/- \*$/, "- \\*");
9783
10092
  if (/\n\s*-\s*$/.test(safeMarkdown)) safeMarkdown = safeMarkdown.replace(/\n\s*-\s*$/, "\n");
9784
10093
  else if (/\n[[(]\n*$/.test(safeMarkdown)) safeMarkdown = safeMarkdown.replace(/(\n\[|\n\()+\n*$/g, "\n");
@@ -9874,6 +10183,17 @@ function processTokens(tokens, options) {
9874
10183
  i = newIndex;
9875
10184
  break;
9876
10185
  }
10186
+ case "footnote_anchor": {
10187
+ const meta = token.meta ?? {};
10188
+ const id = String(meta.label ?? token.content ?? "");
10189
+ result.push({
10190
+ type: "footnote_anchor",
10191
+ id,
10192
+ raw: String(token.content ?? "")
10193
+ });
10194
+ i++;
10195
+ break;
10196
+ }
9877
10197
  case "container_open": {
9878
10198
  const match = /^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/.exec(String(token.info ?? ""));
9879
10199
  if (match) {