stream-markdown-parser 0.0.38 → 0.0.40

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
@@ -6820,7 +6820,291 @@ const VOID_TAGS$2 = new Set([
6820
6820
  "track",
6821
6821
  "wbr"
6822
6822
  ]);
6823
- function applyFixHtmlInlineTokens(md) {
6823
+ const BASE_COMMON_HTML_TAGS = new Set([
6824
+ ...Array.from(VOID_TAGS$2),
6825
+ "a",
6826
+ "abbr",
6827
+ "b",
6828
+ "bdi",
6829
+ "bdo",
6830
+ "button",
6831
+ "cite",
6832
+ "code",
6833
+ "data",
6834
+ "del",
6835
+ "dfn",
6836
+ "em",
6837
+ "i",
6838
+ "img",
6839
+ "input",
6840
+ "ins",
6841
+ "kbd",
6842
+ "label",
6843
+ "mark",
6844
+ "q",
6845
+ "s",
6846
+ "samp",
6847
+ "small",
6848
+ "span",
6849
+ "strong",
6850
+ "sub",
6851
+ "sup",
6852
+ "time",
6853
+ "u",
6854
+ "var",
6855
+ "article",
6856
+ "aside",
6857
+ "blockquote",
6858
+ "div",
6859
+ "details",
6860
+ "figcaption",
6861
+ "figure",
6862
+ "footer",
6863
+ "header",
6864
+ "h1",
6865
+ "h2",
6866
+ "h3",
6867
+ "h4",
6868
+ "h5",
6869
+ "h6",
6870
+ "li",
6871
+ "main",
6872
+ "nav",
6873
+ "ol",
6874
+ "p",
6875
+ "pre",
6876
+ "section",
6877
+ "summary",
6878
+ "table",
6879
+ "tbody",
6880
+ "td",
6881
+ "th",
6882
+ "thead",
6883
+ "tr",
6884
+ "ul",
6885
+ "svg",
6886
+ "g",
6887
+ "path"
6888
+ ]);
6889
+ const OPEN_TAG_RE = /<([A-Z][\w-]*)(?=[\s/>]|$)/gi;
6890
+ const CLOSE_TAG_RE = /<\/\s*([A-Z][\w-]*)(?=[\s/>]|$)/gi;
6891
+ const FULL_TAG_RE = /^<\s*(?:\/\s*)?([A-Z][\w-]*)(?:\s[^>]*?)?\/?>/i;
6892
+ function tokenToRaw$1(token) {
6893
+ const shape = token;
6894
+ return String(shape.raw ?? shape.content ?? shape.markup ?? "");
6895
+ }
6896
+ function buildCommonHtmlTagSet(extraTags) {
6897
+ const set = new Set(BASE_COMMON_HTML_TAGS);
6898
+ if (extraTags && Array.isArray(extraTags)) for (const t of extraTags) {
6899
+ const raw = String(t ?? "").trim();
6900
+ if (!raw) continue;
6901
+ const m = raw.match(/^[<\s/]*([A-Z][\w-]*)/i);
6902
+ if (!m) continue;
6903
+ set.add(m[1].toLowerCase());
6904
+ }
6905
+ return set;
6906
+ }
6907
+ function isCommonHtmlTagOrPrefix(tag, tagSet) {
6908
+ if (tagSet.has(tag)) return true;
6909
+ for (const common of tagSet) if (common.startsWith(tag)) return true;
6910
+ return false;
6911
+ }
6912
+ function findFirstIncompleteTag(content, tagSet) {
6913
+ let first = null;
6914
+ for (const m of content.matchAll(OPEN_TAG_RE)) {
6915
+ const idx = m.index ?? -1;
6916
+ if (idx < 0) continue;
6917
+ const tag = (m[1] ?? "").toLowerCase();
6918
+ if (!tagSet.has(tag)) continue;
6919
+ if (content.slice(idx).includes(">")) continue;
6920
+ if (!first || idx < first.index) first = {
6921
+ index: idx,
6922
+ tag,
6923
+ closing: false
6924
+ };
6925
+ }
6926
+ for (const m of content.matchAll(CLOSE_TAG_RE)) {
6927
+ const idx = m.index ?? -1;
6928
+ if (idx < 0) continue;
6929
+ const tag = (m[1] ?? "").toLowerCase();
6930
+ if (!isCommonHtmlTagOrPrefix(tag, tagSet)) continue;
6931
+ if (content.slice(idx).includes(">")) continue;
6932
+ if (!first || idx < first.index) first = {
6933
+ index: idx,
6934
+ tag,
6935
+ closing: true
6936
+ };
6937
+ }
6938
+ const bareClose = /<\/\s*$/.exec(content);
6939
+ if (bareClose && typeof bareClose.index === "number") {
6940
+ const idx = bareClose.index;
6941
+ if (!content.slice(idx).includes(">") && (!first || idx < first.index)) first = {
6942
+ index: idx,
6943
+ tag: "",
6944
+ closing: true
6945
+ };
6946
+ }
6947
+ const bareOpen = /<\s*$/.exec(content);
6948
+ if (bareOpen && typeof bareOpen.index === "number") {
6949
+ const idx = bareOpen.index;
6950
+ const rest = content.slice(idx);
6951
+ if (!rest.startsWith("</") && !rest.includes(">") && (!first || idx < first.index)) first = {
6952
+ index: idx,
6953
+ tag: "",
6954
+ closing: false
6955
+ };
6956
+ }
6957
+ return first;
6958
+ }
6959
+ function splitTextToken(token, content) {
6960
+ const t = token;
6961
+ return Object.assign(Object.create(Object.getPrototypeOf(t)), t, {
6962
+ type: "text",
6963
+ content,
6964
+ raw: content
6965
+ });
6966
+ }
6967
+ function fixStreamingHtmlInlineChildren(children, tagSet) {
6968
+ if (!children.length) return { children };
6969
+ const out = [];
6970
+ let pending = null;
6971
+ let pendingAtEnd = null;
6972
+ function pushTextPart(text$1, baseToken) {
6973
+ if (!text$1) return;
6974
+ if (baseToken) out.push(splitTextToken(baseToken, text$1));
6975
+ else out.push({
6976
+ type: "text",
6977
+ content: text$1,
6978
+ raw: text$1
6979
+ });
6980
+ }
6981
+ function splitCompleteHtmlFromText(chunk, baseToken) {
6982
+ let cursor = 0;
6983
+ while (cursor < chunk.length) {
6984
+ const lt = chunk.indexOf("<", cursor);
6985
+ if (lt === -1) {
6986
+ pushTextPart(chunk.slice(cursor), baseToken);
6987
+ break;
6988
+ }
6989
+ pushTextPart(chunk.slice(cursor, lt), baseToken);
6990
+ const fullMatch = chunk.slice(lt).match(FULL_TAG_RE);
6991
+ if (!fullMatch) {
6992
+ pushTextPart("<", baseToken);
6993
+ cursor = lt + 1;
6994
+ continue;
6995
+ }
6996
+ const tagText = fullMatch[0];
6997
+ const tagName = (fullMatch[1] ?? "").toLowerCase();
6998
+ if (tagSet.has(tagName)) out.push({
6999
+ type: "html_inline",
7000
+ tag: "",
7001
+ content: tagText,
7002
+ raw: tagText
7003
+ });
7004
+ else pushTextPart(tagText, baseToken);
7005
+ cursor = lt + tagText.length;
7006
+ }
7007
+ }
7008
+ function processTextChunk(chunk, baseToken) {
7009
+ if (!chunk) return;
7010
+ const match = findFirstIncompleteTag(chunk, tagSet);
7011
+ if (!match) {
7012
+ splitCompleteHtmlFromText(chunk, baseToken);
7013
+ return;
7014
+ }
7015
+ const before = chunk.slice(0, match.index);
7016
+ if (before) splitCompleteHtmlFromText(before, baseToken);
7017
+ pending = {
7018
+ tag: match.tag,
7019
+ buffer: chunk.slice(match.index),
7020
+ closing: match.closing
7021
+ };
7022
+ pendingAtEnd = pending.buffer;
7023
+ }
7024
+ for (const child of children) {
7025
+ if (pending) {
7026
+ pending.buffer += tokenToRaw$1(child);
7027
+ pendingAtEnd = pending.buffer;
7028
+ const closeIdx = pending.buffer.indexOf(">");
7029
+ if (closeIdx === -1) continue;
7030
+ const tagChunk = pending.buffer.slice(0, closeIdx + 1);
7031
+ const afterChunk = pending.buffer.slice(closeIdx + 1);
7032
+ out.push({
7033
+ type: "html_inline",
7034
+ tag: "",
7035
+ content: tagChunk,
7036
+ raw: tagChunk
7037
+ });
7038
+ pending = null;
7039
+ pendingAtEnd = null;
7040
+ if (afterChunk) processTextChunk(afterChunk);
7041
+ continue;
7042
+ }
7043
+ if (child.type === "text") {
7044
+ const content = String(child.content ?? "");
7045
+ if (!content.includes("<")) {
7046
+ out.push(child);
7047
+ continue;
7048
+ }
7049
+ processTextChunk(content, child);
7050
+ continue;
7051
+ }
7052
+ out.push(child);
7053
+ }
7054
+ return {
7055
+ children: out,
7056
+ pendingBuffer: pendingAtEnd ?? void 0
7057
+ };
7058
+ }
7059
+ function applyFixHtmlInlineTokens(md, options = {}) {
7060
+ const commonHtmlTags = buildCommonHtmlTagSet(options.customHtmlTags);
7061
+ const autoCloseInlineTagSet = new Set([
7062
+ "a",
7063
+ "span",
7064
+ "strong",
7065
+ "em",
7066
+ "b",
7067
+ "i",
7068
+ "u"
7069
+ ]);
7070
+ const customTagSet = /* @__PURE__ */ new Set();
7071
+ if (options.customHtmlTags?.length) for (const t of options.customHtmlTags) {
7072
+ const raw = String(t ?? "").trim();
7073
+ if (!raw) continue;
7074
+ const m = raw.match(/^[<\s/]*([A-Z][\w-]*)/i);
7075
+ if (!m) continue;
7076
+ const name = m[1].toLowerCase();
7077
+ customTagSet.add(name);
7078
+ autoCloseInlineTagSet.add(name);
7079
+ }
7080
+ md.core.ruler.after("inline", "fix_html_inline_streaming", (state) => {
7081
+ const toks = state.tokens ?? [];
7082
+ for (const t of toks) {
7083
+ const tok = t;
7084
+ if (tok.type !== "inline" || !Array.isArray(tok.children)) continue;
7085
+ const originalContent = String(tok.content ?? "");
7086
+ const sourceChildren = tok.children.length ? tok.children : originalContent.includes("<") ? [{
7087
+ type: "text",
7088
+ content: originalContent,
7089
+ raw: originalContent
7090
+ }] : null;
7091
+ if (!sourceChildren) continue;
7092
+ try {
7093
+ const fixed = fixStreamingHtmlInlineChildren(sourceChildren, commonHtmlTags);
7094
+ tok.children = fixed.children;
7095
+ if (fixed.pendingBuffer) {
7096
+ const idx = originalContent.lastIndexOf(fixed.pendingBuffer);
7097
+ if (idx !== -1) {
7098
+ const trimmed = originalContent.slice(0, idx);
7099
+ tok.content = trimmed;
7100
+ if (typeof tok.raw === "string") tok.raw = trimmed;
7101
+ }
7102
+ }
7103
+ } catch (e) {
7104
+ console.error("[applyFixHtmlInlineTokens] failed to fix streaming html inline", e);
7105
+ }
7106
+ }
7107
+ });
6824
7108
  md.core.ruler.push("fix_html_inline_tokens", (state) => {
6825
7109
  const toks = state.tokens ?? [];
6826
7110
  const tagStack = [];
@@ -6872,7 +7156,26 @@ function applyFixHtmlInlineTokens(md) {
6872
7156
  ].includes(tag)) continue;
6873
7157
  t.type = "inline";
6874
7158
  const loading = t.content?.toLowerCase().includes(`</${tag}>`) ? false : t.loading !== void 0 ? t.loading : true;
6875
- t.children = [{
7159
+ const attrs = [];
7160
+ const attrRegex = /\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;
7161
+ let match;
7162
+ while ((match = attrRegex.exec(t.content || "")) !== null) {
7163
+ const attrName = match[1];
7164
+ const attrValue = match[2] || match[3] || match[4] || "";
7165
+ attrs.push([attrName, attrValue]);
7166
+ }
7167
+ if (customTagSet.has(tag)) {
7168
+ const contentMatch = t.content?.match(new RegExp(`<\\s*${tag}[^>]*>([\\s\\S]*?)<\\s*\\/\\s*${tag}\\s*>`, "i"));
7169
+ const raw$1 = t.content;
7170
+ t.children = [{
7171
+ type: tag,
7172
+ content: contentMatch ? contentMatch[1] : "",
7173
+ raw: raw$1,
7174
+ attrs,
7175
+ tag,
7176
+ loading
7177
+ }];
7178
+ } else t.children = [{
6876
7179
  type: "html_block",
6877
7180
  content: t.content,
6878
7181
  tag,
@@ -6882,16 +7185,8 @@ function applyFixHtmlInlineTokens(md) {
6882
7185
  }
6883
7186
  if (!t || t.type !== "inline") continue;
6884
7187
  if (t.children.length === 2 && t.children[0].type === "html_inline") {
6885
- const tag = t.children[0].content?.match(/<([^\s>/]+)/)?.[1] ?? "";
6886
- if ([
6887
- "a",
6888
- "span",
6889
- "strong",
6890
- "em",
6891
- "b",
6892
- "i",
6893
- "u"
6894
- ].includes(tag)) {
7188
+ const tag = (t.children[0].content?.match(/<([^\s>/]+)/)?.[1] ?? "").toLowerCase();
7189
+ if (autoCloseInlineTagSet.has(tag)) {
6895
7190
  t.children[0].loading = true;
6896
7191
  t.children[0].tag = tag;
6897
7192
  t.children.push({
@@ -6908,16 +7203,8 @@ function applyFixHtmlInlineTokens(md) {
6908
7203
  }];
6909
7204
  continue;
6910
7205
  } else if (t.children.length === 3 && t.children[0].type === "html_inline" && t.children[2].type === "html_inline") {
6911
- const tag = t.children[0].content?.match(/<([^\s>/]+)/)?.[1] ?? "";
6912
- if ([
6913
- "a",
6914
- "span",
6915
- "strong",
6916
- "em",
6917
- "b",
6918
- "i",
6919
- "u"
6920
- ].includes(tag)) continue;
7206
+ const tag = (t.children[0].content?.match(/<([^\s>/]+)/)?.[1] ?? "").toLowerCase();
7207
+ if (autoCloseInlineTagSet.has(tag)) continue;
6921
7208
  t.children = [{
6922
7209
  type: "html_block",
6923
7210
  loading: false,
@@ -7918,6 +8205,12 @@ function normalizeStandaloneBackslashT(s, opts) {
7918
8205
  result = result.replace(ESCAPED_MKATWX_COMMANDS, "$1\\$2");
7919
8206
  return result;
7920
8207
  }
8208
+ function isPlainBracketMathLike(content) {
8209
+ const stripped = content.trim();
8210
+ if (!isMathLike(stripped)) return false;
8211
+ if (!(/\\[a-z]+/i.test(stripped) || /\d/.test(stripped) || /[=+*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/.test(stripped) || /[_^]/.test(stripped)) && /\s-\s/.test(stripped)) return false;
8212
+ return true;
8213
+ }
7921
8214
  function applyMath(md, mathOpts) {
7922
8215
  const mathInline = (state, silent) => {
7923
8216
  const s = state;
@@ -8109,7 +8402,8 @@ function applyMath(md, mathOpts) {
8109
8402
  if (lineText.replace("\\", "").startsWith("[") && !lineText.includes("](")) {
8110
8403
  const closeIndex = lineText.indexOf("]");
8111
8404
  if (lineText.slice(closeIndex).trim() !== "]") continue;
8112
- if (isMathLike(lineText.slice(open.length, closeIndex))) {
8405
+ const inner = lineText.slice(open.length, closeIndex);
8406
+ if (open === "[" ? isPlainBracketMathLike(inner) : isMathLike(inner)) {
8113
8407
  matched = true;
8114
8408
  openDelim = open;
8115
8409
  closeDelim = close;
@@ -8180,7 +8474,7 @@ function applyMath(md, mathOpts) {
8180
8474
  }
8181
8475
  }
8182
8476
  if (strict && !found) return false;
8183
- if (!isMathLike(content)) return false;
8477
+ if (!(openDelim === "[" ? isPlainBracketMathLike(content) : isMathLike(content))) return false;
8184
8478
  const token = s.push("math_block", "math", 0);
8185
8479
  token.content = normalizeStandaloneBackslashT(content);
8186
8480
  token.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]";
@@ -8240,7 +8534,7 @@ function factory(opts = {}) {
8240
8534
  applyFixListItem(md);
8241
8535
  applyFixTableTokens(md);
8242
8536
  applyRenderRules(md);
8243
- applyFixHtmlInlineTokens(md);
8537
+ applyFixHtmlInlineTokens(md, { customHtmlTags: opts.customHtmlTags });
8244
8538
  return md;
8245
8539
  }
8246
8540
 
@@ -8289,7 +8583,10 @@ function parseEmphasisToken(tokens, startIndex, options) {
8289
8583
  innerTokens.push(tokens[i]);
8290
8584
  i++;
8291
8585
  }
8292
- children.push(...parseInlineTokens(innerTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }));
8586
+ children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
8587
+ requireClosingStrong: options?.requireClosingStrong,
8588
+ customHtmlTags: options?.customHtmlTags
8589
+ }));
8293
8590
  return {
8294
8591
  node: {
8295
8592
  type: "emphasis",
@@ -8397,7 +8694,10 @@ function parseHighlightToken(tokens, startIndex, options) {
8397
8694
  innerTokens.push(tokens[i]);
8398
8695
  i++;
8399
8696
  }
8400
- children.push(...parseInlineTokens(innerTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }));
8697
+ children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
8698
+ requireClosingStrong: options?.requireClosingStrong,
8699
+ customHtmlTags: options?.customHtmlTags
8700
+ }));
8401
8701
  return {
8402
8702
  node: {
8403
8703
  type: "highlight",
@@ -8436,6 +8736,12 @@ function isClosingTag(html) {
8436
8736
  function isSelfClosing(tag, html) {
8437
8737
  return /\/\s*>\s*$/.test(html) || VOID_TAGS$1.has(tag);
8438
8738
  }
8739
+ function normalizeCustomTag(t) {
8740
+ const raw = String(t ?? "").trim();
8741
+ if (!raw) return "";
8742
+ const m = raw.match(/^[<\s/]*([A-Z][\w-]*)/i);
8743
+ return m ? m[1].toLowerCase() : "";
8744
+ }
8439
8745
  function tokenToRaw(token) {
8440
8746
  const shape = token;
8441
8747
  const raw = shape.raw ?? shape.content ?? shape.markup ?? "";
@@ -8475,10 +8781,10 @@ function collectHtmlFragment(tokens, startIndex, tag) {
8475
8781
  fragmentTokens.push(...innerTokens, tokens[closingIndex]);
8476
8782
  nextIndex = closingIndex + 1;
8477
8783
  closed = true;
8478
- } else if (tokens[startIndex + 1]?.type === "text") {
8479
- innerTokens = [tokens[startIndex + 1]];
8480
- fragmentTokens.push(tokens[startIndex + 1]);
8481
- nextIndex = startIndex + 2;
8784
+ } else {
8785
+ innerTokens = tokens.slice(startIndex + 1);
8786
+ if (innerTokens.length) fragmentTokens.push(...innerTokens);
8787
+ nextIndex = tokens.length;
8482
8788
  }
8483
8789
  return {
8484
8790
  closed,
@@ -8490,6 +8796,8 @@ function collectHtmlFragment(tokens, startIndex, tag) {
8490
8796
  function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pPreToken, options) {
8491
8797
  const code$1 = String(token.content ?? "");
8492
8798
  const tag = getTagName(code$1);
8799
+ const customTags = options?.customHtmlTags;
8800
+ const customTagSet = customTags && customTags.length ? new Set(customTags.map(normalizeCustomTag).filter(Boolean)) : null;
8493
8801
  if (!tag) return [{
8494
8802
  type: "inline_code",
8495
8803
  code: code$1,
@@ -8532,7 +8840,7 @@ function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pP
8532
8840
  }, fragment$1.nextIndex];
8533
8841
  }
8534
8842
  if (selfClosing) return [{
8535
- type: "html_inline",
8843
+ type: customTagSet?.has(tag) ? tag : "html_inline",
8536
8844
  tag,
8537
8845
  content: code$1,
8538
8846
  children: [],
@@ -8546,13 +8854,41 @@ function parseHtmlInlineCodeToken(token, tokens, i, parseInlineTokens$1, raw, pP
8546
8854
  raw: fragment.html
8547
8855
  }, fragment.nextIndex];
8548
8856
  const children = fragment.innerTokens.length ? parseInlineTokens$1(fragment.innerTokens, raw, pPreToken, options) : [];
8857
+ let content = fragment.html || code$1;
8858
+ let loading = !fragment.closed;
8859
+ let autoClosed = false;
8860
+ if (!fragment.closed) {
8861
+ const closeTag = `</${tag}>`;
8862
+ if (!content.toLowerCase().includes(closeTag.toLowerCase())) content += closeTag;
8863
+ autoClosed = true;
8864
+ loading = true;
8865
+ }
8866
+ const attrs = [];
8867
+ const attrRegex = /\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;
8868
+ let match;
8869
+ while ((match = attrRegex.exec(code$1)) !== null) {
8870
+ const attrName = match[1];
8871
+ const attrValue = match[2] || match[3] || match[4] || "";
8872
+ attrs.push([attrName, attrValue]);
8873
+ }
8874
+ if (customTagSet?.has(tag)) return [{
8875
+ type: tag,
8876
+ tag,
8877
+ attrs,
8878
+ content: fragment.innerTokens.length ? stringifyTokens(fragment.innerTokens) : "",
8879
+ raw: content,
8880
+ loading: token.loading || loading,
8881
+ autoClosed
8882
+ }, fragment.nextIndex];
8549
8883
  return [{
8550
8884
  type: "html_inline",
8551
8885
  tag,
8552
- content: fragment.html || code$1,
8886
+ attrs,
8887
+ content,
8553
8888
  children,
8554
- raw: fragment.html || code$1,
8555
- loading: !fragment.closed
8889
+ raw: content,
8890
+ loading,
8891
+ autoClosed
8556
8892
  }, fragment.nextIndex];
8557
8893
  }
8558
8894
 
@@ -8613,7 +8949,10 @@ function parseInsertToken(tokens, startIndex, options) {
8613
8949
  innerTokens.push(tokens[i]);
8614
8950
  i++;
8615
8951
  }
8616
- children.push(...parseInlineTokens(innerTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }));
8952
+ children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
8953
+ requireClosingStrong: options?.requireClosingStrong,
8954
+ customHtmlTags: options?.customHtmlTags
8955
+ }));
8617
8956
  return {
8618
8957
  node: {
8619
8958
  type: "insert",
@@ -8639,7 +8978,10 @@ function parseLinkToken(tokens, startIndex, options) {
8639
8978
  i++;
8640
8979
  }
8641
8980
  if (tokens[i]?.type === "link_close") loading = false;
8642
- const children = parseInlineTokens(linkTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong });
8981
+ const children = parseInlineTokens(linkTokens, void 0, void 0, {
8982
+ requireClosingStrong: options?.requireClosingStrong,
8983
+ customHtmlTags: options?.customHtmlTags
8984
+ });
8643
8985
  const linkText = children.map((node) => {
8644
8986
  const nodeAny = node;
8645
8987
  if ("content" in node) return String(nodeAny.content ?? "");
@@ -8694,7 +9036,10 @@ function parseStrikethroughToken(tokens, startIndex, options) {
8694
9036
  innerTokens.push(tokens[i]);
8695
9037
  i++;
8696
9038
  }
8697
- children.push(...parseInlineTokens(innerTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }));
9039
+ children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
9040
+ requireClosingStrong: options?.requireClosingStrong,
9041
+ customHtmlTags: options?.customHtmlTags
9042
+ }));
8698
9043
  return {
8699
9044
  node: {
8700
9045
  type: "strikethrough",
@@ -8723,7 +9068,10 @@ function parseStrongToken(tokens, startIndex, raw, options) {
8723
9068
  innerTokens.push(tokens[i]);
8724
9069
  i++;
8725
9070
  }
8726
- children.push(...parseInlineTokens(innerTokens, raw, void 0, { requireClosingStrong: options?.requireClosingStrong }));
9071
+ children.push(...parseInlineTokens(innerTokens, raw, void 0, {
9072
+ requireClosingStrong: options?.requireClosingStrong,
9073
+ customHtmlTags: options?.customHtmlTags
9074
+ }));
8727
9075
  return {
8728
9076
  node: {
8729
9077
  type: "strong",
@@ -8746,7 +9094,10 @@ function parseSubscriptToken(tokens, startIndex, options) {
8746
9094
  innerTokens.push(tokens[i]);
8747
9095
  i++;
8748
9096
  }
8749
- children.push(...parseInlineTokens(innerTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }));
9097
+ children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
9098
+ requireClosingStrong: options?.requireClosingStrong,
9099
+ customHtmlTags: options?.customHtmlTags
9100
+ }));
8750
9101
  const startContent = String(tokens[startIndex].content ?? "");
8751
9102
  const display = subText || startContent;
8752
9103
  return {
@@ -8775,7 +9126,10 @@ function parseSuperscriptToken(tokens, startIndex, options) {
8775
9126
  innerTokens.push(tokens[i]);
8776
9127
  i++;
8777
9128
  }
8778
- children.push(...parseInlineTokens(innerTokens, void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }));
9129
+ children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
9130
+ requireClosingStrong: options?.requireClosingStrong,
9131
+ customHtmlTags: options?.customHtmlTags
9132
+ }));
8779
9133
  return {
8780
9134
  node: {
8781
9135
  type: "superscript",
@@ -9652,7 +10006,10 @@ function parseDefinitionList(tokens, index, options) {
9652
10006
  let definitionNodes = [];
9653
10007
  while (j < tokens.length && tokens[j].type !== "dl_close") if (tokens[j].type === "dt_open") {
9654
10008
  const termToken = tokens[j + 1];
9655
- termNodes = parseInlineTokens(termToken.children || [], void 0, void 0, { requireClosingStrong: options?.requireClosingStrong });
10009
+ termNodes = parseInlineTokens(termToken.children || [], void 0, void 0, {
10010
+ requireClosingStrong: options?.requireClosingStrong,
10011
+ customHtmlTags: options?.customHtmlTags
10012
+ });
9656
10013
  j += 3;
9657
10014
  } else if (tokens[j].type === "dd_open") {
9658
10015
  let k = j + 1;
@@ -9661,7 +10018,10 @@ function parseDefinitionList(tokens, index, options) {
9661
10018
  const contentToken = tokens[k + 1];
9662
10019
  definitionNodes.push({
9663
10020
  type: "paragraph",
9664
- children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }),
10021
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
10022
+ requireClosingStrong: options?.requireClosingStrong,
10023
+ customHtmlTags: options?.customHtmlTags
10024
+ }),
9665
10025
  raw: String(contentToken.content ?? "")
9666
10026
  });
9667
10027
  k += 3;
@@ -9697,7 +10057,10 @@ function parseFootnote(tokens, index, options) {
9697
10057
  if (tokens[j + 2].type === "footnote_anchor") children.push(tokens[j + 2]);
9698
10058
  footnoteChildren.push({
9699
10059
  type: "paragraph",
9700
- children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }),
10060
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
10061
+ requireClosingStrong: options?.requireClosingStrong,
10062
+ customHtmlTags: options?.customHtmlTags
10063
+ }),
9701
10064
  raw: String(contentToken.content ?? "")
9702
10065
  });
9703
10066
  j += 3;
@@ -9722,7 +10085,10 @@ function parseHeading(tokens, index, options) {
9722
10085
  type: "heading",
9723
10086
  level: headingLevel,
9724
10087
  text: headingContent,
9725
- children: parseInlineTokens(headingContentToken.children || [], headingContent, void 0, { requireClosingStrong: options?.requireClosingStrong }),
10088
+ children: parseInlineTokens(headingContentToken.children || [], headingContent, void 0, {
10089
+ requireClosingStrong: options?.requireClosingStrong,
10090
+ customHtmlTags: options?.customHtmlTags
10091
+ }),
9726
10092
  raw: headingContent
9727
10093
  };
9728
10094
  }
@@ -9833,7 +10199,10 @@ function parseTable(tokens, index, options) {
9833
10199
  cells.push({
9834
10200
  type: "table_cell",
9835
10201
  header: isHeaderCell || isHeader,
9836
- children: parseInlineTokens(contentToken.children || [], content, void 0, { requireClosingStrong: options?.requireClosingStrong }),
10202
+ children: parseInlineTokens(contentToken.children || [], content, void 0, {
10203
+ requireClosingStrong: options?.requireClosingStrong,
10204
+ customHtmlTags: options?.customHtmlTags
10205
+ }),
9837
10206
  raw: content,
9838
10207
  align
9839
10208
  });
@@ -9880,7 +10249,19 @@ function parseBasicBlockToken(tokens, index, options) {
9880
10249
  case "code_block": return [parseCodeBlock(token), index + 1];
9881
10250
  case "fence": return [parseFenceToken(token), index + 1];
9882
10251
  case "math_block": return [parseMathBlock(token), index + 1];
9883
- case "html_block": return [parseHtmlBlock(token), index + 1];
10252
+ case "html_block": {
10253
+ const htmlBlockNode = parseHtmlBlock(token);
10254
+ if (options?.customHtmlTags && htmlBlockNode.tag) {
10255
+ if (new Set(options.customHtmlTags.map((t) => {
10256
+ const m = String(t ?? "").trim().match(/^[<\s/]*([A-Z][\w-]*)/i);
10257
+ return m ? m[1].toLowerCase() : "";
10258
+ }).filter(Boolean)).has(htmlBlockNode.tag)) return [{
10259
+ ...htmlBlockNode,
10260
+ type: htmlBlockNode.tag
10261
+ }, index + 1];
10262
+ }
10263
+ return [htmlBlockNode, index + 1];
10264
+ }
9884
10265
  case "table_open": {
9885
10266
  const [tableNode, newIndex] = parseTable(tokens, index, options);
9886
10267
  return [tableNode, newIndex];
@@ -9941,7 +10322,10 @@ function parseList(tokens, index, options) {
9941
10322
  }
9942
10323
  itemChildren.push({
9943
10324
  type: "paragraph",
9944
- children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken, { requireClosingStrong: options?.requireClosingStrong }),
10325
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken, {
10326
+ requireClosingStrong: options?.requireClosingStrong,
10327
+ customHtmlTags: options?.customHtmlTags
10328
+ }),
9945
10329
  raw: String(contentToken.content ?? "")
9946
10330
  });
9947
10331
  k += 3;
@@ -9995,7 +10379,10 @@ function parseAdmonition(tokens, index, match, options) {
9995
10379
  const contentToken = tokens[j + 1];
9996
10380
  if (contentToken) admonitionChildren.push({
9997
10381
  type: "paragraph",
9998
- children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }),
10382
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
10383
+ requireClosingStrong: options?.requireClosingStrong,
10384
+ customHtmlTags: options?.customHtmlTags
10385
+ }),
9999
10386
  raw: String(contentToken.content ?? "")
10000
10387
  });
10001
10388
  j += 3;
@@ -10064,7 +10451,10 @@ function parseContainer(tokens, index, options) {
10064
10451
  const _children = i !== -1 ? childrenArr.slice(0, i) : childrenArr;
10065
10452
  children.push({
10066
10453
  type: "paragraph",
10067
- children: parseInlineTokens(_children || [], void 0, void 0, { requireClosingStrong: options?.requireClosingStrong }),
10454
+ children: parseInlineTokens(_children || [], void 0, void 0, {
10455
+ requireClosingStrong: options?.requireClosingStrong,
10456
+ customHtmlTags: options?.customHtmlTags
10457
+ }),
10068
10458
  raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
10069
10459
  });
10070
10460
  }
@@ -10118,7 +10508,10 @@ function parseBlockquote(tokens, index, options) {
10118
10508
  const contentToken = tokens[j + 1];
10119
10509
  blockquoteChildren.push({
10120
10510
  type: "paragraph",
10121
- children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }),
10511
+ children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
10512
+ requireClosingStrong: options?.requireClosingStrong,
10513
+ customHtmlTags: options?.customHtmlTags
10514
+ }),
10122
10515
  raw: String(contentToken.content ?? "")
10123
10516
  });
10124
10517
  j += 3;
@@ -10169,7 +10562,10 @@ function parseParagraph(tokens, index, options) {
10169
10562
  const paragraphContent = String(paragraphContentToken.content ?? "");
10170
10563
  return {
10171
10564
  type: "paragraph",
10172
- children: parseInlineTokens(paragraphContentToken.children || [], paragraphContent, void 0, { requireClosingStrong: options?.requireClosingStrong }),
10565
+ children: parseInlineTokens(paragraphContentToken.children || [], paragraphContent, void 0, {
10566
+ requireClosingStrong: options?.requireClosingStrong,
10567
+ customHtmlTags: options?.customHtmlTags
10568
+ }),
10173
10569
  raw: paragraphContent
10174
10570
  };
10175
10571
  }
@@ -10246,7 +10642,10 @@ function processTokens(tokens, options) {
10246
10642
  i++;
10247
10643
  break;
10248
10644
  case "inline":
10249
- result.push(...parseInlineTokens(token.children || [], String(token.content ?? ""), void 0, { requireClosingStrong: options?.requireClosingStrong }));
10645
+ result.push(...parseInlineTokens(token.children || [], String(token.content ?? ""), void 0, {
10646
+ requireClosingStrong: options?.requireClosingStrong,
10647
+ customHtmlTags: options?.customHtmlTags
10648
+ }));
10250
10649
  i += 1;
10251
10650
  break;
10252
10651
  default: