diff --git a/src/markdown/index.ts b/src/markdown/index.ts
index 8072063..af78697 100644
--- a/src/markdown/index.ts
+++ b/src/markdown/index.ts
@@ -1,8 +1,9 @@
-import { Marked, type MarkedExtension, type Tokens } from 'marked';
+import { Marked, type MarkedExtension } from 'marked';
import {createDirectives, presetDirectiveConfigs} from 'marked-directive';
import yaml from 'js-yaml';
import markedAlert from "marked-alert";
import markedMermaid from "./mermaid";
+import markedTable from "./table";
import {gfmHeadingId} from "marked-gfm-heading-id";
let globalIconPrefix: string | undefined = undefined;
@@ -15,32 +16,12 @@ function overrideIconPrefix(path?: string){
}
}
-/**
- * 将表格数据转换为 CSV 格式字符串
- * @param headers 表头数组
- * @param rows 表格数据行
- * @returns CSV 格式字符串
- */
-function tableToCSV(headers: string[], rows: string[][]): string {
- const escapeCell = (cell: string) => {
- // 如果单元格包含逗号、换行或引号,需要转义
- if (cell.includes(',') || cell.includes('\n') || cell.includes('"')) {
- return `"${cell.replace(/"/g, '""')}"`;
- }
- return cell;
- };
-
- const headerLine = headers.map(escapeCell).join(',');
- const dataLines = rows.map(row => row.map(escapeCell).join(','));
-
- return [headerLine, ...dataLines].join('\n');
-}
-
// 使用 marked-directive 来支持指令语法
const marked = new Marked()
.use(gfmHeadingId())
.use(markedAlert())
.use(markedMermaid())
+ .use(markedTable())
.use(createDirectives([
...presetDirectiveConfigs,
{
@@ -121,36 +102,6 @@ const marked = new Marked()
}]
});
-// 覆盖默认的 table renderer 以支持自动转换
-marked.use({
- renderer: {
- table(token: Tokens.Table) {
- // 检查表头是否包含 md-table-label
- const header = token.header;
- const labelIndex = header.findIndex(cell => cell.text === 'md-table-label');
-
- if (labelIndex !== -1) {
- // 将 md-table-label 列转换为 label
- const headers = header.map(cell => cell.text === 'md-table-label' ? 'label' : cell.text);
-
- // 转换所有行
- const rows = token.rows.map(row =>
- row.map(cell => cell.text)
- );
-
- // 生成 CSV 数据
- const csvData = tableToCSV(headers, rows);
-
- // 渲染为 md-table 组件,内联 CSV 数据
- return `${csvData}\n`;
- }
-
- // 默认表格渲染 - 使用 marked 默认行为
- return false;
- }
- }
-} as MarkedExtension);
-
export function parseMarkdown(content: string, iconPrefix?: string): string {
using prefix = overrideIconPrefix(iconPrefix);
return marked.parse(content.trimStart()) as string;
diff --git a/src/markdown/table.ts b/src/markdown/table.ts
new file mode 100644
index 0000000..effbd7a
--- /dev/null
+++ b/src/markdown/table.ts
@@ -0,0 +1,65 @@
+import type { MarkedExtension, Tokens } from "marked";
+
+/**
+ * 将表格数据转换为 CSV 格式字符串
+ * @param headers 表头数组
+ * @param rows 表格数据行
+ * @returns CSV 格式字符串
+ */
+function tableToCSV(headers: string[], rows: string[][]): string {
+ const escapeCell = (cell: string) => {
+ // 如果单元格包含逗号、换行或引号,需要转义
+ if (cell.includes(',') || cell.includes('\n') || cell.includes('"')) {
+ return `"${cell.replace(/"/g, '""')}"`;
+ }
+ return cell;
+ };
+
+ const headerLine = headers.map(escapeCell).join(',');
+ const dataLines = rows.map(row => row.map(escapeCell).join(','));
+
+ return [headerLine, ...dataLines].join('\n');
+}
+
+export default function markedTable(): MarkedExtension {
+ return {
+ renderer: {
+ table(token: Tokens.Table) {
+ // 检查表头是否包含 md-table-label
+ const header = token.header;
+ const labelIndex = header.findIndex(cell => cell.text === 'md-table-label');
+
+ // 默认表格渲染 - 使用 marked 默认行为
+ if(labelIndex === -1) return false;
+
+ const headers = token.header.map(cell => cell.text);
+ headers[labelIndex] = 'label';
+ const rows = token.rows.map(row => row.map(cell => cell.text));
+
+ if(header.findIndex(header => header.text === 'body') < 0){
+ // 收集所有非 label 列的表头
+ const bodyColumns = header
+ .filter(cell => cell.text !== 'md-table-label')
+ .map(cell => cell.text);
+
+ // 构建 body 列的模板:**列名**:{{列名}}\n\n
+ const bodyTemplate = bodyColumns
+ .map(col => `**${col}**:{{${col}}}`)
+ .join('\n\n');
+
+ headers.push('body');
+ rows.forEach(row => {
+ row.push(bodyTemplate);
+ });
+ }
+
+ // 生成 CSV 数据
+ const csvData = tableToCSV(headers, rows);
+
+ // 渲染为 md-table 组件,内联 CSV 数据
+ console.log(csvData)
+ return `${csvData}\n`;
+ }
+ }
+ };
+}