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.d.ts +39 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +452 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6820,7 +6820,291 @@ const VOID_TAGS$2 = new Set([
|
|
|
6820
6820
|
"track",
|
|
6821
6821
|
"wbr"
|
|
6822
6822
|
]);
|
|
6823
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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, {
|
|
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, {
|
|
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
|
|
8479
|
-
innerTokens =
|
|
8480
|
-
fragmentTokens.push(
|
|
8481
|
-
nextIndex =
|
|
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
|
-
|
|
8886
|
+
attrs,
|
|
8887
|
+
content,
|
|
8553
8888
|
children,
|
|
8554
|
-
raw:
|
|
8555
|
-
loading
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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":
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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:
|