feat: yaml tag block
This commit is contained in:
parent
2b5bcfff93
commit
19256b501f
|
|
@ -0,0 +1,35 @@
|
||||||
|
# yaml/tag 代码块格式测试
|
||||||
|
|
||||||
|
## 使用 yaml/tag 语法创建 md-deck
|
||||||
|
|
||||||
|
```yaml/tag
|
||||||
|
tag: md-deck
|
||||||
|
body: ./sparks.csv
|
||||||
|
size: 54x86
|
||||||
|
grid: 5x8
|
||||||
|
bleed: 1
|
||||||
|
padding: 2
|
||||||
|
font-size: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用 body 字段添加内容
|
||||||
|
|
||||||
|
```yaml/tag
|
||||||
|
tag: tag-box
|
||||||
|
class: note
|
||||||
|
body: |
|
||||||
|
这是一个提示框
|
||||||
|
```
|
||||||
|
|
||||||
|
## 带引号的值
|
||||||
|
|
||||||
|
```yaml/tag
|
||||||
|
tag: tag-alert
|
||||||
|
type: warning
|
||||||
|
class: my-alert
|
||||||
|
body: 这是一个警告信息
|
||||||
|
```
|
||||||
|
|
||||||
|
## 旧的指令语法仍然可用
|
||||||
|
|
||||||
|
:md-deck[./sparks.csv]{size="54x86" grid="5x8"}
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
"commander": "^12.1.0",
|
"commander": "^12.1.0",
|
||||||
"csv-parse": "^5.5.6",
|
"csv-parse": "^5.5.6",
|
||||||
|
"js-yaml": "^4.1.1",
|
||||||
"marked": "^14.1.0",
|
"marked": "^14.1.0",
|
||||||
"marked-directive": "^1.0.7",
|
"marked-directive": "^1.0.7",
|
||||||
"solid-element": "^1.9.1",
|
"solid-element": "^1.9.1",
|
||||||
|
|
@ -2251,6 +2252,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"license": "Python-2.0"
|
||||||
|
},
|
||||||
"node_modules/attributes-parser": {
|
"node_modules/attributes-parser": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/attributes-parser/-/attributes-parser-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/attributes-parser/-/attributes-parser-2.2.3.tgz",
|
||||||
|
|
@ -2669,6 +2676,18 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jsesc": {
|
"node_modules/jsesc": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
"commander": "^12.1.0",
|
"commander": "^12.1.0",
|
||||||
"csv-parse": "^5.5.6",
|
"csv-parse": "^5.5.6",
|
||||||
|
"js-yaml": "^4.1.1",
|
||||||
"marked": "^14.1.0",
|
"marked": "^14.1.0",
|
||||||
"marked-directive": "^1.0.7",
|
"marked-directive": "^1.0.7",
|
||||||
"solid-element": "^1.9.1",
|
"solid-element": "^1.9.1",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Marked } from 'marked';
|
import { Marked } from 'marked';
|
||||||
import {createDirectives, presetDirectiveConfigs} from 'marked-directive';
|
import {createDirectives, presetDirectiveConfigs} from 'marked-directive';
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
|
||||||
// 使用 marked-directive 来支持指令语法
|
// 使用 marked-directive 来支持指令语法
|
||||||
const marked = new Marked().use(createDirectives([
|
const marked = new Marked().use(createDirectives([
|
||||||
|
|
@ -23,7 +24,63 @@ const marked = new Marked().use(createDirectives([
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]));
|
]), {
|
||||||
|
// 自定义代码块渲染器,支持 yaml/tag 格式
|
||||||
|
extensions: [{
|
||||||
|
name: 'code-block-yaml-tag',
|
||||||
|
level: 'block',
|
||||||
|
start(src: string) {
|
||||||
|
// 检测 ```yaml/tag 开头的代码块
|
||||||
|
return src.match(/^```yaml\/tag\s*\n/m)?.index;
|
||||||
|
},
|
||||||
|
tokenizer(src: string) {
|
||||||
|
const rule = /^```yaml\/tag\s*\n([\s\S]*?)\n```/;
|
||||||
|
const match = rule.exec(src);
|
||||||
|
if (match) {
|
||||||
|
const yamlContent = match[1]?.trim() || '';
|
||||||
|
const props = yaml.load(yamlContent) as Record<string, unknown> || {};
|
||||||
|
|
||||||
|
// 提取 tag 名称,默认为 tag-unknown
|
||||||
|
const tagName = (props.tag as string) || 'tag-unknown';
|
||||||
|
|
||||||
|
// 移除 tag 属性,剩下的作为 HTML 属性
|
||||||
|
const { tag, ...rest } = props;
|
||||||
|
|
||||||
|
// 提取 innerText 内容(如果有 body 字段)
|
||||||
|
let content = '';
|
||||||
|
if ('body' in rest) {
|
||||||
|
content = String(rest.body || '');
|
||||||
|
delete (rest as Record<string, unknown>).body;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建属性字符串
|
||||||
|
const propsStr = Object.entries(rest)
|
||||||
|
.map(([key, value]) => {
|
||||||
|
const strValue = String(value);
|
||||||
|
// 如果值包含空格或特殊字符,添加引号
|
||||||
|
if (strValue.includes(' ') || strValue.includes('"')) {
|
||||||
|
return `${key}="${strValue.replace(/"/g, '"')}"`;
|
||||||
|
}
|
||||||
|
return `${key}="${strValue}"`;
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'code-block-yaml-tag',
|
||||||
|
raw: match[0],
|
||||||
|
tagName,
|
||||||
|
props: propsStr,
|
||||||
|
content
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderer(token: any) {
|
||||||
|
// 渲染为自定义 HTML 标签
|
||||||
|
const propsAttr = token.props ? ` ${token.props}` : '';
|
||||||
|
return `<${token.tagName}${propsAttr}>${token.content || ''}</${token.tagName}>\n`;
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
export function parseMarkdown(content: string): string {
|
export function parseMarkdown(content: string): string {
|
||||||
return marked.parse(content.trimStart()) as string;
|
return marked.parse(content.trimStart()) as string;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue