fix: parsing issues

This commit is contained in:
hypercross 2026-03-26 11:46:33 +08:00
parent faf179a4fd
commit 0aaf81057a
2 changed files with 43 additions and 12 deletions

View File

@ -61,7 +61,13 @@ const marked = new Marked()
const match = rule.exec(src);
if (match) {
const yamlContent = match[1]?.trim() || '';
const props = yaml.load(yamlContent) as Record<string, unknown> || {};
let props: Record<string, unknown> = {};
try {
props = (yaml.load(yamlContent) as Record<string, unknown>) || {};
} catch (e) {
console.error("YAML Parse Error in code-block-yaml-tag:", e);
props = { error: "Invalid YAML content" };
}
// 提取 tag 名称,默认为 tag-unknown
const tagName = (props.tag as string) || 'tag-unknown';

View File

@ -87,24 +87,17 @@ class Parser {
while (!this.at("NODE_START")) {
const keyTok = this.take("HEADER_KEY", "Expected node header before '---'");
const valTok = this.take("HEADER_VALUE", "Expected header value");
if (keyTok.text === "title") title = valTok.text.trim();
if (keyTok.text === "tags") {
const raw = valTok.text.trim();
nodeTags = raw.split(/\s+/).filter(Boolean);
}
if (keyTok.text === "when") {
// Each when: header adds one condition (can have multiple when: headers)
const raw = valTok.text.trim();
whenConditions.push(raw);
}
// Capture &css{ ... } styles in any header value
const rawVal = valTok.text.trim();
let finalVal = valTok.text;
if (rawVal.startsWith("&css{")) {
// Collect until closing '}' possibly spanning multiple lines before '---'
let cssContent = rawVal.replace(/^&css\{/, "");
let closed = cssContent.includes("}");
if (closed) {
cssContent = cssContent.split("}")[0];
finalVal = rawVal.replace(/^&css\{[^}]*\}/, "").trim();
} else {
// Consume subsequent TEXT or HEADER_VALUE tokens until we find a '}'
while (!this.at("NODE_START") && !this.at("EOF")) {
@ -114,6 +107,7 @@ class Parser {
if (t.includes("}")) {
cssContent += (cssContent ? "\n" : "") + t.split("}")[0];
closed = true;
finalVal = t.split("}").slice(1).join("}").trim();
break;
} else {
cssContent += (cssContent ? "\n" : "") + t;
@ -127,7 +121,18 @@ class Parser {
}
nodeCss = (cssContent || "").trim();
}
headers[keyTok.text] = valTok.text;
if (keyTok.text === "title") title = finalVal.trim();
if (keyTok.text === "tags") {
const raw = finalVal.trim();
nodeTags = raw.split(/\s+/).filter(Boolean);
}
if (keyTok.text === "when") {
// Each when: header adds one condition (can have multiple when: headers)
const raw = finalVal.trim();
whenConditions.push(raw);
}
headers[keyTok.text] = finalVal;
// allow empty lines
while (this.at("EMPTY")) this.i++;
}
@ -156,6 +161,26 @@ class Parser {
while (this.at("EMPTY")) this.i++;
if (this.at(endType) || this.at("EOF")) break;
// Handle plain indentation seamlessly within blocks
if (this.at("INDENT")) {
this.take("INDENT");
while (!this.at("DEDENT") && !this.at(endType) && !this.at("EOF")) {
while (this.at("EMPTY")) this.i++;
if (this.at("DEDENT") || this.at(endType) || this.at("EOF")) break;
if (this.at("OPTION")) {
out.push(this.parseOptionGroup());
continue;
}
out.push(this.parseStatement());
}
if (this.at("DEDENT")) {
this.take("DEDENT");
while (this.at("EMPTY")) this.i++;
}
continue;
}
if (this.at("OPTION")) {
out.push(this.parseOptionGroup());
continue;