stream-markdown-parser 0.0.59-beta.8 → 0.0.59
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/README.md +19 -1
- package/README.zh-CN.md +19 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +268 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -227,7 +227,7 @@ Processes raw markdown-it tokens into a flat array.
|
|
|
227
227
|
|
|
228
228
|
#### `parseInlineTokens(tokens, content?, preToken?, options?)`
|
|
229
229
|
|
|
230
|
-
Parses inline markdown-it-ts tokens into renderer nodes. Pass the inline token array plus the optional raw `content` string (from the parent token), an optional previous token, and inline parse options (`requireClosingStrong`, `customHtmlTags`).
|
|
230
|
+
Parses inline markdown-it-ts tokens into renderer nodes. Pass the inline token array plus the optional raw `content` string (from the parent token), an optional previous token, and inline parse options (`requireClosingStrong`, `customHtmlTags`, `validateLink`).
|
|
231
231
|
|
|
232
232
|
### Configuration Functions
|
|
233
233
|
|
|
@@ -255,6 +255,8 @@ interface ParseOptions {
|
|
|
255
255
|
postTransformTokens?: (tokens: Token[]) => Token[]
|
|
256
256
|
// Custom HTML-like tags to emit as custom nodes (e.g. ['thinking'])
|
|
257
257
|
customHtmlTags?: string[]
|
|
258
|
+
// Validate link href before emitting a `link` node; false -> plain text
|
|
259
|
+
validateLink?: (url: string) => boolean
|
|
258
260
|
// When true, treats the input as complete (end-of-stream)
|
|
259
261
|
final?: boolean
|
|
260
262
|
// Require closing `**` for strong parsing (default: false)
|
|
@@ -279,6 +281,22 @@ const tagged = nodes.map(node =>
|
|
|
279
281
|
|
|
280
282
|
Use the metadata in your renderer to show custom UI without mangling the original Markdown.
|
|
281
283
|
|
|
284
|
+
Example — enforce safe link protocols:
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
const md = getMarkdown('safe-links')
|
|
288
|
+
md.set?.({
|
|
289
|
+
validateLink: (url: string) => !/^\s*javascript:/i.test(url.trim()),
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
const nodes = parseMarkdownToStructure(
|
|
293
|
+
'[ok](https://example.com) [bad](javascript:alert(1))',
|
|
294
|
+
md,
|
|
295
|
+
{ final: true },
|
|
296
|
+
)
|
|
297
|
+
// "ok" stays a link node; "bad" is downgraded to plain text
|
|
298
|
+
```
|
|
299
|
+
|
|
282
300
|
### Unknown HTML-like tags
|
|
283
301
|
|
|
284
302
|
By default, non-standard HTML-like tags (for example `<question>`) are rendered as raw HTML elements once they are complete; during streaming, partial tags are kept as **literal text** to avoid flicker. If you want them emitted as custom nodes (`type: 'question'` with parsed attrs/content), opt in via `customHtmlTags`.
|
package/README.zh-CN.md
CHANGED
|
@@ -226,7 +226,7 @@ interface GetMarkdownOptions {
|
|
|
226
226
|
|
|
227
227
|
#### `parseInlineTokens(tokens, content?, preToken?, options?)`
|
|
228
228
|
|
|
229
|
-
解析内联 markdown-it-ts tokens 并产出节点。可传入原始 `content`(来自父 token)、可选的前一个 token,以及 inline 解析选项(`requireClosingStrong`、`customHtmlTags`)。
|
|
229
|
+
解析内联 markdown-it-ts tokens 并产出节点。可传入原始 `content`(来自父 token)、可选的前一个 token,以及 inline 解析选项(`requireClosingStrong`、`customHtmlTags`、`validateLink`)。
|
|
230
230
|
|
|
231
231
|
### 配置函数
|
|
232
232
|
|
|
@@ -254,6 +254,8 @@ interface ParseOptions {
|
|
|
254
254
|
postTransformTokens?: (tokens: Token[]) => Token[]
|
|
255
255
|
// 自定义 HTML 类标签,作为自定义节点输出(如 ['thinking'])
|
|
256
256
|
customHtmlTags?: string[]
|
|
257
|
+
// 输出 link 节点前校验 href;返回 false 时降级为纯文本
|
|
258
|
+
validateLink?: (url: string) => boolean
|
|
257
259
|
// true 表示输入已结束(end-of-stream)
|
|
258
260
|
final?: boolean
|
|
259
261
|
// 解析 strong 时要求闭合 `**`(默认 false)
|
|
@@ -278,6 +280,22 @@ const tagged = nodes.map(node =>
|
|
|
278
280
|
|
|
279
281
|
在渲染器中读取 `node.meta` 即可渲染自定义 UI,而无需直接修改 Markdown 文本。
|
|
280
282
|
|
|
283
|
+
示例 —— 限制链接协议,拦截不安全链接:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
const md = getMarkdown('safe-links')
|
|
287
|
+
md.set?.({
|
|
288
|
+
validateLink: (url: string) => !/^\s*javascript:/i.test(url.trim()),
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
const nodes = parseMarkdownToStructure(
|
|
292
|
+
'[ok](https://example.com) [bad](javascript:alert(1))',
|
|
293
|
+
md,
|
|
294
|
+
{ final: true },
|
|
295
|
+
)
|
|
296
|
+
// "ok" 保持为 link 节点;"bad" 会降级为纯文本
|
|
297
|
+
```
|
|
298
|
+
|
|
281
299
|
### 未知 HTML 类标签
|
|
282
300
|
|
|
283
301
|
默认情况下,非标准的 HTML 类标签(例如 `<question>`)在完整闭合时会按原生 HTML 渲染(作为自定义元素输出);流式场景下未闭合的片段会先按**纯文本**处理以避免闪烁。若希望它们作为自定义节点输出(`type: 'question'`,携带 attrs/content),需要在 `customHtmlTags` 中显式声明。
|
package/dist/index.d.ts
CHANGED
|
@@ -336,6 +336,14 @@ interface ParseOptions {
|
|
|
336
336
|
* to enable mid-state suppression for the same tags during streaming.
|
|
337
337
|
*/
|
|
338
338
|
customHtmlTags?: string[];
|
|
339
|
+
/**
|
|
340
|
+
* If provided, link nodes are only emitted when this returns true for the href.
|
|
341
|
+
* When it returns false, the link is rendered as plain text (the link text only).
|
|
342
|
+
* Typically set from the MarkdownIt instance (e.g. md.options.validateLink or
|
|
343
|
+
* md.set({ validateLink })) so that unsafe URLs (e.g. javascript:) are not
|
|
344
|
+
* output as links.
|
|
345
|
+
*/
|
|
346
|
+
validateLink?: (url: string) => boolean;
|
|
339
347
|
debug?: boolean;
|
|
340
348
|
}
|
|
341
349
|
type PostTransformNodesHook = (nodes: ParsedNode[]) => ParsedNode[];
|
|
@@ -344,6 +352,7 @@ type PostTransformNodesHook = (nodes: ParsedNode[]) => ParsedNode[];
|
|
|
344
352
|
declare function parseInlineTokens(tokens: MarkdownToken[], raw?: string, pPreToken?: MarkdownToken, options?: {
|
|
345
353
|
requireClosingStrong?: boolean;
|
|
346
354
|
customHtmlTags?: readonly string[];
|
|
355
|
+
validateLink?: (url: string) => boolean;
|
|
347
356
|
}): ParsedNode[];
|
|
348
357
|
//#endregion
|
|
349
358
|
//#region src/parser/index.d.ts
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/factory.ts","../src/types.ts","../src/parser/inline-parsers/index.ts","../src/parser/index.ts","../src/config.ts","../src/findMatchingClose.ts","../src/parser/inline-parsers/fence-parser.ts","../src/plugins/containers.ts","../src/plugins/isMathLike.ts","../src/plugins/math.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/factory.ts","../src/types.ts","../src/parser/inline-parsers/index.ts","../src/parser/index.ts","../src/config.ts","../src/findMatchingClose.ts","../src/parser/inline-parsers/fence-parser.ts","../src/plugins/containers.ts","../src/plugins/isMathLike.ts","../src/plugins/math.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7830,6 +7830,7 @@ function applyFixIndentedCodeBlock(md, options = {}) {
|
|
|
7830
7830
|
|
|
7831
7831
|
//#endregion
|
|
7832
7832
|
//#region src/plugins/fixLinkTokens.ts
|
|
7833
|
+
const LINKIFY_HARD_STOP_CHARS = ["!"];
|
|
7833
7834
|
function textToken(content) {
|
|
7834
7835
|
return {
|
|
7835
7836
|
type: "text",
|
|
@@ -7906,6 +7907,38 @@ function createLinkToken(text$1, href, loading) {
|
|
|
7906
7907
|
raw: String(`[${text$1}](${href})`)
|
|
7907
7908
|
};
|
|
7908
7909
|
}
|
|
7910
|
+
function appendToLinkToken(link$1, suffix) {
|
|
7911
|
+
if (!link$1 || !suffix) return;
|
|
7912
|
+
link$1.href = String(link$1.href ?? "") + suffix;
|
|
7913
|
+
link$1.text = String(link$1.text ?? "") + suffix;
|
|
7914
|
+
link$1.raw = String(`[${link$1.text}](${link$1.href})`);
|
|
7915
|
+
if (Array.isArray(link$1.children) && link$1.children.length) {
|
|
7916
|
+
const last = link$1.children[link$1.children.length - 1];
|
|
7917
|
+
if (last?.type === "text") {
|
|
7918
|
+
last.content = String(last.content ?? "") + suffix;
|
|
7919
|
+
last.raw = String(last.raw ?? "") + suffix;
|
|
7920
|
+
} else link$1.children.push(textToken(suffix));
|
|
7921
|
+
}
|
|
7922
|
+
}
|
|
7923
|
+
function firstIndexOfAny(input, chars) {
|
|
7924
|
+
let first = -1;
|
|
7925
|
+
for (const ch of chars) {
|
|
7926
|
+
const idx = input.indexOf(ch);
|
|
7927
|
+
if (idx !== -1 && (first === -1 || idx < first)) first = idx;
|
|
7928
|
+
}
|
|
7929
|
+
return first;
|
|
7930
|
+
}
|
|
7931
|
+
function getHrefFromLinkOpen(token) {
|
|
7932
|
+
const href = token?.attrs?.find((attr) => attr?.[0] === "href")?.[1];
|
|
7933
|
+
return typeof href === "string" ? href : "";
|
|
7934
|
+
}
|
|
7935
|
+
function setHrefOnLinkOpen(token, href) {
|
|
7936
|
+
if (!token) return;
|
|
7937
|
+
token.attrs = Array.isArray(token.attrs) ? token.attrs : [];
|
|
7938
|
+
const idx = token.attrs.findIndex((attr) => attr?.[0] === "href");
|
|
7939
|
+
if (idx >= 0) token.attrs[idx][1] = href;
|
|
7940
|
+
else token.attrs.push(["href", href]);
|
|
7941
|
+
}
|
|
7909
7942
|
function applyFixLinkTokens(md) {
|
|
7910
7943
|
md.core.ruler.after("inline", "fix_link_tokens", (state) => {
|
|
7911
7944
|
const toks = state.tokens ?? [];
|
|
@@ -7920,12 +7953,57 @@ function applyFixLinkTokens(md) {
|
|
|
7920
7953
|
});
|
|
7921
7954
|
}
|
|
7922
7955
|
function fixLinkToken(tokens) {
|
|
7923
|
-
if (tokens.length <
|
|
7956
|
+
if (tokens.length < 3) return tokens;
|
|
7924
7957
|
if (tokens.some((token) => token.type === "code_inline")) return tokens;
|
|
7925
7958
|
for (let i = 0; i <= tokens.length - 1; i++) {
|
|
7926
7959
|
if (i < 0) i = 0;
|
|
7927
7960
|
const curToken = tokens[i];
|
|
7928
7961
|
if (!curToken) break;
|
|
7962
|
+
if (curToken.type === "link_open" && (curToken.markup === "linkify" || curToken.markup === "autolink")) {
|
|
7963
|
+
let closeIdx = -1;
|
|
7964
|
+
for (let j = i + 1; j < tokens.length; j++) if (tokens[j]?.type === "link_close") {
|
|
7965
|
+
closeIdx = j;
|
|
7966
|
+
break;
|
|
7967
|
+
}
|
|
7968
|
+
if (closeIdx !== -1) {
|
|
7969
|
+
const href = getHrefFromLinkOpen(curToken);
|
|
7970
|
+
const hrefStop = firstIndexOfAny(href, LINKIFY_HARD_STOP_CHARS);
|
|
7971
|
+
for (let j = i + 1; j < closeIdx; j++) {
|
|
7972
|
+
const t = tokens[j];
|
|
7973
|
+
if (t?.type !== "text" || typeof t.content !== "string") continue;
|
|
7974
|
+
const stopAt = firstIndexOfAny(t.content, LINKIFY_HARD_STOP_CHARS);
|
|
7975
|
+
if (stopAt === -1) continue;
|
|
7976
|
+
const stopChar = t.content[stopAt];
|
|
7977
|
+
const before = t.content.slice(0, stopAt);
|
|
7978
|
+
let tail = t.content.slice(stopAt);
|
|
7979
|
+
for (let k = j + 1; k < closeIdx; k++) {
|
|
7980
|
+
const tk = tokens[k];
|
|
7981
|
+
if (tk?.type === "text" && typeof tk.content === "string") tail += tk.content;
|
|
7982
|
+
}
|
|
7983
|
+
t.content = before;
|
|
7984
|
+
t.raw = before;
|
|
7985
|
+
const removeCount = closeIdx - (j + 1);
|
|
7986
|
+
if (removeCount > 0) {
|
|
7987
|
+
tokens.splice(j + 1, removeCount);
|
|
7988
|
+
closeIdx = j + 1;
|
|
7989
|
+
}
|
|
7990
|
+
let newHref = href;
|
|
7991
|
+
if (hrefStop !== -1) newHref = href.slice(0, hrefStop);
|
|
7992
|
+
else if (tail) {
|
|
7993
|
+
const encodedTail = encodeURI(tail);
|
|
7994
|
+
if (encodedTail && href.endsWith(encodedTail)) newHref = href.slice(0, href.length - encodedTail.length);
|
|
7995
|
+
else {
|
|
7996
|
+
const encodedStop = stopChar ? encodeURI(stopChar) : "";
|
|
7997
|
+
const idx = encodedStop ? href.indexOf(encodedStop) : -1;
|
|
7998
|
+
if (idx !== -1) newHref = href.slice(0, idx);
|
|
7999
|
+
}
|
|
8000
|
+
}
|
|
8001
|
+
if (newHref !== href) setHrefOnLinkOpen(curToken, newHref);
|
|
8002
|
+
if (tail) tokens.splice(closeIdx + 1, 0, textToken(tail));
|
|
8003
|
+
break;
|
|
8004
|
+
}
|
|
8005
|
+
}
|
|
8006
|
+
}
|
|
7929
8007
|
if (curToken?.type === "em_open" && tokens[i - 1]?.type === "text" && tokens[i - 1].content?.endsWith("*")) {
|
|
7930
8008
|
const beforeText = tokens[i - 1].content?.replace(/(\*+)$/, "") || "";
|
|
7931
8009
|
tokens[i - 1].content = beforeText;
|
|
@@ -8197,6 +8275,21 @@ function fixLinkToken(tokens) {
|
|
|
8197
8275
|
}
|
|
8198
8276
|
}
|
|
8199
8277
|
}
|
|
8278
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
8279
|
+
const t = tokens[i];
|
|
8280
|
+
const next = tokens[i + 1];
|
|
8281
|
+
if (t?.type !== "link" || next?.type !== "text" || typeof next.content !== "string") continue;
|
|
8282
|
+
if (!next.content.startsWith("!")) continue;
|
|
8283
|
+
const href = String(t.href ?? "");
|
|
8284
|
+
if (String(t.text ?? "") !== href) continue;
|
|
8285
|
+
if (!href.endsWith("=") && !href.endsWith("#")) continue;
|
|
8286
|
+
appendToLinkToken(t, "!");
|
|
8287
|
+
const rest = next.content.slice(1);
|
|
8288
|
+
if (rest) {
|
|
8289
|
+
next.content = rest;
|
|
8290
|
+
next.raw = rest;
|
|
8291
|
+
} else tokens.splice(i + 1, 1);
|
|
8292
|
+
}
|
|
8200
8293
|
return tokens;
|
|
8201
8294
|
}
|
|
8202
8295
|
|
|
@@ -9411,7 +9504,8 @@ function parseEmphasisToken(tokens, startIndex, options) {
|
|
|
9411
9504
|
}
|
|
9412
9505
|
children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
|
|
9413
9506
|
requireClosingStrong: options?.requireClosingStrong,
|
|
9414
|
-
customHtmlTags: options?.customHtmlTags
|
|
9507
|
+
customHtmlTags: options?.customHtmlTags,
|
|
9508
|
+
validateLink: options?.validateLink
|
|
9415
9509
|
}));
|
|
9416
9510
|
return {
|
|
9417
9511
|
node: {
|
|
@@ -9933,7 +10027,8 @@ function parseStrongToken(tokens, startIndex, raw, options) {
|
|
|
9933
10027
|
}
|
|
9934
10028
|
children.push(...parseInlineTokens(innerTokens, raw, void 0, {
|
|
9935
10029
|
requireClosingStrong: options?.requireClosingStrong,
|
|
9936
|
-
customHtmlTags: options?.customHtmlTags
|
|
10030
|
+
customHtmlTags: options?.customHtmlTags,
|
|
10031
|
+
validateLink: options?.validateLink
|
|
9937
10032
|
}));
|
|
9938
10033
|
return {
|
|
9939
10034
|
node: {
|
|
@@ -10036,6 +10131,28 @@ function countUnescapedAsterisks(str) {
|
|
|
10036
10131
|
}
|
|
10037
10132
|
return count;
|
|
10038
10133
|
}
|
|
10134
|
+
const WORD_CHAR_RE = /[\p{L}\p{N}]/u;
|
|
10135
|
+
const WORD_ONLY_RE = /^[\p{L}\p{N}]+$/u;
|
|
10136
|
+
function isWordChar(ch) {
|
|
10137
|
+
if (!ch) return false;
|
|
10138
|
+
return WORD_CHAR_RE.test(ch);
|
|
10139
|
+
}
|
|
10140
|
+
function isWordOnly(text$1) {
|
|
10141
|
+
if (!text$1) return false;
|
|
10142
|
+
return WORD_ONLY_RE.test(text$1);
|
|
10143
|
+
}
|
|
10144
|
+
function getAsteriskRunInfo(content, start) {
|
|
10145
|
+
let end = start;
|
|
10146
|
+
while (end < content.length && content[end] === "*") end++;
|
|
10147
|
+
const prev = start > 0 ? content[start - 1] : void 0;
|
|
10148
|
+
const next = end < content.length ? content[end] : void 0;
|
|
10149
|
+
return {
|
|
10150
|
+
len: end - start,
|
|
10151
|
+
prev,
|
|
10152
|
+
next,
|
|
10153
|
+
intraword: isWordChar(prev) && isWordChar(next)
|
|
10154
|
+
};
|
|
10155
|
+
}
|
|
10039
10156
|
function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
10040
10157
|
if (!tokens || tokens.length === 0) return [];
|
|
10041
10158
|
const result = [];
|
|
@@ -10127,15 +10244,32 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10127
10244
|
return true;
|
|
10128
10245
|
}
|
|
10129
10246
|
}
|
|
10247
|
+
const runInfo = getAsteriskRunInfo(content, openIdx);
|
|
10130
10248
|
const exec = STRONG_PAIR_RE.exec(content);
|
|
10131
10249
|
let inner = "";
|
|
10132
10250
|
let after = "";
|
|
10133
10251
|
if (exec && typeof exec.index === "number") {
|
|
10134
10252
|
inner = exec[1];
|
|
10135
10253
|
after = content.slice(exec.index + exec[0].length);
|
|
10254
|
+
const closeRunInfo = getAsteriskRunInfo(content, exec.index + exec[0].length - 2);
|
|
10255
|
+
if (runInfo.intraword && closeRunInfo.intraword && !isWordOnly(inner)) {
|
|
10256
|
+
pushText(content.slice(beforeText.length), content.slice(beforeText.length));
|
|
10257
|
+
i++;
|
|
10258
|
+
return true;
|
|
10259
|
+
}
|
|
10260
|
+
if (!inner && runInfo.len >= 4 && runInfo.intraword) {
|
|
10261
|
+
pushText(content.slice(beforeText.length), content.slice(beforeText.length));
|
|
10262
|
+
i++;
|
|
10263
|
+
return true;
|
|
10264
|
+
}
|
|
10136
10265
|
} else {
|
|
10137
10266
|
if (requireClosingStrong) {
|
|
10138
|
-
pushText(content, content);
|
|
10267
|
+
pushText(content.slice(beforeText.length), content.slice(beforeText.length));
|
|
10268
|
+
i++;
|
|
10269
|
+
return true;
|
|
10270
|
+
}
|
|
10271
|
+
if (runInfo.intraword) {
|
|
10272
|
+
pushText(content.slice(beforeText.length), content.slice(beforeText.length));
|
|
10139
10273
|
i++;
|
|
10140
10274
|
return true;
|
|
10141
10275
|
}
|
|
@@ -10201,7 +10335,13 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10201
10335
|
};
|
|
10202
10336
|
result.push(currentTextNode);
|
|
10203
10337
|
}
|
|
10338
|
+
const runInfo = getAsteriskRunInfo(content, idx);
|
|
10204
10339
|
const closeIndex = content.indexOf("*", idx + 1);
|
|
10340
|
+
if (closeIndex === -1 && runInfo.intraword) {
|
|
10341
|
+
pushText(content.slice(idx), content.slice(idx));
|
|
10342
|
+
i++;
|
|
10343
|
+
return true;
|
|
10344
|
+
}
|
|
10205
10345
|
const { node } = parseEmphasisToken([
|
|
10206
10346
|
{
|
|
10207
10347
|
type: "em_open",
|
|
@@ -10497,7 +10637,11 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10497
10637
|
i++;
|
|
10498
10638
|
break;
|
|
10499
10639
|
default:
|
|
10500
|
-
|
|
10640
|
+
if (token.type === "link" && token.href != null && options?.validateLink && !options.validateLink(token.href)) {
|
|
10641
|
+
resetCurrentTextNode();
|
|
10642
|
+
const displayText = String(token.text ?? "");
|
|
10643
|
+
pushText(displayText, displayText);
|
|
10644
|
+
} else pushToken(token);
|
|
10501
10645
|
i++;
|
|
10502
10646
|
break;
|
|
10503
10647
|
}
|
|
@@ -10577,6 +10721,10 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10577
10721
|
resetCurrentTextNode();
|
|
10578
10722
|
const { node, nextIndex } = parseLinkToken(tokens, i, { requireClosingStrong });
|
|
10579
10723
|
i = nextIndex;
|
|
10724
|
+
if (options?.validateLink && !options.validateLink(node.href)) {
|
|
10725
|
+
pushText(node.text, node.text);
|
|
10726
|
+
return;
|
|
10727
|
+
}
|
|
10580
10728
|
const hrefAttr = token.attrs?.find(([name]) => name === "href")?.[1];
|
|
10581
10729
|
const hrefStr = String(hrefAttr ?? "");
|
|
10582
10730
|
if (raw && hrefStr) {
|
|
@@ -10630,9 +10778,11 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10630
10778
|
loading$1 = false;
|
|
10631
10779
|
} else if (last?.type === "text" && last.content === ".") i++;
|
|
10632
10780
|
if (textNodeContent) pushText(textNodeContent, textNodeContent);
|
|
10633
|
-
|
|
10781
|
+
const hrefFromToken = String(textToken$1.content ?? "");
|
|
10782
|
+
if (options?.validateLink && !options.validateLink(hrefFromToken)) pushText(text$1, text$1);
|
|
10783
|
+
else pushParsed({
|
|
10634
10784
|
type: "link",
|
|
10635
|
-
href:
|
|
10785
|
+
href: hrefFromToken,
|
|
10636
10786
|
title: null,
|
|
10637
10787
|
text: text$1,
|
|
10638
10788
|
children: [{
|
|
@@ -10723,7 +10873,8 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
10723
10873
|
const { node } = parseEmphasisToken(newTokens, 0, options);
|
|
10724
10874
|
pushNode(node);
|
|
10725
10875
|
}
|
|
10726
|
-
} else
|
|
10876
|
+
} else if (options?.validateLink && !options.validateLink(href)) pushText(text$1, text$1);
|
|
10877
|
+
else pushParsed({
|
|
10727
10878
|
type: "link",
|
|
10728
10879
|
href,
|
|
10729
10880
|
title: null,
|
|
@@ -10866,7 +11017,8 @@ function parseList(tokens, index, options) {
|
|
|
10866
11017
|
type: "paragraph",
|
|
10867
11018
|
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken, {
|
|
10868
11019
|
requireClosingStrong: options?.requireClosingStrong,
|
|
10869
|
-
customHtmlTags: options?.customHtmlTags
|
|
11020
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11021
|
+
validateLink: options?.validateLink
|
|
10870
11022
|
}),
|
|
10871
11023
|
raw: String(contentToken.content ?? "")
|
|
10872
11024
|
});
|
|
@@ -10923,7 +11075,8 @@ function parseAdmonition(tokens, index, match, options) {
|
|
|
10923
11075
|
type: "paragraph",
|
|
10924
11076
|
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
10925
11077
|
requireClosingStrong: options?.requireClosingStrong,
|
|
10926
|
-
customHtmlTags: options?.customHtmlTags
|
|
11078
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11079
|
+
validateLink: options?.validateLink
|
|
10927
11080
|
}),
|
|
10928
11081
|
raw: String(contentToken.content ?? "")
|
|
10929
11082
|
});
|
|
@@ -10995,7 +11148,8 @@ function parseContainer(tokens, index, options) {
|
|
|
10995
11148
|
type: "paragraph",
|
|
10996
11149
|
children: parseInlineTokens(_children || [], void 0, void 0, {
|
|
10997
11150
|
requireClosingStrong: options?.requireClosingStrong,
|
|
10998
|
-
customHtmlTags: options?.customHtmlTags
|
|
11151
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11152
|
+
validateLink: options?.validateLink
|
|
10999
11153
|
}),
|
|
11000
11154
|
raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
|
|
11001
11155
|
});
|
|
@@ -11052,7 +11206,8 @@ function parseBlockquote(tokens, index, options) {
|
|
|
11052
11206
|
type: "paragraph",
|
|
11053
11207
|
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
11054
11208
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11055
|
-
customHtmlTags: options?.customHtmlTags
|
|
11209
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11210
|
+
validateLink: options?.validateLink
|
|
11056
11211
|
}),
|
|
11057
11212
|
raw: String(contentToken.content ?? "")
|
|
11058
11213
|
});
|
|
@@ -11116,7 +11271,8 @@ function parseDefinitionList(tokens, index, options) {
|
|
|
11116
11271
|
const termToken = tokens[j + 1];
|
|
11117
11272
|
termNodes = parseInlineTokens(termToken.children || [], void 0, void 0, {
|
|
11118
11273
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11119
|
-
customHtmlTags: options?.customHtmlTags
|
|
11274
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11275
|
+
validateLink: options?.validateLink
|
|
11120
11276
|
});
|
|
11121
11277
|
j += 3;
|
|
11122
11278
|
} else if (tokens[j].type === "dd_open") {
|
|
@@ -11128,7 +11284,8 @@ function parseDefinitionList(tokens, index, options) {
|
|
|
11128
11284
|
type: "paragraph",
|
|
11129
11285
|
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
11130
11286
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11131
|
-
customHtmlTags: options?.customHtmlTags
|
|
11287
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11288
|
+
validateLink: options?.validateLink
|
|
11132
11289
|
}),
|
|
11133
11290
|
raw: String(contentToken.content ?? "")
|
|
11134
11291
|
});
|
|
@@ -11167,7 +11324,8 @@ function parseFootnote(tokens, index, options) {
|
|
|
11167
11324
|
type: "paragraph",
|
|
11168
11325
|
children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
|
|
11169
11326
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11170
|
-
customHtmlTags: options?.customHtmlTags
|
|
11327
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11328
|
+
validateLink: options?.validateLink
|
|
11171
11329
|
}),
|
|
11172
11330
|
raw: String(contentToken.content ?? "")
|
|
11173
11331
|
});
|
|
@@ -11198,7 +11356,8 @@ function parseHeading(tokens, index, options) {
|
|
|
11198
11356
|
...attrsRecord ? { attrs: attrsRecord } : {},
|
|
11199
11357
|
children: parseInlineTokens(headingContentToken.children || [], headingContent, void 0, {
|
|
11200
11358
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11201
|
-
customHtmlTags: options?.customHtmlTags
|
|
11359
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11360
|
+
validateLink: options?.validateLink
|
|
11202
11361
|
}),
|
|
11203
11362
|
raw: headingContent
|
|
11204
11363
|
};
|
|
@@ -11313,7 +11472,8 @@ function parseTable(tokens, index, options) {
|
|
|
11313
11472
|
header: isHeaderCell || isHeader,
|
|
11314
11473
|
children: parseInlineTokens(contentToken.children || [], content, void 0, {
|
|
11315
11474
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11316
|
-
customHtmlTags: options?.customHtmlTags
|
|
11475
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11476
|
+
validateLink: options?.validateLink
|
|
11317
11477
|
}),
|
|
11318
11478
|
raw: content,
|
|
11319
11479
|
align
|
|
@@ -11413,7 +11573,8 @@ function parseVmrContainer(tokens, index, options) {
|
|
|
11413
11573
|
type: "paragraph",
|
|
11414
11574
|
children: parseInlineTokens(childrenArr || [], void 0, void 0, {
|
|
11415
11575
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11416
|
-
customHtmlTags: options?.customHtmlTags
|
|
11576
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11577
|
+
validateLink: options?.validateLink
|
|
11417
11578
|
}),
|
|
11418
11579
|
raw: String(contentToken.content ?? "")
|
|
11419
11580
|
});
|
|
@@ -11676,7 +11837,8 @@ function parseParagraph(tokens, index, options) {
|
|
|
11676
11837
|
type: "paragraph",
|
|
11677
11838
|
children: parseInlineTokens(paragraphContentToken.children || [], paragraphContent, void 0, {
|
|
11678
11839
|
requireClosingStrong: options?.requireClosingStrong,
|
|
11679
|
-
customHtmlTags: options?.customHtmlTags
|
|
11840
|
+
customHtmlTags: options?.customHtmlTags,
|
|
11841
|
+
validateLink: options?.validateLink
|
|
11680
11842
|
}),
|
|
11681
11843
|
raw: paragraphContent
|
|
11682
11844
|
};
|
|
@@ -12010,6 +12172,87 @@ function normalizeCustomHtmlOpeningTagSameLine(markdown, tags) {
|
|
|
12010
12172
|
}
|
|
12011
12173
|
return out;
|
|
12012
12174
|
}
|
|
12175
|
+
function ensureBlankLineAfterCustomHtmlCloseBeforeBlockMarkerSameLine(markdown, tags) {
|
|
12176
|
+
if (!markdown || !tags.length) return markdown;
|
|
12177
|
+
const tagSet = new Set(tags.map((t) => String(t ?? "").toLowerCase()));
|
|
12178
|
+
if (!tagSet.size) return markdown;
|
|
12179
|
+
const isIndentWs = (ch) => ch === " " || ch === " ";
|
|
12180
|
+
const parseBlockquotePrefix = (rawLine) => {
|
|
12181
|
+
let i = 0;
|
|
12182
|
+
let saw = false;
|
|
12183
|
+
let prefixEnd = 0;
|
|
12184
|
+
while (i < rawLine.length) {
|
|
12185
|
+
while (i < rawLine.length && isIndentWs(rawLine[i])) i++;
|
|
12186
|
+
if (i >= rawLine.length || rawLine[i] !== ">") break;
|
|
12187
|
+
saw = true;
|
|
12188
|
+
i++;
|
|
12189
|
+
while (i < rawLine.length && isIndentWs(rawLine[i])) i++;
|
|
12190
|
+
prefixEnd = i;
|
|
12191
|
+
}
|
|
12192
|
+
if (!saw) return null;
|
|
12193
|
+
return {
|
|
12194
|
+
prefix: rawLine.slice(0, prefixEnd),
|
|
12195
|
+
content: rawLine.slice(prefixEnd)
|
|
12196
|
+
};
|
|
12197
|
+
};
|
|
12198
|
+
const parseFenceMarker = (line) => {
|
|
12199
|
+
let i = 0;
|
|
12200
|
+
while (i < line.length && isIndentWs(line[i])) i++;
|
|
12201
|
+
const ch = line[i];
|
|
12202
|
+
if (ch !== "`" && ch !== "~") return null;
|
|
12203
|
+
let j = i;
|
|
12204
|
+
while (j < line.length && line[j] === ch) j++;
|
|
12205
|
+
const len = j - i;
|
|
12206
|
+
if (len < 3) return null;
|
|
12207
|
+
return {
|
|
12208
|
+
markerChar: ch,
|
|
12209
|
+
markerLen: len,
|
|
12210
|
+
rest: line.slice(j)
|
|
12211
|
+
};
|
|
12212
|
+
};
|
|
12213
|
+
const closeTagRes = Array.from(tagSet).map((tag) => {
|
|
12214
|
+
return new RegExp(String.raw`(<\s*\/\s*${tag}\s*>)${"(?=[\\t ]*(?:#{1,6}[\\t ]+|>|(?:[*+-]|\\d+[.)])[\\t ]+|(?:`{3,}|~{3,})|\\||\\$\\$|:{3,}|\\[\\^[^\\]]+\\]:|(?:-{3,}|\\*{3,}|_{3,})))"}`, "gi");
|
|
12215
|
+
});
|
|
12216
|
+
let inFence = false;
|
|
12217
|
+
let fenceChar = "";
|
|
12218
|
+
let fenceLen = 0;
|
|
12219
|
+
let out = "";
|
|
12220
|
+
let idx = 0;
|
|
12221
|
+
while (idx < markdown.length) {
|
|
12222
|
+
const nl = markdown.indexOf("\n", idx);
|
|
12223
|
+
const hasNl = nl !== -1;
|
|
12224
|
+
const isCrlf = hasNl && nl > idx && markdown[nl - 1] === "\r";
|
|
12225
|
+
const lineEnd = hasNl ? isCrlf ? nl - 1 : nl : markdown.length;
|
|
12226
|
+
const rawLine = markdown.slice(idx, lineEnd);
|
|
12227
|
+
const newline$1 = hasNl ? isCrlf ? "\r\n" : "\n" : "";
|
|
12228
|
+
const bq = parseBlockquotePrefix(rawLine);
|
|
12229
|
+
const prefix = bq?.prefix ?? "";
|
|
12230
|
+
const contentLine = bq?.content ?? rawLine;
|
|
12231
|
+
const fenceMatch = parseFenceMarker(contentLine);
|
|
12232
|
+
if (fenceMatch) if (inFence) {
|
|
12233
|
+
if (fenceMatch.markerChar === fenceChar && fenceMatch.markerLen >= fenceLen) {
|
|
12234
|
+
if (/^\s*$/.test(fenceMatch.rest)) {
|
|
12235
|
+
inFence = false;
|
|
12236
|
+
fenceChar = "";
|
|
12237
|
+
fenceLen = 0;
|
|
12238
|
+
}
|
|
12239
|
+
}
|
|
12240
|
+
} else {
|
|
12241
|
+
inFence = true;
|
|
12242
|
+
fenceChar = fenceMatch.markerChar;
|
|
12243
|
+
fenceLen = fenceMatch.markerLen;
|
|
12244
|
+
}
|
|
12245
|
+
let nextContent = contentLine;
|
|
12246
|
+
if (!inFence && nextContent.includes("</")) for (const re of closeTagRes) nextContent = nextContent.replace(re, "$1\n\n");
|
|
12247
|
+
if (prefix) {
|
|
12248
|
+
const withPrefix = prefix + nextContent.split("\n").join(`\n${prefix}`);
|
|
12249
|
+
out += withPrefix;
|
|
12250
|
+
} else out += nextContent;
|
|
12251
|
+
out += newline$1;
|
|
12252
|
+
idx = hasNl ? nl + 1 : markdown.length;
|
|
12253
|
+
}
|
|
12254
|
+
return out;
|
|
12255
|
+
}
|
|
12013
12256
|
function ensureBlankLineBeforeCustomHtmlBlocks(markdown, tags) {
|
|
12014
12257
|
if (!markdown || !tags.length) return markdown;
|
|
12015
12258
|
const tagSet = new Set(tags.map((t) => String(t ?? "").toLowerCase()));
|
|
@@ -12243,6 +12486,7 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
12243
12486
|
if (tags.length) {
|
|
12244
12487
|
safeMarkdown = normalizeCustomHtmlOpeningTagSameLine(safeMarkdown, tags);
|
|
12245
12488
|
safeMarkdown = ensureBlankLineBeforeCustomHtmlBlocks(safeMarkdown, tags);
|
|
12489
|
+
safeMarkdown = ensureBlankLineAfterCustomHtmlCloseBeforeBlockMarkerSameLine(safeMarkdown, tags);
|
|
12246
12490
|
if (!safeMarkdown.includes("</")) {} else for (const tag of tags) {
|
|
12247
12491
|
const re = new RegExp(String.raw`(^[\t ]*<\s*\/\s*${tag}\s*>[\t ]*)(\r?\n)(?![\t ]*\r?\n|$)`, "gim");
|
|
12248
12492
|
safeMarkdown = safeMarkdown.replace(re, "$1$2$2");
|
|
@@ -12256,8 +12500,11 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
|
|
|
12256
12500
|
const post = options.postTransformTokens;
|
|
12257
12501
|
let transformedTokens = tokens;
|
|
12258
12502
|
if (pre && typeof pre === "function") transformedTokens = pre(transformedTokens) || transformedTokens;
|
|
12503
|
+
const mdAny = md;
|
|
12504
|
+
const validateLink$1 = options.validateLink ?? mdAny.options?.validateLink ?? (typeof mdAny.validateLink === "function" ? mdAny.validateLink : void 0);
|
|
12259
12505
|
const internalOptions = {
|
|
12260
12506
|
...options,
|
|
12507
|
+
validateLink: validateLink$1,
|
|
12261
12508
|
__sourceMarkdown: safeMarkdown,
|
|
12262
12509
|
__customHtmlBlockCursor: 0
|
|
12263
12510
|
};
|
|
@@ -12337,7 +12584,8 @@ function processTokens(tokens, options) {
|
|
|
12337
12584
|
{
|
|
12338
12585
|
const parsed = parseInlineTokens(token.children || [], String(token.content ?? ""), void 0, {
|
|
12339
12586
|
requireClosingStrong: options?.requireClosingStrong,
|
|
12340
|
-
customHtmlTags: options?.customHtmlTags
|
|
12587
|
+
customHtmlTags: options?.customHtmlTags,
|
|
12588
|
+
validateLink: options?.validateLink
|
|
12341
12589
|
});
|
|
12342
12590
|
if (parsed.length === 0) {} else if (parsed.every((n) => n.type === "html_block")) result.push(...parsed);
|
|
12343
12591
|
else result.push({
|