feat: Unify spark table detection and content resolution

Export isSparkTableHeader from content-registry and use it in both CLI
and frontend table parsing. Add resolveContentRef to resolve content
references consistently. Write processed registry content back to the
file index so browser mode renders identically to CLI mode.
This commit is contained in:
hyper
2026-08-07 13:15:51 +08:00
parent 0a68122efd
commit c03528a293
7 changed files with 114 additions and 18 deletions
+18 -13
View File
@@ -7,9 +7,9 @@ import {
createMemo,
createResource,
} from "solid-js";
import { marked } from "../markdown";
import { loadCSV, CSV, processVariables, isCSV } from "./utils/csv-loader";
import { resolvePath } from "./utils/path";
import { parseMarkdown } from "../markdown";
import { loadCSV, CSV, processVariables } from "./utils/csv-loader";
import { resolveContentRef } from "./utils/resolve-content";
import {
areAllLabelsNumeric,
weightedRandomIndex,
@@ -51,13 +51,17 @@ customElement(
const articleEl = element?.closest("article[data-src]");
const articlePath = articleEl?.getAttribute("data-src") || "";
// 如果是 inline CSV,直接使用;否则解析相对路径
const contentOrPath = isCSV(rawContent)
? rawContent
: resolvePath(articlePath, rawContent);
// 使用 createResource 加载 CSV,自动响应路径变化并避免重复加载
const [csvData] = createResource(() => contentOrPath, loadCSV);
// 解析引用:inline CSV 直接使用,否则通过 registry 解析(含内联内容 id)
const [csvData] = createResource(
() => ({ ref: rawContent, docPath: articlePath }),
async ({ ref, docPath }) => {
const content = await resolveContentRef(ref, docPath);
if (content === null) {
throw new Error(`Failed to resolve table content: "${ref}"`);
}
return loadCSV(content);
},
);
// 当数据加载完成后更新 rows
createEffect(() => {
@@ -97,10 +101,11 @@ customElement(
// 处理 body 内容中的 {{prop}} 语法并解析 markdown
const processBody = (body: string, currentRow: TableRow): string => {
// 使用 marked 解析 markdown
return marked.parse(
// 使用 parseMarkdown 统一入口(设置图标 base path 等)
return parseMarkdown(
processVariables(body, currentRow, rows(), filteredRows(), props.remix),
) as string;
articlePath,
);
};
// 更新 body 内容