@anyblock/remark-any-block 1.0.0-beta10 → 1.0.0-beta11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/anyblock.ts +63 -75
- package/dist/remark-any-block.cjs +2559 -1020
- package/dist/remark-any-block.js +2559 -1020
- package/index.ts +1 -1
- package/package.json +1 -1
package/anyblock.ts
CHANGED
|
@@ -54,15 +54,18 @@ export interface AnyBlockOptions {
|
|
|
54
54
|
*/
|
|
55
55
|
function matchAbHeader(node: RootContent): string | null {
|
|
56
56
|
if (node.type !== "paragraph") return null;
|
|
57
|
+
|
|
57
58
|
const text = (node.children as RootContent[])
|
|
58
59
|
.map((c) => (c.type === "text" ? (c as Text).value : ""))
|
|
59
60
|
.join("");
|
|
60
|
-
const
|
|
61
|
-
|
|
61
|
+
const match = text.match(ABReg.reg_header_noprefix);
|
|
62
|
+
if (!match || !match.length) return null
|
|
63
|
+
|
|
64
|
+
return match[5]
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
/**
|
|
65
|
-
* 检测 `:::container`
|
|
68
|
+
* 检测 `:::container` 首段落
|
|
66
69
|
* 匹配时返回 `{flag, type}`
|
|
67
70
|
*/
|
|
68
71
|
function matchContainerStart(node: RootContent):
|
|
@@ -79,9 +82,9 @@ function matchContainerStart(node: RootContent):
|
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
/**
|
|
82
|
-
*
|
|
85
|
+
* 检测 `:::container` 尾段落
|
|
83
86
|
*/
|
|
84
|
-
function
|
|
87
|
+
function matchContainerEnd(node: RootContent, flag: string): boolean {
|
|
85
88
|
if (node.type !== "paragraph") return false;
|
|
86
89
|
const text = (node.children as RootContent[])
|
|
87
90
|
.map((c) => (c.type === "text" ? (c as Text).value : ""))
|
|
@@ -91,7 +94,7 @@ function isContainerEnd(node: RootContent, flag: string): boolean {
|
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
/**
|
|
94
|
-
* 将一组 mdast
|
|
97
|
+
* 将一组 mdast 节点反序列化为 markdown 格式
|
|
95
98
|
*/
|
|
96
99
|
function nodesToMarkdown(nodes: RootContent[]): string {
|
|
97
100
|
return toMarkdown(
|
|
@@ -107,86 +110,73 @@ function nodesToMarkdown(nodes: RootContent[]): string {
|
|
|
107
110
|
* - `:::type ... :::`
|
|
108
111
|
*/
|
|
109
112
|
export const remark_anyblock_to_codeblock: Plugin<[Partial<AnyBlockOptions>?], Root> =
|
|
110
|
-
(_options = {}) =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
(_options = {}) => (tree) =>
|
|
114
|
+
{
|
|
115
|
+
const children = [...tree.children] as RootContent[];
|
|
116
|
+
|
|
117
|
+
const out: RootContent[] = [];
|
|
118
|
+
for (let i = 0; i < children.length; i++) {
|
|
119
|
+
const node = children[i];
|
|
120
|
+
|
|
121
|
+
// step1. 检测 `[]` 语法
|
|
122
|
+
const header = matchAbHeader(node);
|
|
123
|
+
if (header) {
|
|
124
|
+
const node_next = children[i+1];
|
|
125
|
+
if (
|
|
126
|
+
node_next.type === "list" ||
|
|
127
|
+
node_next.type === "heading" ||
|
|
128
|
+
node_next.type === "code" ||
|
|
129
|
+
node_next.type === "blockquote" ||
|
|
130
|
+
node_next.type === "table"
|
|
131
|
+
) {
|
|
132
|
+
const codeValue = `[${header}]\n${nodesToMarkdown([node_next])}`;
|
|
133
|
+
out.push({
|
|
134
|
+
type: "code",
|
|
135
|
+
lang: "anyblock",
|
|
136
|
+
value: codeValue,
|
|
137
|
+
data: { markup: "[]" },
|
|
138
|
+
} as Code);
|
|
139
|
+
i++; continue;
|
|
140
|
+
} else {}
|
|
141
|
+
}
|
|
117
142
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
n.type === "list" ||
|
|
127
|
-
n.type === "heading" ||
|
|
128
|
-
n.type === "code" ||
|
|
129
|
-
n.type === "blockquote" ||
|
|
130
|
-
n.type === "table"
|
|
131
|
-
) {
|
|
132
|
-
body.push(n);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
// stop when first non-matching block is hit
|
|
143
|
+
// step2. 检测 `:::` 语法
|
|
144
|
+
const container = matchContainerStart(node);
|
|
145
|
+
if (container) {
|
|
146
|
+
const body: RootContent[] = [];
|
|
147
|
+
let j = i + 1;
|
|
148
|
+
for (; j < children.length; j++) {
|
|
149
|
+
const n = children[j];
|
|
150
|
+
if (matchContainerEnd(n, container.flag)) {
|
|
136
151
|
break;
|
|
137
152
|
}
|
|
138
|
-
|
|
139
|
-
const codeValue = `[${header}]\n${nodesToMarkdown(body)}`;
|
|
140
|
-
out.push({
|
|
141
|
-
type: "code",
|
|
142
|
-
lang: "AnyBlock",
|
|
143
|
-
value: codeValue,
|
|
144
|
-
data: { markup: "[]" },
|
|
145
|
-
} as Code);
|
|
146
|
-
i = j - 1;
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
153
|
+
body.push(n);
|
|
149
154
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
body.push(n);
|
|
162
|
-
}
|
|
163
|
-
if (j < children.length) {
|
|
164
|
-
const codeValue = `[${container.type}]\n${nodesToMarkdown(body)}`;
|
|
165
|
-
out.push({
|
|
166
|
-
type: "code",
|
|
167
|
-
lang: "AnyBlock",
|
|
168
|
-
value: codeValue,
|
|
169
|
-
data: { markup: container.flag },
|
|
170
|
-
} as Code);
|
|
171
|
-
i = j; // skip closing line
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
155
|
+
if (j < children.length) {
|
|
156
|
+
const codeValue = `[${container.type}]\n${nodesToMarkdown(body)}`;
|
|
157
|
+
out.push({
|
|
158
|
+
type: "code",
|
|
159
|
+
lang: "anyblock",
|
|
160
|
+
value: codeValue,
|
|
161
|
+
data: { markup: container.flag },
|
|
162
|
+
} as Code);
|
|
163
|
+
i = j; continue;
|
|
174
164
|
}
|
|
175
|
-
|
|
176
|
-
// default passthrough
|
|
177
|
-
out.push(node);
|
|
178
165
|
}
|
|
179
166
|
|
|
180
|
-
|
|
167
|
+
// step3. 不处理的节点,保持不变
|
|
168
|
+
out.push(node)
|
|
181
169
|
}
|
|
182
170
|
|
|
171
|
+
(tree as Root).children = out;
|
|
172
|
+
}
|
|
173
|
+
|
|
183
174
|
// 渲染 anyblock 代码块
|
|
184
175
|
export const remark_anyblock_render_codeblock = () => {
|
|
185
176
|
if (typeof document == "undefined") return
|
|
186
177
|
return (tree: Root, _file: VFile) => {
|
|
187
178
|
visit(tree, "code", (node: Code, index: number|undefined, parent: any|undefined) => { // 遍历所有的 code 类型节点
|
|
188
|
-
|
|
189
|
-
if (node.lang != "anyblock") return
|
|
179
|
+
if (node.lang.toLowerCase() != "anyblock") return
|
|
190
180
|
if (!parent || !index) return
|
|
191
181
|
|
|
192
182
|
const lines = node.value.split("\n")
|
|
@@ -203,8 +193,6 @@ export const remark_anyblock_render_codeblock = () => {
|
|
|
203
193
|
ABConvertManager.autoABConvert(el, header, content, markup.startsWith(":::") ? "mdit" : "");
|
|
204
194
|
|
|
205
195
|
// new node
|
|
206
|
-
console.log("\nanyblock codeblock transformer visit2:", header, 'c==', content)
|
|
207
|
-
console.log("\nanyblock codeblock transformer visit3:", el.outerHTML, el)
|
|
208
196
|
const new_node: Html = {
|
|
209
197
|
type: 'html',
|
|
210
198
|
value: el.outerHTML,
|
|
@@ -245,7 +233,7 @@ export const transformer_anyblock: QuartzTransformerPlugin = (/*options: any*/)
|
|
|
245
233
|
name: "AnyBlock",
|
|
246
234
|
markdownPlugins(_ctx: BuildCtx) {
|
|
247
235
|
return [
|
|
248
|
-
|
|
236
|
+
remark_anyblock_to_codeblock,
|
|
249
237
|
remark_anyblock_render_codeblock, // last
|
|
250
238
|
]
|
|
251
239
|
},
|