fix: parsing issues
This commit is contained in:
parent
faf179a4fd
commit
0aaf81057a
|
|
@ -61,7 +61,13 @@ const marked = new Marked()
|
||||||
const match = rule.exec(src);
|
const match = rule.exec(src);
|
||||||
if (match) {
|
if (match) {
|
||||||
const yamlContent = match[1]?.trim() || '';
|
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
|
// 提取 tag 名称,默认为 tag-unknown
|
||||||
const tagName = (props.tag as string) || 'tag-unknown';
|
const tagName = (props.tag as string) || 'tag-unknown';
|
||||||
|
|
|
||||||
|
|
@ -87,24 +87,17 @@ class Parser {
|
||||||
while (!this.at("NODE_START")) {
|
while (!this.at("NODE_START")) {
|
||||||
const keyTok = this.take("HEADER_KEY", "Expected node header before '---'");
|
const keyTok = this.take("HEADER_KEY", "Expected node header before '---'");
|
||||||
const valTok = this.take("HEADER_VALUE", "Expected header value");
|
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
|
// Capture &css{ ... } styles in any header value
|
||||||
const rawVal = valTok.text.trim();
|
const rawVal = valTok.text.trim();
|
||||||
|
let finalVal = valTok.text;
|
||||||
if (rawVal.startsWith("&css{")) {
|
if (rawVal.startsWith("&css{")) {
|
||||||
// Collect until closing '}' possibly spanning multiple lines before '---'
|
// Collect until closing '}' possibly spanning multiple lines before '---'
|
||||||
let cssContent = rawVal.replace(/^&css\{/, "");
|
let cssContent = rawVal.replace(/^&css\{/, "");
|
||||||
let closed = cssContent.includes("}");
|
let closed = cssContent.includes("}");
|
||||||
if (closed) {
|
if (closed) {
|
||||||
cssContent = cssContent.split("}")[0];
|
cssContent = cssContent.split("}")[0];
|
||||||
|
finalVal = rawVal.replace(/^&css\{[^}]*\}/, "").trim();
|
||||||
} else {
|
} else {
|
||||||
// Consume subsequent TEXT or HEADER_VALUE tokens until we find a '}'
|
// Consume subsequent TEXT or HEADER_VALUE tokens until we find a '}'
|
||||||
while (!this.at("NODE_START") && !this.at("EOF")) {
|
while (!this.at("NODE_START") && !this.at("EOF")) {
|
||||||
|
|
@ -114,6 +107,7 @@ class Parser {
|
||||||
if (t.includes("}")) {
|
if (t.includes("}")) {
|
||||||
cssContent += (cssContent ? "\n" : "") + t.split("}")[0];
|
cssContent += (cssContent ? "\n" : "") + t.split("}")[0];
|
||||||
closed = true;
|
closed = true;
|
||||||
|
finalVal = t.split("}").slice(1).join("}").trim();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
cssContent += (cssContent ? "\n" : "") + t;
|
cssContent += (cssContent ? "\n" : "") + t;
|
||||||
|
|
@ -127,7 +121,18 @@ class Parser {
|
||||||
}
|
}
|
||||||
nodeCss = (cssContent || "").trim();
|
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
|
// allow empty lines
|
||||||
while (this.at("EMPTY")) this.i++;
|
while (this.at("EMPTY")) this.i++;
|
||||||
}
|
}
|
||||||
|
|
@ -156,6 +161,26 @@ class Parser {
|
||||||
while (this.at("EMPTY")) this.i++;
|
while (this.at("EMPTY")) this.i++;
|
||||||
if (this.at(endType) || this.at("EOF")) break;
|
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")) {
|
if (this.at("OPTION")) {
|
||||||
out.push(this.parseOptionGroup());
|
out.push(this.parseOptionGroup());
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue