+5
-2
deno.json
+5
-2
deno.json
···
1
1
{
2
2
"tasks": {
3
-
"dev": "deno run --watch main.ts"
3
+
"dev": "deno run --unstable-broadcast-channel --allow-env --allow-net --allow-read --allow-write --watch main.ts dev"
4
4
},
5
5
"imports": {
6
6
"@cliffy/command": "jsr:@cliffy/command@1.0.0-rc.8",
7
7
"@eta-dev/eta": "jsr:@eta-dev/eta@^3.5.0",
8
8
"@markdoc/markdoc": "https://esm.sh/@markdoc/markdoc@0.5.2",
9
-
"@std/assert": "jsr:@std/assert@1"
9
+
"@std/assert": "jsr:@std/assert@1",
10
+
"@types/hast": "npm:@types/hast@^3.0.4",
11
+
"hast-util-is-element": "npm:hast-util-is-element@^3.0.0",
12
+
"shiki": "npm:shiki@^3.8.1"
10
13
}
11
14
}
+267
-2
deno.lock
+267
-2
deno.lock
···
11
11
"jsr:@std/internal@^1.0.6": "1.0.9",
12
12
"jsr:@std/text@~1.0.7": "1.0.15",
13
13
"npm:@markdoc/markdoc@*": "0.5.2",
14
-
"npm:@types/node@*": "22.15.15"
14
+
"npm:@types/hast@^3.0.4": "3.0.4",
15
+
"npm:@types/node@*": "22.15.15",
16
+
"npm:hast-util-is-element@3": "3.0.0",
17
+
"npm:shiki@^3.8.1": "3.8.1"
15
18
},
16
19
"jsr": {
17
20
"@cliffy/command@1.0.0-rc.8": {
···
66
69
"@types/markdown-it"
67
70
]
68
71
},
72
+
"@shikijs/core@3.8.1": {
73
+
"integrity": "sha512-uTSXzUBQ/IgFcUa6gmGShCHr4tMdR3pxUiiWKDm8pd42UKJdYhkAYsAmHX5mTwybQ5VyGDgTjW4qKSsRvGSang==",
74
+
"dependencies": [
75
+
"@shikijs/types",
76
+
"@shikijs/vscode-textmate",
77
+
"@types/hast",
78
+
"hast-util-to-html"
79
+
]
80
+
},
81
+
"@shikijs/engine-javascript@3.8.1": {
82
+
"integrity": "sha512-rZRp3BM1llrHkuBPAdYAzjlF7OqlM0rm/7EWASeCcY7cRYZIrOnGIHE9qsLz5TCjGefxBFnwgIECzBs2vmOyKA==",
83
+
"dependencies": [
84
+
"@shikijs/types",
85
+
"@shikijs/vscode-textmate",
86
+
"oniguruma-to-es"
87
+
]
88
+
},
89
+
"@shikijs/engine-oniguruma@3.8.1": {
90
+
"integrity": "sha512-KGQJZHlNY7c656qPFEQpIoqOuC4LrxjyNndRdzk5WKB/Ie87+NJCF1xo9KkOUxwxylk7rT6nhlZyTGTC4fCe1g==",
91
+
"dependencies": [
92
+
"@shikijs/types",
93
+
"@shikijs/vscode-textmate"
94
+
]
95
+
},
96
+
"@shikijs/langs@3.8.1": {
97
+
"integrity": "sha512-TjOFg2Wp1w07oKnXjs0AUMb4kJvujML+fJ1C5cmEj45lhjbUXtziT1x2bPQb9Db6kmPhkG5NI2tgYW1/DzhUuQ==",
98
+
"dependencies": [
99
+
"@shikijs/types"
100
+
]
101
+
},
102
+
"@shikijs/themes@3.8.1": {
103
+
"integrity": "sha512-Vu3t3BBLifc0GB0UPg2Pox1naTemrrvyZv2lkiSw3QayVV60me1ujFQwPZGgUTmwXl1yhCPW8Lieesm0CYruLQ==",
104
+
"dependencies": [
105
+
"@shikijs/types"
106
+
]
107
+
},
108
+
"@shikijs/types@3.8.1": {
109
+
"integrity": "sha512-5C39Q8/8r1I26suLh+5TPk1DTrbY/kn3IdWA5HdizR0FhlhD05zx5nKCqhzSfDHH3p4S0ZefxWd77DLV+8FhGg==",
110
+
"dependencies": [
111
+
"@shikijs/vscode-textmate",
112
+
"@types/hast"
113
+
]
114
+
},
115
+
"@shikijs/vscode-textmate@10.0.2": {
116
+
"integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="
117
+
},
118
+
"@types/hast@3.0.4": {
119
+
"integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
120
+
"dependencies": [
121
+
"@types/unist"
122
+
]
123
+
},
69
124
"@types/linkify-it@3.0.5": {
70
125
"integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw=="
71
126
},
···
76
131
"@types/mdurl"
77
132
]
78
133
},
134
+
"@types/mdast@4.0.4": {
135
+
"integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
136
+
"dependencies": [
137
+
"@types/unist"
138
+
]
139
+
},
79
140
"@types/mdurl@2.0.0": {
80
141
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="
81
142
},
···
85
146
"undici-types"
86
147
]
87
148
},
149
+
"@types/unist@3.0.3": {
150
+
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="
151
+
},
152
+
"@ungap/structured-clone@1.3.0": {
153
+
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="
154
+
},
155
+
"ccount@2.0.1": {
156
+
"integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="
157
+
},
158
+
"character-entities-html4@2.1.0": {
159
+
"integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="
160
+
},
161
+
"character-entities-legacy@3.0.0": {
162
+
"integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="
163
+
},
164
+
"comma-separated-tokens@2.0.3": {
165
+
"integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="
166
+
},
167
+
"dequal@2.0.3": {
168
+
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="
169
+
},
170
+
"devlop@1.1.0": {
171
+
"integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
172
+
"dependencies": [
173
+
"dequal"
174
+
]
175
+
},
176
+
"hast-util-is-element@3.0.0": {
177
+
"integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==",
178
+
"dependencies": [
179
+
"@types/hast"
180
+
]
181
+
},
182
+
"hast-util-to-html@9.0.5": {
183
+
"integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
184
+
"dependencies": [
185
+
"@types/hast",
186
+
"@types/unist",
187
+
"ccount",
188
+
"comma-separated-tokens",
189
+
"hast-util-whitespace",
190
+
"html-void-elements",
191
+
"mdast-util-to-hast",
192
+
"property-information",
193
+
"space-separated-tokens",
194
+
"stringify-entities",
195
+
"zwitch"
196
+
]
197
+
},
198
+
"hast-util-whitespace@3.0.0": {
199
+
"integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
200
+
"dependencies": [
201
+
"@types/hast"
202
+
]
203
+
},
204
+
"html-void-elements@3.0.0": {
205
+
"integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="
206
+
},
207
+
"mdast-util-to-hast@13.2.0": {
208
+
"integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
209
+
"dependencies": [
210
+
"@types/hast",
211
+
"@types/mdast",
212
+
"@ungap/structured-clone",
213
+
"devlop",
214
+
"micromark-util-sanitize-uri",
215
+
"trim-lines",
216
+
"unist-util-position",
217
+
"unist-util-visit",
218
+
"vfile"
219
+
]
220
+
},
221
+
"micromark-util-character@2.1.1": {
222
+
"integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
223
+
"dependencies": [
224
+
"micromark-util-symbol",
225
+
"micromark-util-types"
226
+
]
227
+
},
228
+
"micromark-util-encode@2.0.1": {
229
+
"integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="
230
+
},
231
+
"micromark-util-sanitize-uri@2.0.1": {
232
+
"integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
233
+
"dependencies": [
234
+
"micromark-util-character",
235
+
"micromark-util-encode",
236
+
"micromark-util-symbol"
237
+
]
238
+
},
239
+
"micromark-util-symbol@2.0.1": {
240
+
"integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="
241
+
},
242
+
"micromark-util-types@2.0.2": {
243
+
"integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="
244
+
},
245
+
"oniguruma-parser@0.12.1": {
246
+
"integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="
247
+
},
248
+
"oniguruma-to-es@4.3.3": {
249
+
"integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==",
250
+
"dependencies": [
251
+
"oniguruma-parser",
252
+
"regex",
253
+
"regex-recursion"
254
+
]
255
+
},
256
+
"property-information@7.1.0": {
257
+
"integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="
258
+
},
259
+
"regex-recursion@6.0.2": {
260
+
"integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
261
+
"dependencies": [
262
+
"regex-utilities"
263
+
]
264
+
},
265
+
"regex-utilities@2.3.0": {
266
+
"integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="
267
+
},
268
+
"regex@6.0.1": {
269
+
"integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==",
270
+
"dependencies": [
271
+
"regex-utilities"
272
+
]
273
+
},
274
+
"shiki@3.8.1": {
275
+
"integrity": "sha512-+MYIyjwGPCaegbpBeFN9+oOifI8CKiKG3awI/6h3JeT85c//H2wDW/xCJEGuQ5jPqtbboKNqNy+JyX9PYpGwNg==",
276
+
"dependencies": [
277
+
"@shikijs/core",
278
+
"@shikijs/engine-javascript",
279
+
"@shikijs/engine-oniguruma",
280
+
"@shikijs/langs",
281
+
"@shikijs/themes",
282
+
"@shikijs/types",
283
+
"@shikijs/vscode-textmate",
284
+
"@types/hast"
285
+
]
286
+
},
287
+
"space-separated-tokens@2.0.2": {
288
+
"integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="
289
+
},
290
+
"stringify-entities@4.0.4": {
291
+
"integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
292
+
"dependencies": [
293
+
"character-entities-html4",
294
+
"character-entities-legacy"
295
+
]
296
+
},
297
+
"trim-lines@3.0.1": {
298
+
"integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="
299
+
},
88
300
"undici-types@6.21.0": {
89
301
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
302
+
},
303
+
"unist-util-is@6.0.0": {
304
+
"integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
305
+
"dependencies": [
306
+
"@types/unist"
307
+
]
308
+
},
309
+
"unist-util-position@5.0.0": {
310
+
"integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
311
+
"dependencies": [
312
+
"@types/unist"
313
+
]
314
+
},
315
+
"unist-util-stringify-position@4.0.0": {
316
+
"integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
317
+
"dependencies": [
318
+
"@types/unist"
319
+
]
320
+
},
321
+
"unist-util-visit-parents@6.0.1": {
322
+
"integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
323
+
"dependencies": [
324
+
"@types/unist",
325
+
"unist-util-is"
326
+
]
327
+
},
328
+
"unist-util-visit@5.0.0": {
329
+
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
330
+
"dependencies": [
331
+
"@types/unist",
332
+
"unist-util-is",
333
+
"unist-util-visit-parents"
334
+
]
335
+
},
336
+
"vfile-message@4.0.3": {
337
+
"integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==",
338
+
"dependencies": [
339
+
"@types/unist",
340
+
"unist-util-stringify-position"
341
+
]
342
+
},
343
+
"vfile@6.0.3": {
344
+
"integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
345
+
"dependencies": [
346
+
"@types/unist",
347
+
"vfile-message"
348
+
]
349
+
},
350
+
"zwitch@2.0.4": {
351
+
"integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="
90
352
}
91
353
},
92
354
"redirects": {
···
101
363
"dependencies": [
102
364
"jsr:@cliffy/command@1.0.0-rc.8",
103
365
"jsr:@eta-dev/eta@^3.5.0",
104
-
"jsr:@std/assert@1"
366
+
"jsr:@std/assert@1",
367
+
"npm:@types/hast@^3.0.4",
368
+
"npm:hast-util-is-element@3",
369
+
"npm:shiki@^3.8.1"
105
370
]
106
371
}
107
372
}
+55
-2
parse/render.ts
+55
-2
parse/render.ts
···
1
-
import Markdoc, { Config, Node } from "@markdoc/markdoc";
1
+
import Markdoc, {
2
+
Config,
3
+
Node,
4
+
RenderableTreeNode,
5
+
Tag,
6
+
} from "@markdoc/markdoc";
7
+
import { codeToHast } from "shiki";
8
+
import { isElement } from "hast-util-is-element";
9
+
import type { Node as HastNode } from "@types/hast";
10
+
11
+
function hastToRenderNode(node: HastNode): RenderableTreeNode {
12
+
let tag: Tag;
13
+
14
+
if (isElement(node)) {
15
+
tag = new Tag(
16
+
node.tagName,
17
+
node.properties,
18
+
node.children.map(hastToRenderNode),
19
+
);
20
+
} else if ("value" in node) {
21
+
return node.value as string;
22
+
} else {
23
+
tag = new Tag(
24
+
"div",
25
+
undefined,
26
+
"children" in node
27
+
? (node.children as HastNode[]).map(hastToRenderNode)
28
+
: undefined,
29
+
);
30
+
}
31
+
32
+
console.log(tag);
33
+
34
+
return tag;
35
+
}
2
36
3
37
const config: Config = {
4
38
tags: {
···
9
43
render: "div",
10
44
},
11
45
},
46
+
nodes: {
47
+
fence: {
48
+
render: "pre",
49
+
attributes: {
50
+
content: { type: "String", render: false },
51
+
language: { type: "String", render: false },
52
+
},
53
+
async transform(node) {
54
+
const { content, language = "text" } = node.attributes;
55
+
56
+
const hast = await codeToHast(content, {
57
+
lang: language,
58
+
theme: "rose-pine",
59
+
});
60
+
61
+
return hastToRenderNode(hast);
62
+
},
63
+
},
64
+
},
12
65
};
13
66
14
67
export async function renderBody(path: string) {
···
37
90
38
91
const tree = Markdoc.transform(ast, config);
39
92
40
-
return Markdoc.renderers.html(tree);
93
+
return Markdoc.renderers.html(await Promise.resolve(tree));
41
94
}
+23
slides.mdoc
+23
slides.mdoc
···
12
12
13
13
---
14
14
15
+
## Some code
16
+
17
+
```typescript
18
+
// And here's some code
19
+
20
+
function hello() {
21
+
return "hello"
22
+
}
23
+
24
+
console.log("hello") // Prints "hello"
25
+
```
26
+
27
+
---
28
+
29
+
## And a diagram
30
+
31
+
```mermaid
32
+
flowchart LR
33
+
Hello --> World
34
+
```
35
+
36
+
---
37
+
15
38
## Thank You
16
39
+17
-1
templates/live-reload.eta
+17
-1
templates/live-reload.eta
···
26
26
margin: 0;
27
27
}
28
28
29
+
pre {
30
+
margin: 0;
31
+
font-variation-settings: "MONO" 1;
32
+
font-family: "Recursive", monospace;
33
+
}
34
+
35
+
code {
36
+
font-variation-settings: "MONO" 1;
37
+
font-family: "Recursive", monospace;
38
+
}
39
+
29
40
article {
30
41
width: 100vw;
31
42
height: 100vh;
···
41
52
position: relative;
42
53
}
43
54
44
-
section div {
55
+
section > div {
45
56
container: slide / inline-size;
46
57
box-sizing: border-box;
47
58
position: absolute;
···
92
103
justify-content: center;
93
104
}
94
105
106
+
.shiki {
107
+
padding: 2cqi;
108
+
font-size: 2cqi;
109
+
border-radius: 1em;
110
+
}
95
111
</style>
96
112
</head>
97
113
<body>