@incremark/core 0.2.3 → 0.2.4
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/detector/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, T as isFootnoteContinuation, S as isFootnoteDefinitionStart, h as isHeading, m as isHtmlBlock, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, u as updateContext } from '../index-
|
|
1
|
+
export { r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, T as isFootnoteContinuation, S as isFootnoteDefinitionStart, h as isHeading, m as isHtmlBlock, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, u as updateContext } from '../index-zDgyJFpf.js';
|
|
2
2
|
import 'mdast';
|
|
3
3
|
import 'micromark-util-types';
|
|
4
4
|
import 'mdast-util-from-markdown';
|
package/dist/detector/index.js
CHANGED
|
@@ -78,7 +78,7 @@ function detectContainer(line, config) {
|
|
|
78
78
|
if (!pattern) {
|
|
79
79
|
const escapedMarker = marker.replace(RE_ESCAPE_SPECIAL, "\\$&");
|
|
80
80
|
pattern = new RegExp(
|
|
81
|
-
`^(\\s*)(${escapedMarker}{${minLength},})(?:\\s
|
|
81
|
+
`^(\\s*)(${escapedMarker}{${minLength},})(?:\\s*(\\w[\\w-]*))?(?:\\{[^}]*\\})?(?:\\s+(.*))?\\s*$`
|
|
82
82
|
);
|
|
83
83
|
containerPatternCache.set(cacheKey, pattern);
|
|
84
84
|
}
|
|
@@ -130,9 +130,17 @@ function createInitialContext() {
|
|
|
130
130
|
listDepth: 0,
|
|
131
131
|
blockquoteDepth: 0,
|
|
132
132
|
inContainer: false,
|
|
133
|
-
containerDepth: 0
|
|
133
|
+
containerDepth: 0,
|
|
134
|
+
inList: false
|
|
134
135
|
};
|
|
135
136
|
}
|
|
137
|
+
function isListContinuation(line, listIndent) {
|
|
138
|
+
if (isEmptyLine(line)) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
const contentIndent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
142
|
+
return contentIndent > listIndent;
|
|
143
|
+
}
|
|
136
144
|
function updateContext(line, context, containerConfig) {
|
|
137
145
|
const newContext = { ...context };
|
|
138
146
|
const containerCfg = containerConfig === true ? {} : containerConfig === false ? void 0 : containerConfig;
|
|
@@ -167,6 +175,7 @@ function updateContext(line, context, containerConfig) {
|
|
|
167
175
|
newContext.containerDepth = context.containerDepth + 1;
|
|
168
176
|
return newContext;
|
|
169
177
|
}
|
|
178
|
+
return newContext;
|
|
170
179
|
} else {
|
|
171
180
|
const container = detectContainer(line, containerCfg);
|
|
172
181
|
if (container && !container.isEnd) {
|
|
@@ -178,6 +187,54 @@ function updateContext(line, context, containerConfig) {
|
|
|
178
187
|
}
|
|
179
188
|
}
|
|
180
189
|
}
|
|
190
|
+
const listItem = isListItemStart(line);
|
|
191
|
+
if (context.inList) {
|
|
192
|
+
if (context.listMayEnd) {
|
|
193
|
+
if (listItem) {
|
|
194
|
+
if (listItem.ordered === context.listOrdered && listItem.indent === context.listIndent) {
|
|
195
|
+
newContext.listMayEnd = false;
|
|
196
|
+
return newContext;
|
|
197
|
+
}
|
|
198
|
+
newContext.inList = true;
|
|
199
|
+
newContext.listOrdered = listItem.ordered;
|
|
200
|
+
newContext.listIndent = listItem.indent;
|
|
201
|
+
newContext.listMayEnd = false;
|
|
202
|
+
return newContext;
|
|
203
|
+
} else if (isListContinuation(line, context.listIndent ?? 0)) {
|
|
204
|
+
newContext.listMayEnd = isEmptyLine(line);
|
|
205
|
+
return newContext;
|
|
206
|
+
} else {
|
|
207
|
+
newContext.inList = false;
|
|
208
|
+
newContext.listOrdered = void 0;
|
|
209
|
+
newContext.listIndent = void 0;
|
|
210
|
+
newContext.listMayEnd = false;
|
|
211
|
+
return newContext;
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
if (listItem) {
|
|
215
|
+
return newContext;
|
|
216
|
+
} else if (isEmptyLine(line)) {
|
|
217
|
+
newContext.listMayEnd = true;
|
|
218
|
+
return newContext;
|
|
219
|
+
} else if (isListContinuation(line, context.listIndent ?? 0)) {
|
|
220
|
+
return newContext;
|
|
221
|
+
} else {
|
|
222
|
+
newContext.inList = false;
|
|
223
|
+
newContext.listOrdered = void 0;
|
|
224
|
+
newContext.listIndent = void 0;
|
|
225
|
+
newContext.listMayEnd = false;
|
|
226
|
+
return newContext;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
if (listItem) {
|
|
231
|
+
newContext.inList = true;
|
|
232
|
+
newContext.listOrdered = listItem.ordered;
|
|
233
|
+
newContext.listIndent = listItem.indent;
|
|
234
|
+
newContext.listMayEnd = false;
|
|
235
|
+
return newContext;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
181
238
|
return newContext;
|
|
182
239
|
}
|
|
183
240
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/detector/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 块类型检测与边界判断\n *\n * Markdown 块级元素的识别规则\n */\n\nimport type { BlockContext, ContainerConfig, ContainerMatch } from '../types'\n\n// ============ 预编译正则表达式(性能优化) ============\n\nconst RE_FENCE_START = /^(\\s*)((`{3,})|(~{3,}))/\nconst RE_EMPTY_LINE = /^\\s*$/\nconst RE_HEADING = /^#{1,6}\\s/\nconst RE_THEMATIC_BREAK = /^(\\*{3,}|-{3,}|_{3,})\\s*$/\nconst RE_UNORDERED_LIST = /^(\\s*)([-*+])\\s/\nconst RE_ORDERED_LIST = /^(\\s*)(\\d{1,9})[.)]\\s/\nconst RE_BLOCKQUOTE = /^\\s{0,3}>/\nconst RE_HTML_BLOCK_1 = /^\\s{0,3}<(script|pre|style|textarea|!--|!DOCTYPE|\\?|!\\[CDATA\\[)/i\nconst RE_HTML_BLOCK_2 = /^\\s{0,3}<\\/?[a-zA-Z][a-zA-Z0-9-]*(\\s|>|$)/\nconst RE_TABLE_DELIMITER = /^\\|?\\s*:?-{3,}:?\\s*(\\|\\s*:?-{3,}:?\\s*)*\\|?$/\nconst RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\\]\\\\]/g\nconst RE_FOOTNOTE_DEFINITION = /^\\[\\^[^\\]]+\\]:\\s/\nconst RE_FOOTNOTE_CONTINUATION = /^(?: |\\t)/\n\n/** fence 结束模式缓存 */\nconst fenceEndPatternCache = new Map<string, RegExp>()\n\n/** 容器模式缓存 */\nconst containerPatternCache = new Map<string, RegExp>()\n\n// ============ 代码块检测 ============\n\n/**\n * 检测行是否是代码块 fence 开始\n */\nexport function detectFenceStart(line: string): { char: string; length: number } | null {\n const match = line.match(RE_FENCE_START)\n if (match) {\n const fence = match[2]\n const char = fence[0]\n return { char, length: fence.length }\n }\n return null\n}\n\n/**\n * 检测行是否是代码块 fence 结束\n */\nexport function detectFenceEnd(line: string, context: BlockContext): boolean {\n if (!context.inFencedCode || !context.fenceChar || !context.fenceLength) {\n return false\n }\n\n // 使用缓存的正则表达式\n const cacheKey = `${context.fenceChar}-${context.fenceLength}`\n let pattern = fenceEndPatternCache.get(cacheKey)\n if (!pattern) {\n pattern = new RegExp(`^\\\\s{0,3}${context.fenceChar}{${context.fenceLength},}\\\\s*$`)\n fenceEndPatternCache.set(cacheKey, pattern)\n }\n return pattern.test(line)\n}\n\n// ============ 行类型检测 ============\n\n/**\n * 检测是否是空行或仅包含空白字符\n */\nexport function isEmptyLine(line: string): boolean {\n return RE_EMPTY_LINE.test(line)\n}\n\n/**\n * 检测是否是标题行\n */\nexport function isHeading(line: string): boolean {\n return RE_HEADING.test(line)\n}\n\n/**\n * 检测是否是 thematic break(水平线)\n */\nexport function isThematicBreak(line: string): boolean {\n return RE_THEMATIC_BREAK.test(line.trim())\n}\n\n/**\n * 检测是否是列表项开始\n */\nexport function isListItemStart(line: string): { ordered: boolean; indent: number } | null {\n // 无序列表: - * +\n const unordered = line.match(RE_UNORDERED_LIST)\n if (unordered) {\n return { ordered: false, indent: unordered[1].length }\n }\n\n // 有序列表: 1. 2) 等\n const ordered = line.match(RE_ORDERED_LIST)\n if (ordered) {\n return { ordered: true, indent: ordered[1].length }\n }\n\n return null\n}\n\n/**\n * 检测是否是引用块开始\n */\nexport function isBlockquoteStart(line: string): boolean {\n return RE_BLOCKQUOTE.test(line)\n}\n\n/**\n * 检测是否是 HTML 块\n */\nexport function isHtmlBlock(line: string): boolean {\n return RE_HTML_BLOCK_1.test(line) || RE_HTML_BLOCK_2.test(line)\n}\n\n/**\n * 检测表格分隔行\n */\nexport function isTableDelimiter(line: string): boolean {\n return RE_TABLE_DELIMITER.test(line.trim())\n}\n\n// ============ 脚注检测 ============\n\n/**\n * 检测是否是脚注定义的起始行\n * 格式: [^id]: content\n * \n * @example\n * isFootnoteDefinitionStart('[^1]: 脚注内容') // true\n * isFootnoteDefinitionStart('[^note]: 内容') // true\n * isFootnoteDefinitionStart(' 缩进内容') // false\n */\nexport function isFootnoteDefinitionStart(line: string): boolean {\n return RE_FOOTNOTE_DEFINITION.test(line)\n}\n\n/**\n * 检测是否是脚注定义的延续行(缩进行)\n * 至少4个空格或1个tab\n * \n * @example\n * isFootnoteContinuation(' 第二行') // true\n * isFootnoteContinuation('\\t第二行') // true\n * isFootnoteContinuation(' 两个空格') // false\n */\nexport function isFootnoteContinuation(line: string): boolean {\n return RE_FOOTNOTE_CONTINUATION.test(line)\n}\n\n// ============ 容器检测 ============\n\n/**\n * 检测容器开始或结束\n *\n * 支持格式:\n * - ::: name 开始\n * - ::: name attr 开始(带属性)\n * - ::: 结束\n * - :::::: name 开始(更长的标记,用于嵌套)\n */\nexport function detectContainer(line: string, config?: ContainerConfig): ContainerMatch | null {\n const marker = config?.marker || ':'\n const minLength = config?.minMarkerLength || 3\n\n // 使用缓存的正则表达式\n const cacheKey = `${marker}-${minLength}`\n let pattern = containerPatternCache.get(cacheKey)\n if (!pattern) {\n const escapedMarker = marker.replace(RE_ESCAPE_SPECIAL, '\\\\$&')\n pattern = new RegExp(\n `^(\\\\s*)(${escapedMarker}{${minLength},})(?:\\\\s+(\\\\w[\\\\w-]*))?(?:\\\\s+(.*))?\\\\s*$`\n )\n containerPatternCache.set(cacheKey, pattern)\n }\n\n const match = line.match(pattern)\n if (!match) {\n return null\n }\n\n const markerLength = match[2].length\n const name = match[3] || ''\n const isEnd = !name && !match[4]\n\n if (!isEnd && config?.allowedNames && config.allowedNames.length > 0) {\n if (!config.allowedNames.includes(name)) {\n return null\n }\n }\n\n return { name, markerLength, isEnd }\n}\n\n/**\n * 检测容器结束\n */\nexport function detectContainerEnd(\n line: string,\n context: BlockContext,\n config?: ContainerConfig\n): boolean {\n if (!context.inContainer || !context.containerMarkerLength) {\n return false\n }\n\n const result = detectContainer(line, config)\n if (!result) {\n return false\n }\n\n return result.isEnd && result.markerLength >= context.containerMarkerLength\n}\n\n// ============ 边界检测 ============\n\n/**\n * 判断两行之间是否构成块边界\n */\nexport function isBlockBoundary(\n prevLine: string,\n currentLine: string,\n context: BlockContext\n): boolean {\n if (context.inFencedCode) {\n return detectFenceEnd(currentLine, context)\n }\n\n if (isEmptyLine(prevLine) && !isEmptyLine(currentLine)) {\n return true\n }\n\n if (isHeading(currentLine) && !isEmptyLine(prevLine)) {\n return true\n }\n\n if (isThematicBreak(currentLine)) {\n return true\n }\n\n if (detectFenceStart(currentLine)) {\n return true\n }\n\n return false\n}\n\n// ============ 上下文管理 ============\n\n/**\n * 创建初始上下文\n */\nexport function createInitialContext(): BlockContext {\n return {\n inFencedCode: false,\n listDepth: 0,\n blockquoteDepth: 0,\n inContainer: false,\n containerDepth: 0\n }\n}\n\n/**\n * 更新上下文(处理一行后)\n */\nexport function updateContext(\n line: string,\n context: BlockContext,\n containerConfig?: ContainerConfig | boolean\n): BlockContext {\n const newContext = { ...context }\n\n const containerCfg =\n containerConfig === true ? {} : containerConfig === false ? undefined : containerConfig\n\n // 代码块优先级最高\n if (context.inFencedCode) {\n if (detectFenceEnd(line, context)) {\n newContext.inFencedCode = false\n newContext.fenceChar = undefined\n newContext.fenceLength = undefined\n }\n return newContext\n }\n\n const fence = detectFenceStart(line)\n if (fence) {\n newContext.inFencedCode = true\n newContext.fenceChar = fence.char\n newContext.fenceLength = fence.length\n return newContext\n }\n\n // 容器处理\n if (containerCfg !== undefined) {\n if (context.inContainer) {\n if (detectContainerEnd(line, context, containerCfg)) {\n newContext.containerDepth = context.containerDepth - 1\n if (newContext.containerDepth === 0) {\n newContext.inContainer = false\n newContext.containerMarkerLength = undefined\n newContext.containerName = undefined\n }\n return newContext\n }\n\n const nested = detectContainer(line, containerCfg)\n if (nested && !nested.isEnd) {\n newContext.containerDepth = context.containerDepth + 1\n return newContext\n }\n } else {\n const container = detectContainer(line, containerCfg)\n if (container && !container.isEnd) {\n newContext.inContainer = true\n newContext.containerMarkerLength = container.markerLength\n newContext.containerName = container.name\n newContext.containerDepth = 1\n return newContext\n }\n }\n }\n\n return newContext\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/detector/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 块类型检测与边界判断\n *\n * Markdown 块级元素的识别规则\n */\n\nimport type { BlockContext, ContainerConfig, ContainerMatch } from '../types'\n\n// ============ 预编译正则表达式(性能优化) ============\n\nconst RE_FENCE_START = /^(\\s*)((`{3,})|(~{3,}))/\nconst RE_EMPTY_LINE = /^\\s*$/\nconst RE_HEADING = /^#{1,6}\\s/\nconst RE_THEMATIC_BREAK = /^(\\*{3,}|-{3,}|_{3,})\\s*$/\nconst RE_UNORDERED_LIST = /^(\\s*)([-*+])\\s/\nconst RE_ORDERED_LIST = /^(\\s*)(\\d{1,9})[.)]\\s/\nconst RE_BLOCKQUOTE = /^\\s{0,3}>/\nconst RE_HTML_BLOCK_1 = /^\\s{0,3}<(script|pre|style|textarea|!--|!DOCTYPE|\\?|!\\[CDATA\\[)/i\nconst RE_HTML_BLOCK_2 = /^\\s{0,3}<\\/?[a-zA-Z][a-zA-Z0-9-]*(\\s|>|$)/\nconst RE_TABLE_DELIMITER = /^\\|?\\s*:?-{3,}:?\\s*(\\|\\s*:?-{3,}:?\\s*)*\\|?$/\nconst RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\\]\\\\]/g\nconst RE_FOOTNOTE_DEFINITION = /^\\[\\^[^\\]]+\\]:\\s/\nconst RE_FOOTNOTE_CONTINUATION = /^(?: |\\t)/\n\n/** fence 结束模式缓存 */\nconst fenceEndPatternCache = new Map<string, RegExp>()\n\n/** 容器模式缓存 */\nconst containerPatternCache = new Map<string, RegExp>()\n\n// ============ 代码块检测 ============\n\n/**\n * 检测行是否是代码块 fence 开始\n */\nexport function detectFenceStart(line: string): { char: string; length: number } | null {\n const match = line.match(RE_FENCE_START)\n if (match) {\n const fence = match[2]\n const char = fence[0]\n return { char, length: fence.length }\n }\n return null\n}\n\n/**\n * 检测行是否是代码块 fence 结束\n */\nexport function detectFenceEnd(line: string, context: BlockContext): boolean {\n if (!context.inFencedCode || !context.fenceChar || !context.fenceLength) {\n return false\n }\n\n // 使用缓存的正则表达式\n const cacheKey = `${context.fenceChar}-${context.fenceLength}`\n let pattern = fenceEndPatternCache.get(cacheKey)\n if (!pattern) {\n pattern = new RegExp(`^\\\\s{0,3}${context.fenceChar}{${context.fenceLength},}\\\\s*$`)\n fenceEndPatternCache.set(cacheKey, pattern)\n }\n return pattern.test(line)\n}\n\n// ============ 行类型检测 ============\n\n/**\n * 检测是否是空行或仅包含空白字符\n */\nexport function isEmptyLine(line: string): boolean {\n return RE_EMPTY_LINE.test(line)\n}\n\n/**\n * 检测是否是标题行\n */\nexport function isHeading(line: string): boolean {\n return RE_HEADING.test(line)\n}\n\n/**\n * 检测是否是 thematic break(水平线)\n */\nexport function isThematicBreak(line: string): boolean {\n return RE_THEMATIC_BREAK.test(line.trim())\n}\n\n/**\n * 检测是否是列表项开始\n */\nexport function isListItemStart(line: string): { ordered: boolean; indent: number } | null {\n // 无序列表: - * +\n const unordered = line.match(RE_UNORDERED_LIST)\n if (unordered) {\n return { ordered: false, indent: unordered[1].length }\n }\n\n // 有序列表: 1. 2) 等\n const ordered = line.match(RE_ORDERED_LIST)\n if (ordered) {\n return { ordered: true, indent: ordered[1].length }\n }\n\n return null\n}\n\n/**\n * 检测是否是引用块开始\n */\nexport function isBlockquoteStart(line: string): boolean {\n return RE_BLOCKQUOTE.test(line)\n}\n\n/**\n * 检测是否是 HTML 块\n */\nexport function isHtmlBlock(line: string): boolean {\n return RE_HTML_BLOCK_1.test(line) || RE_HTML_BLOCK_2.test(line)\n}\n\n/**\n * 检测表格分隔行\n */\nexport function isTableDelimiter(line: string): boolean {\n return RE_TABLE_DELIMITER.test(line.trim())\n}\n\n// ============ 脚注检测 ============\n\n/**\n * 检测是否是脚注定义的起始行\n * 格式: [^id]: content\n * \n * @example\n * isFootnoteDefinitionStart('[^1]: 脚注内容') // true\n * isFootnoteDefinitionStart('[^note]: 内容') // true\n * isFootnoteDefinitionStart(' 缩进内容') // false\n */\nexport function isFootnoteDefinitionStart(line: string): boolean {\n return RE_FOOTNOTE_DEFINITION.test(line)\n}\n\n/**\n * 检测是否是脚注定义的延续行(缩进行)\n * 至少4个空格或1个tab\n * \n * @example\n * isFootnoteContinuation(' 第二行') // true\n * isFootnoteContinuation('\\t第二行') // true\n * isFootnoteContinuation(' 两个空格') // false\n */\nexport function isFootnoteContinuation(line: string): boolean {\n return RE_FOOTNOTE_CONTINUATION.test(line)\n}\n\n// ============ 容器检测 ============\n\n/**\n * 检测容器开始或结束\n *\n * 支持格式:\n * - ::: name 开始\n * - ::: name attr 开始(带属性)\n * - ::: 结束\n * - :::::: name 开始(更长的标记,用于嵌套)\n */\nexport function detectContainer(line: string, config?: ContainerConfig): ContainerMatch | null {\n const marker = config?.marker || ':'\n const minLength = config?.minMarkerLength || 3\n\n // 使用缓存的正则表达式\n const cacheKey = `${marker}-${minLength}`\n let pattern = containerPatternCache.get(cacheKey)\n if (!pattern) {\n const escapedMarker = marker.replace(RE_ESCAPE_SPECIAL, '\\\\$&')\n // 支持两种格式:\n // 1. ::: name attr (有空格分隔)\n // 2. :::name{...} (directive 语法,无空格)\n pattern = new RegExp(\n `^(\\\\s*)(${escapedMarker}{${minLength},})(?:\\\\s*(\\\\w[\\\\w-]*))?(?:\\\\{[^}]*\\\\})?(?:\\\\s+(.*))?\\\\s*$`\n )\n containerPatternCache.set(cacheKey, pattern)\n }\n\n const match = line.match(pattern)\n if (!match) {\n return null\n }\n\n const markerLength = match[2].length\n const name = match[3] || ''\n const isEnd = !name && !match[4]\n\n if (!isEnd && config?.allowedNames && config.allowedNames.length > 0) {\n if (!config.allowedNames.includes(name)) {\n return null\n }\n }\n\n return { name, markerLength, isEnd }\n}\n\n/**\n * 检测容器结束\n */\nexport function detectContainerEnd(\n line: string,\n context: BlockContext,\n config?: ContainerConfig\n): boolean {\n if (!context.inContainer || !context.containerMarkerLength) {\n return false\n }\n\n const result = detectContainer(line, config)\n if (!result) {\n return false\n }\n\n return result.isEnd && result.markerLength >= context.containerMarkerLength\n}\n\n// ============ 边界检测 ============\n\n/**\n * 判断两行之间是否构成块边界\n */\nexport function isBlockBoundary(\n prevLine: string,\n currentLine: string,\n context: BlockContext\n): boolean {\n if (context.inFencedCode) {\n return detectFenceEnd(currentLine, context)\n }\n\n if (isEmptyLine(prevLine) && !isEmptyLine(currentLine)) {\n return true\n }\n\n if (isHeading(currentLine) && !isEmptyLine(prevLine)) {\n return true\n }\n\n if (isThematicBreak(currentLine)) {\n return true\n }\n\n if (detectFenceStart(currentLine)) {\n return true\n }\n\n return false\n}\n\n// ============ 上下文管理 ============\n\n/**\n * 创建初始上下文\n */\nexport function createInitialContext(): BlockContext {\n return {\n inFencedCode: false,\n listDepth: 0,\n blockquoteDepth: 0,\n inContainer: false,\n containerDepth: 0,\n inList: false\n }\n}\n\n/**\n * 检测是否是列表项的延续内容(缩进内容或空行)\n * @param line 当前行\n * @param listIndent 列表的基础缩进\n */\nfunction isListContinuation(line: string, listIndent: number): boolean {\n // 空行可能是列表内部的段落分隔\n if (isEmptyLine(line)) {\n return true\n }\n\n // 检查是否有足够的缩进(列表内容至少需要缩进到列表标记之后)\n // 通常列表标记后至少需要 2 个字符的缩进(如 \"1. \" 或 \"- \")\n const contentIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n return contentIndent > listIndent\n}\n\n/**\n * 更新上下文(处理一行后)\n */\nexport function updateContext(\n line: string,\n context: BlockContext,\n containerConfig?: ContainerConfig | boolean\n): BlockContext {\n const newContext = { ...context }\n\n const containerCfg =\n containerConfig === true ? {} : containerConfig === false ? undefined : containerConfig\n\n // 代码块优先级最高\n if (context.inFencedCode) {\n if (detectFenceEnd(line, context)) {\n newContext.inFencedCode = false\n newContext.fenceChar = undefined\n newContext.fenceLength = undefined\n }\n return newContext\n }\n\n const fence = detectFenceStart(line)\n if (fence) {\n newContext.inFencedCode = true\n newContext.fenceChar = fence.char\n newContext.fenceLength = fence.length\n return newContext\n }\n\n // 容器处理\n if (containerCfg !== undefined) {\n if (context.inContainer) {\n // 检查是否是容器结束\n if (detectContainerEnd(line, context, containerCfg)) {\n newContext.containerDepth = context.containerDepth - 1\n if (newContext.containerDepth === 0) {\n newContext.inContainer = false\n newContext.containerMarkerLength = undefined\n newContext.containerName = undefined\n }\n return newContext\n }\n\n // 检查是否是嵌套容器开始\n const nested = detectContainer(line, containerCfg)\n if (nested && !nested.isEnd) {\n newContext.containerDepth = context.containerDepth + 1\n return newContext\n }\n\n // ⚠️ 关键:在容器内,无论是什么内容(空行、列表、段落等),都保持 inContainer = true\n // 只有容器结束标记才能改变容器状态\n // 这里不需要做任何操作,因为 newContext 已经复制了 context,inContainer 已经是 true\n return newContext\n } else {\n // 不在容器内,检查是否是容器开始\n const container = detectContainer(line, containerCfg)\n if (container && !container.isEnd) {\n newContext.inContainer = true\n newContext.containerMarkerLength = container.markerLength\n newContext.containerName = container.name\n newContext.containerDepth = 1\n return newContext\n }\n }\n }\n\n // 列表处理\n const listItem = isListItemStart(line)\n\n if (context.inList) {\n // 已经在列表中\n if (context.listMayEnd) {\n // 上一行是空行,需要确认列表是否结束\n if (listItem) {\n // 遇到新的列表项\n // 检查是否是同类型列表的延续\n if (listItem.ordered === context.listOrdered && listItem.indent === context.listIndent) {\n // 同类型同级别列表项,列表继续\n newContext.listMayEnd = false\n return newContext\n }\n // 不同类型或不同级别,列表结束,新列表开始\n newContext.inList = true\n newContext.listOrdered = listItem.ordered\n newContext.listIndent = listItem.indent\n newContext.listMayEnd = false\n return newContext\n } else if (isListContinuation(line, context.listIndent ?? 0)) {\n // 缩进内容或空行,列表继续\n newContext.listMayEnd = isEmptyLine(line)\n return newContext\n } else {\n // 非列表内容,列表结束\n newContext.inList = false\n newContext.listOrdered = undefined\n newContext.listIndent = undefined\n newContext.listMayEnd = false\n return newContext\n }\n } else {\n // 上一行不是空行\n if (listItem) {\n // 新列表项(可能是同级或嵌套)\n return newContext\n } else if (isEmptyLine(line)) {\n // 遇到空行,列表可能结束\n newContext.listMayEnd = true\n return newContext\n } else if (isListContinuation(line, context.listIndent ?? 0)) {\n // 缩进内容,列表继续\n return newContext\n } else {\n // 非缩进非列表内容,列表结束\n newContext.inList = false\n newContext.listOrdered = undefined\n newContext.listIndent = undefined\n newContext.listMayEnd = false\n return newContext\n }\n }\n } else {\n // 不在列表中\n if (listItem) {\n // 列表开始\n newContext.inList = true\n newContext.listOrdered = listItem.ordered\n newContext.listIndent = listItem.indent\n newContext.listMayEnd = false\n return newContext\n }\n }\n\n return newContext\n}\n\n"]}
|
|
@@ -273,6 +273,14 @@ interface BlockContext {
|
|
|
273
273
|
containerName?: string;
|
|
274
274
|
/** 容器嵌套深度(支持嵌套容器) */
|
|
275
275
|
containerDepth: number;
|
|
276
|
+
/** 当前是否在列表中 */
|
|
277
|
+
inList: boolean;
|
|
278
|
+
/** 当前列表是否是有序列表 */
|
|
279
|
+
listOrdered?: boolean;
|
|
280
|
+
/** 当前列表的基础缩进 */
|
|
281
|
+
listIndent?: number;
|
|
282
|
+
/** 遇到空行后,列表可能结束(等待下一行确认) */
|
|
283
|
+
listMayEnd?: boolean;
|
|
276
284
|
}
|
|
277
285
|
/**
|
|
278
286
|
* 容器检测结果
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ParserOptions, I as IncrementalUpdate, a as ParsedBlock, D as DefinitionMap, F as FootnoteDefinitionMap, b as ParserState, B as BlockStatus } from './index-
|
|
2
|
-
export { A as AstNode, c as BlockContext, e as BlockTypeInfo, C as ContainerConfig, d as ContainerMatch, J as HTML_ATTR_BLACKLIST, K as HTML_PROTOCOL_BLACKLIST, H as HTML_TAG_BLACKLIST, N as HtmlAttrInfo, R as HtmlContentType, M as HtmlElementNode, Q as HtmlTreeExtensionOptions, O as ParsedHtmlTag, s as createHtmlTreeTransformer, r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, x as detectHtmlContentType, E as findHtmlElementsByTag, G as htmlElementToString, L as htmlTreeExtension, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, h as isHeading, m as isHtmlBlock, y as isHtmlElementNode, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, w as parseHtmlFragment, v as parseHtmlTag, t as transformHtmlNodes, u as updateContext, z as walkHtmlElements } from './index-
|
|
1
|
+
import { P as ParserOptions, I as IncrementalUpdate, a as ParsedBlock, D as DefinitionMap, F as FootnoteDefinitionMap, b as ParserState, B as BlockStatus } from './index-zDgyJFpf.js';
|
|
2
|
+
export { A as AstNode, c as BlockContext, e as BlockTypeInfo, C as ContainerConfig, d as ContainerMatch, J as HTML_ATTR_BLACKLIST, K as HTML_PROTOCOL_BLACKLIST, H as HTML_TAG_BLACKLIST, N as HtmlAttrInfo, R as HtmlContentType, M as HtmlElementNode, Q as HtmlTreeExtensionOptions, O as ParsedHtmlTag, s as createHtmlTreeTransformer, r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, x as detectHtmlContentType, E as findHtmlElementsByTag, G as htmlElementToString, L as htmlTreeExtension, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, h as isHeading, m as isHtmlBlock, y as isHtmlElementNode, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, w as parseHtmlFragment, v as parseHtmlTag, t as transformHtmlNodes, u as updateContext, z as walkHtmlElements } from './index-zDgyJFpf.js';
|
|
3
3
|
import { Root, RootContent, Text } from 'mdast';
|
|
4
4
|
export { Root, RootContent } from 'mdast';
|
|
5
5
|
export { calculateLineOffset, generateId, joinLines, resetIdCounter, splitLines } from './utils/index.js';
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,8 @@ import { factoryLabel } from 'micromark-factory-label';
|
|
|
10
10
|
import { factoryWhitespace } from 'micromark-factory-whitespace';
|
|
11
11
|
import { gfmFootnote } from 'micromark-extension-gfm-footnote';
|
|
12
12
|
import { normalizeIdentifier } from 'micromark-util-normalize-identifier';
|
|
13
|
+
import { directive } from 'micromark-extension-directive';
|
|
14
|
+
import { directiveFromMarkdown } from 'mdast-util-directive';
|
|
13
15
|
|
|
14
16
|
// src/parser/IncremarkParser.ts
|
|
15
17
|
|
|
@@ -938,7 +940,7 @@ function detectContainer(line, config) {
|
|
|
938
940
|
if (!pattern) {
|
|
939
941
|
const escapedMarker = marker.replace(RE_ESCAPE_SPECIAL, "\\$&");
|
|
940
942
|
pattern = new RegExp(
|
|
941
|
-
`^(\\s*)(${escapedMarker}{${minLength},})(?:\\s
|
|
943
|
+
`^(\\s*)(${escapedMarker}{${minLength},})(?:\\s*(\\w[\\w-]*))?(?:\\{[^}]*\\})?(?:\\s+(.*))?\\s*$`
|
|
942
944
|
);
|
|
943
945
|
containerPatternCache.set(cacheKey, pattern);
|
|
944
946
|
}
|
|
@@ -990,9 +992,17 @@ function createInitialContext() {
|
|
|
990
992
|
listDepth: 0,
|
|
991
993
|
blockquoteDepth: 0,
|
|
992
994
|
inContainer: false,
|
|
993
|
-
containerDepth: 0
|
|
995
|
+
containerDepth: 0,
|
|
996
|
+
inList: false
|
|
994
997
|
};
|
|
995
998
|
}
|
|
999
|
+
function isListContinuation(line, listIndent) {
|
|
1000
|
+
if (isEmptyLine(line)) {
|
|
1001
|
+
return true;
|
|
1002
|
+
}
|
|
1003
|
+
const contentIndent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
1004
|
+
return contentIndent > listIndent;
|
|
1005
|
+
}
|
|
996
1006
|
function updateContext(line, context, containerConfig) {
|
|
997
1007
|
const newContext = { ...context };
|
|
998
1008
|
const containerCfg = containerConfig === true ? {} : containerConfig === false ? void 0 : containerConfig;
|
|
@@ -1027,6 +1037,7 @@ function updateContext(line, context, containerConfig) {
|
|
|
1027
1037
|
newContext.containerDepth = context.containerDepth + 1;
|
|
1028
1038
|
return newContext;
|
|
1029
1039
|
}
|
|
1040
|
+
return newContext;
|
|
1030
1041
|
} else {
|
|
1031
1042
|
const container = detectContainer(line, containerCfg);
|
|
1032
1043
|
if (container && !container.isEnd) {
|
|
@@ -1038,6 +1049,54 @@ function updateContext(line, context, containerConfig) {
|
|
|
1038
1049
|
}
|
|
1039
1050
|
}
|
|
1040
1051
|
}
|
|
1052
|
+
const listItem = isListItemStart(line);
|
|
1053
|
+
if (context.inList) {
|
|
1054
|
+
if (context.listMayEnd) {
|
|
1055
|
+
if (listItem) {
|
|
1056
|
+
if (listItem.ordered === context.listOrdered && listItem.indent === context.listIndent) {
|
|
1057
|
+
newContext.listMayEnd = false;
|
|
1058
|
+
return newContext;
|
|
1059
|
+
}
|
|
1060
|
+
newContext.inList = true;
|
|
1061
|
+
newContext.listOrdered = listItem.ordered;
|
|
1062
|
+
newContext.listIndent = listItem.indent;
|
|
1063
|
+
newContext.listMayEnd = false;
|
|
1064
|
+
return newContext;
|
|
1065
|
+
} else if (isListContinuation(line, context.listIndent ?? 0)) {
|
|
1066
|
+
newContext.listMayEnd = isEmptyLine(line);
|
|
1067
|
+
return newContext;
|
|
1068
|
+
} else {
|
|
1069
|
+
newContext.inList = false;
|
|
1070
|
+
newContext.listOrdered = void 0;
|
|
1071
|
+
newContext.listIndent = void 0;
|
|
1072
|
+
newContext.listMayEnd = false;
|
|
1073
|
+
return newContext;
|
|
1074
|
+
}
|
|
1075
|
+
} else {
|
|
1076
|
+
if (listItem) {
|
|
1077
|
+
return newContext;
|
|
1078
|
+
} else if (isEmptyLine(line)) {
|
|
1079
|
+
newContext.listMayEnd = true;
|
|
1080
|
+
return newContext;
|
|
1081
|
+
} else if (isListContinuation(line, context.listIndent ?? 0)) {
|
|
1082
|
+
return newContext;
|
|
1083
|
+
} else {
|
|
1084
|
+
newContext.inList = false;
|
|
1085
|
+
newContext.listOrdered = void 0;
|
|
1086
|
+
newContext.listIndent = void 0;
|
|
1087
|
+
newContext.listMayEnd = false;
|
|
1088
|
+
return newContext;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
} else {
|
|
1092
|
+
if (listItem) {
|
|
1093
|
+
newContext.inList = true;
|
|
1094
|
+
newContext.listOrdered = listItem.ordered;
|
|
1095
|
+
newContext.listIndent = listItem.indent;
|
|
1096
|
+
newContext.listMayEnd = false;
|
|
1097
|
+
return newContext;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1041
1100
|
return newContext;
|
|
1042
1101
|
}
|
|
1043
1102
|
|
|
@@ -1186,6 +1245,10 @@ var IncremarkParser = class {
|
|
|
1186
1245
|
extensions.push(gfm());
|
|
1187
1246
|
mdastExtensions.push(...gfmFromMarkdown(), gfmFootnoteFromMarkdown());
|
|
1188
1247
|
}
|
|
1248
|
+
if (this.containerConfig !== void 0) {
|
|
1249
|
+
extensions.push(directive());
|
|
1250
|
+
mdastExtensions.push(directiveFromMarkdown());
|
|
1251
|
+
}
|
|
1189
1252
|
if (this.options.extensions) {
|
|
1190
1253
|
extensions.push(...this.options.extensions);
|
|
1191
1254
|
}
|
|
@@ -1331,7 +1394,7 @@ var IncremarkParser = class {
|
|
|
1331
1394
|
if (tempContext.inContainer) {
|
|
1332
1395
|
continue;
|
|
1333
1396
|
}
|
|
1334
|
-
const stablePoint = this.checkStability(i);
|
|
1397
|
+
const stablePoint = this.checkStability(i, tempContext);
|
|
1335
1398
|
if (stablePoint >= 0) {
|
|
1336
1399
|
stableLine = stablePoint;
|
|
1337
1400
|
stableContext = { ...tempContext };
|
|
@@ -1339,12 +1402,26 @@ var IncremarkParser = class {
|
|
|
1339
1402
|
}
|
|
1340
1403
|
return { line: stableLine, contextAtLine: stableContext };
|
|
1341
1404
|
}
|
|
1342
|
-
checkStability(lineIndex) {
|
|
1405
|
+
checkStability(lineIndex, context) {
|
|
1343
1406
|
if (lineIndex === 0) {
|
|
1344
1407
|
return -1;
|
|
1345
1408
|
}
|
|
1346
1409
|
const line = this.lines[lineIndex];
|
|
1347
1410
|
const prevLine = this.lines[lineIndex - 1];
|
|
1411
|
+
if (context.inContainer) {
|
|
1412
|
+
if (this.containerConfig !== void 0) {
|
|
1413
|
+
const containerEnd = detectContainerEnd(line, context, this.containerConfig);
|
|
1414
|
+
if (containerEnd) {
|
|
1415
|
+
return lineIndex - 1;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
return -1;
|
|
1419
|
+
}
|
|
1420
|
+
if (context.inList) {
|
|
1421
|
+
if (!context.listMayEnd) {
|
|
1422
|
+
return -1;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1348
1425
|
if (isHeading(prevLine) || isThematicBreak(prevLine)) {
|
|
1349
1426
|
return lineIndex - 1;
|
|
1350
1427
|
}
|
|
@@ -1384,7 +1461,7 @@ var IncremarkParser = class {
|
|
|
1384
1461
|
if (isBlockquoteStart(line) && !isBlockquoteStart(prevLine)) {
|
|
1385
1462
|
return lineIndex - 1;
|
|
1386
1463
|
}
|
|
1387
|
-
if (isListItemStart(line) && !isListItemStart(prevLine)) {
|
|
1464
|
+
if (!context.inList && isListItemStart(line) && !isListItemStart(prevLine)) {
|
|
1388
1465
|
return lineIndex - 1;
|
|
1389
1466
|
}
|
|
1390
1467
|
if (this.containerConfig !== void 0) {
|
|
@@ -1397,7 +1474,7 @@ var IncremarkParser = class {
|
|
|
1397
1474
|
}
|
|
1398
1475
|
}
|
|
1399
1476
|
}
|
|
1400
|
-
if (isEmptyLine(line) && !isEmptyLine(prevLine)) {
|
|
1477
|
+
if (isEmptyLine(line) && !isEmptyLine(prevLine) && !context.inList) {
|
|
1401
1478
|
return lineIndex;
|
|
1402
1479
|
}
|
|
1403
1480
|
return -1;
|