@d10f/asciidoc-astro-loader 0.0.1
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/LICENSE +21 -0
- package/README.md +286 -0
- package/dist/chunk-2F52PMNV.js +132 -0
- package/dist/chunk-DDIUST2Z.js +113 -0
- package/dist/chunk-HAZIHU2Y.js +56 -0
- package/dist/index-Cf7MF6tZ.d.cts +325 -0
- package/dist/index-Cf7MF6tZ.d.ts +325 -0
- package/dist/index.cjs +708 -0
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +402 -0
- package/dist/lib/asciidoc/converters/index.cjs +178 -0
- package/dist/lib/asciidoc/converters/index.d.cts +13 -0
- package/dist/lib/asciidoc/converters/index.d.ts +13 -0
- package/dist/lib/asciidoc/converters/index.js +7 -0
- package/dist/lib/asciidoc/templates/engines/index.cjs +191 -0
- package/dist/lib/asciidoc/templates/engines/index.d.cts +30 -0
- package/dist/lib/asciidoc/templates/engines/index.d.ts +30 -0
- package/dist/lib/asciidoc/templates/engines/index.js +30 -0
- package/dist/lib/shiki/transformers/index.cjs +127 -0
- package/dist/lib/shiki/transformers/index.d.cts +59 -0
- package/dist/lib/shiki/transformers/index.d.ts +59 -0
- package/dist/lib/shiki/transformers/index.js +8 -0
- package/package.json +58 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
asciidocLoader: () => asciidocLoader
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/loader.ts
|
|
38
|
+
var import_node_fs4 = require("fs");
|
|
39
|
+
var import_node_process = require("process");
|
|
40
|
+
|
|
41
|
+
// src/lib/asciidoc/AsciidocDocument.ts
|
|
42
|
+
var import_asciidoctor = __toESM(require("asciidoctor"), 1);
|
|
43
|
+
|
|
44
|
+
// src/lib/utils.ts
|
|
45
|
+
function slugify(text) {
|
|
46
|
+
return text.trim().normalize().toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]+/g, "").replace(/--+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
|
|
47
|
+
}
|
|
48
|
+
function escapeRegexCharacters(str) {
|
|
49
|
+
const re = /[-\\^$*+?.()|\[\]{}]/g;
|
|
50
|
+
return str.replace(re, "\\$&");
|
|
51
|
+
}
|
|
52
|
+
function splitFilenameComponents(filename) {
|
|
53
|
+
const match = filename.match(/^(?<path>.*\/)*(?<name>[^\.]+)\.(?<ext>.*)$/);
|
|
54
|
+
return {
|
|
55
|
+
filepath: match?.groups?.path ?? null,
|
|
56
|
+
filename: match?.groups?.name ?? null,
|
|
57
|
+
extension: match?.groups?.ext ?? null
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/lib/asciidoc/BaseConverter.ts
|
|
62
|
+
var BaseConverter = class {
|
|
63
|
+
constructor(defaultConverter) {
|
|
64
|
+
this.defaultConverter = defaultConverter;
|
|
65
|
+
this.customConverters = /* @__PURE__ */ new Map();
|
|
66
|
+
this.templateEngine = void 0;
|
|
67
|
+
}
|
|
68
|
+
customConverters;
|
|
69
|
+
templateEngine;
|
|
70
|
+
/**
|
|
71
|
+
* Registers a new custom converter to act upon a specific block type.
|
|
72
|
+
*/
|
|
73
|
+
register(converter) {
|
|
74
|
+
const context = converter.nodeContext;
|
|
75
|
+
this.customConverters.set(context, converter);
|
|
76
|
+
}
|
|
77
|
+
registerTemplateEngine(templateEngine) {
|
|
78
|
+
this.templateEngine = templateEngine;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Converts the node to an HTML string. If the node's context matches one of
|
|
82
|
+
* the registered converters, it will use that converter.
|
|
83
|
+
*/
|
|
84
|
+
convert(node) {
|
|
85
|
+
const context = node.getNodeName();
|
|
86
|
+
const converter = this.customConverters.get(context);
|
|
87
|
+
if (converter) {
|
|
88
|
+
const output = converter.convert(node, this.templateEngine);
|
|
89
|
+
if (output) return output;
|
|
90
|
+
}
|
|
91
|
+
if (this.templateEngine) {
|
|
92
|
+
const output = this.templateEngine.convert(node);
|
|
93
|
+
if (output) return output;
|
|
94
|
+
}
|
|
95
|
+
return this.defaultConverter.convert(node);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/lib/asciidoc/TemplateEngineRegistry.ts
|
|
100
|
+
var import_node_fs = require("fs");
|
|
101
|
+
var TemplateEngineRegistry = class _TemplateEngineRegistry {
|
|
102
|
+
/**
|
|
103
|
+
* A list of supported templating engines, their associated extensions
|
|
104
|
+
* and associatied template files to render.
|
|
105
|
+
*/
|
|
106
|
+
static modules = [];
|
|
107
|
+
/**
|
|
108
|
+
* A list of all the node existing contexts an Asciidoc node can have.
|
|
109
|
+
*/
|
|
110
|
+
static nodeContexts = [
|
|
111
|
+
"admonition",
|
|
112
|
+
"audio",
|
|
113
|
+
"colist",
|
|
114
|
+
"dlist",
|
|
115
|
+
"document",
|
|
116
|
+
"embedded",
|
|
117
|
+
"example",
|
|
118
|
+
"floating-title",
|
|
119
|
+
"image",
|
|
120
|
+
"inline_anchor",
|
|
121
|
+
"inline_break",
|
|
122
|
+
"inline_button",
|
|
123
|
+
"inline_callout",
|
|
124
|
+
"inline_footnote",
|
|
125
|
+
"inline_image",
|
|
126
|
+
"inline_indexterm",
|
|
127
|
+
"inline_kbd",
|
|
128
|
+
"inline_menu",
|
|
129
|
+
"inline_quoted",
|
|
130
|
+
"listing",
|
|
131
|
+
"literal",
|
|
132
|
+
"olist",
|
|
133
|
+
"open",
|
|
134
|
+
"outline",
|
|
135
|
+
"page_break",
|
|
136
|
+
"paragraph",
|
|
137
|
+
"preamble",
|
|
138
|
+
"quote",
|
|
139
|
+
"section",
|
|
140
|
+
"sidebar",
|
|
141
|
+
"stem",
|
|
142
|
+
"table",
|
|
143
|
+
"thematic_break",
|
|
144
|
+
"toc",
|
|
145
|
+
"ulist",
|
|
146
|
+
"verse",
|
|
147
|
+
"video"
|
|
148
|
+
];
|
|
149
|
+
constructor(templateEngines, options) {
|
|
150
|
+
for (let i = 0; i < templateEngines.length; i++) {
|
|
151
|
+
const current = templateEngines[i];
|
|
152
|
+
for (let j = 0; j < i; j++) {
|
|
153
|
+
const previous = templateEngines[j];
|
|
154
|
+
if (current.name === previous.name) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Engine named "${current.name}" is already registered.`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
current.extensions.forEach((currentExt) => {
|
|
160
|
+
if (previous.extensions.includes(currentExt)) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Extension "${currentExt}" is already handled by engine "${previous.name}".`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
_TemplateEngineRegistry.modules.push(templateEngines[i]);
|
|
168
|
+
}
|
|
169
|
+
this.loadTemplates(options);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Asynchronously loads the necessary third party modules.
|
|
173
|
+
*/
|
|
174
|
+
async loadEngines() {
|
|
175
|
+
_TemplateEngineRegistry.modules.forEach(async (m) => {
|
|
176
|
+
if (m.canLoad) {
|
|
177
|
+
await m.load();
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Returns the module with the given name.
|
|
183
|
+
*/
|
|
184
|
+
getEngineByName(name) {
|
|
185
|
+
return _TemplateEngineRegistry.modules.find((m) => m.name === name);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Returns the module that supports the given extension.
|
|
189
|
+
*/
|
|
190
|
+
getEngineByExtension(ext) {
|
|
191
|
+
return _TemplateEngineRegistry.modules.find(
|
|
192
|
+
(m) => m.extensions.includes(ext)
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Converts the provided node using one of the registered template
|
|
197
|
+
* engine modules. For more granular control, gain access to the
|
|
198
|
+
* engine itself with _getEngineByName_ or _getEngineByExtension_
|
|
199
|
+
* and use one of its render methods directly.
|
|
200
|
+
*/
|
|
201
|
+
convert(node, options = {}) {
|
|
202
|
+
const context = node.getNodeName();
|
|
203
|
+
return _TemplateEngineRegistry.modules.find((m) => m.hasContext(context))?.renderNode(node, options);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Scans the templates directory and creates an index of all templates
|
|
207
|
+
* based on supported block names and extensions.
|
|
208
|
+
*
|
|
209
|
+
* @see https://docs.asciidoctor.org/asciidoctor.js/latest/extend/converter/template-converter/#naming-convention
|
|
210
|
+
*/
|
|
211
|
+
loadTemplates({ rootDir, recursive }) {
|
|
212
|
+
(0, import_node_fs.readdirSync)(rootDir, {
|
|
213
|
+
encoding: "utf8",
|
|
214
|
+
recursive
|
|
215
|
+
}).forEach((template) => {
|
|
216
|
+
const { filename, extension } = splitFilenameComponents(
|
|
217
|
+
template
|
|
218
|
+
);
|
|
219
|
+
if (!filename || !extension) return false;
|
|
220
|
+
if (!_TemplateEngineRegistry.nodeContexts.includes(filename))
|
|
221
|
+
return false;
|
|
222
|
+
const engineModule = _TemplateEngineRegistry.modules.find((m) => {
|
|
223
|
+
return m.supportsExt(extension);
|
|
224
|
+
});
|
|
225
|
+
if (engineModule) {
|
|
226
|
+
engineModule.addContext(filename, `${rootDir}/${template}`);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// src/lib/asciidoc/AsciidocDocument.ts
|
|
233
|
+
var AsciidocDocument = class {
|
|
234
|
+
document;
|
|
235
|
+
baseConverter;
|
|
236
|
+
constructor(filepath) {
|
|
237
|
+
const asciidoc = (0, import_asciidoctor.default)();
|
|
238
|
+
this.baseConverter = new BaseConverter(
|
|
239
|
+
asciidoc.Html5Converter.create()
|
|
240
|
+
);
|
|
241
|
+
asciidoc.ConverterFactory.register(this.baseConverter, ["html5"]);
|
|
242
|
+
this.document = asciidoc.loadFile(filepath);
|
|
243
|
+
}
|
|
244
|
+
get documentTitle() {
|
|
245
|
+
return this.document.getDocumentTitle({
|
|
246
|
+
partition: true
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
get title() {
|
|
250
|
+
return this.documentTitle.getMain();
|
|
251
|
+
}
|
|
252
|
+
get subtitle() {
|
|
253
|
+
return this.documentTitle.getSubtitle();
|
|
254
|
+
}
|
|
255
|
+
get slug() {
|
|
256
|
+
return slugify(this.title);
|
|
257
|
+
}
|
|
258
|
+
get preamble() {
|
|
259
|
+
const [documentBlock] = this.document.getBlocks();
|
|
260
|
+
const [preambleBlock] = documentBlock?.getBlocks();
|
|
261
|
+
if (preambleBlock) return preambleBlock.getSourceLines()[0];
|
|
262
|
+
}
|
|
263
|
+
get version() {
|
|
264
|
+
return this.document.getRevisionNumber();
|
|
265
|
+
}
|
|
266
|
+
get createdAt() {
|
|
267
|
+
return this.document.getRevisionDate();
|
|
268
|
+
}
|
|
269
|
+
get keywords() {
|
|
270
|
+
return this.document.getAttribute("keywords");
|
|
271
|
+
}
|
|
272
|
+
get languages() {
|
|
273
|
+
return this.document.findBy({ context: "listing", style: "source" }).reduce((acc, cur) => {
|
|
274
|
+
const lang = cur.getAttribute("language");
|
|
275
|
+
if (!lang) return acc;
|
|
276
|
+
return acc.add(lang);
|
|
277
|
+
}, /* @__PURE__ */ new Set());
|
|
278
|
+
}
|
|
279
|
+
convert(converters = [], templateEngine) {
|
|
280
|
+
converters.forEach((converter) => {
|
|
281
|
+
this.baseConverter.register(converter);
|
|
282
|
+
});
|
|
283
|
+
if (templateEngine) {
|
|
284
|
+
this.baseConverter.registerTemplateEngine(templateEngine);
|
|
285
|
+
}
|
|
286
|
+
return this.document.getContent();
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
// src/schemas/index.ts
|
|
291
|
+
var import_zod3 = require("zod");
|
|
292
|
+
|
|
293
|
+
// src/schemas/document.ts
|
|
294
|
+
var import_node_path = require("path");
|
|
295
|
+
var import_zod = require("zod");
|
|
296
|
+
var documentOptionsSchema = import_zod.z.looseObject({
|
|
297
|
+
mode: import_zod.z.union([import_zod.z.literal("safe"), import_zod.z.literal("unsafe")]).default("safe"),
|
|
298
|
+
template: import_zod.z.string().default("").transform((val) => (0, import_node_path.resolve)(process.cwd(), val)),
|
|
299
|
+
recursive: import_zod.z.boolean().default(false)
|
|
300
|
+
}).default({
|
|
301
|
+
mode: "safe",
|
|
302
|
+
template: "",
|
|
303
|
+
recursive: false
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// src/schemas/shiki.ts
|
|
307
|
+
var import_zod2 = require("zod");
|
|
308
|
+
var shikiOptionsSchema = import_zod2.z.object({
|
|
309
|
+
theme: import_zod2.z.union([
|
|
310
|
+
import_zod2.z.string(),
|
|
311
|
+
import_zod2.z.object({
|
|
312
|
+
light: import_zod2.z.string(),
|
|
313
|
+
dark: import_zod2.z.string()
|
|
314
|
+
}).catchall(import_zod2.z.string())
|
|
315
|
+
]).transform(transformThemeProp).default({
|
|
316
|
+
light: "catppuccin-latte",
|
|
317
|
+
dark: "catppuccin-macchiato"
|
|
318
|
+
}),
|
|
319
|
+
defaultColor: import_zod2.z.string().default("light-dark()"),
|
|
320
|
+
cssVariablePrefix: import_zod2.z.string().default("--shiki-"),
|
|
321
|
+
mergeWhitespaces: import_zod2.z.union([import_zod2.z.boolean(), import_zod2.z.literal("never")]).default(true),
|
|
322
|
+
tabindex: import_zod2.z.union([import_zod2.z.number(), import_zod2.z.string(), import_zod2.z.literal(false)]).default(false)
|
|
323
|
+
}).transform(({ theme, ...rest }) => ({
|
|
324
|
+
themes: theme,
|
|
325
|
+
...rest
|
|
326
|
+
})).default({
|
|
327
|
+
mergeWhitespaces: true,
|
|
328
|
+
cssVariablePrefix: "--shiki-",
|
|
329
|
+
defaultColor: "light-dark()",
|
|
330
|
+
tabindex: false,
|
|
331
|
+
theme: {
|
|
332
|
+
light: "catppuccin-latte",
|
|
333
|
+
dark: "catppuccin-macchiato"
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
function transformThemeProp(value) {
|
|
337
|
+
return typeof value === "string" ? { light: value, dark: value } : value;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/schemas/index.ts
|
|
341
|
+
var preambleOptionsSchema = import_zod3.z.object({
|
|
342
|
+
tableOfContents: import_zod3.z.boolean().default(true),
|
|
343
|
+
maxLevel: import_zod3.z.number().max(6).min(1).default(3),
|
|
344
|
+
position: import_zod3.z.union([import_zod3.z.literal("before"), import_zod3.z.literal("after")]).default("after")
|
|
345
|
+
}).default({
|
|
346
|
+
tableOfContents: true,
|
|
347
|
+
maxLevel: 3,
|
|
348
|
+
position: "after"
|
|
349
|
+
});
|
|
350
|
+
var loaderOptionsSchema = import_zod3.z.object({
|
|
351
|
+
base: import_zod3.z.string(),
|
|
352
|
+
document: documentOptionsSchema,
|
|
353
|
+
syntaxHighlighting: shikiOptionsSchema,
|
|
354
|
+
preamble: preambleOptionsSchema
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// src/lib/shiki/Highlighter.ts
|
|
358
|
+
var import_shiki2 = require("shiki");
|
|
359
|
+
async function createHighlighter(documents, themes) {
|
|
360
|
+
const langs = documents.reduce((acc, cur) => {
|
|
361
|
+
cur.languages.forEach((lang) => {
|
|
362
|
+
acc.add(lang);
|
|
363
|
+
});
|
|
364
|
+
return acc;
|
|
365
|
+
}, /* @__PURE__ */ new Set());
|
|
366
|
+
const highlighter = await (0, import_shiki2.createHighlighterCore)({
|
|
367
|
+
themes: Object.values(themes).map((theme) => {
|
|
368
|
+
return import(`@shikijs/themes/${theme}`);
|
|
369
|
+
}),
|
|
370
|
+
langs: Array.from(langs).map((lang) => {
|
|
371
|
+
return import(`@shikijs/langs/${lang}`);
|
|
372
|
+
}),
|
|
373
|
+
engine: (0, import_shiki2.createJavaScriptRegexEngine)()
|
|
374
|
+
});
|
|
375
|
+
return Object.freeze(highlighter);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// src/lib/asciidoc/converters/sourceCodeConverter.ts
|
|
379
|
+
var import_transformers = require("@shikijs/transformers");
|
|
380
|
+
var import_node_path2 = require("path");
|
|
381
|
+
|
|
382
|
+
// src/lib/shiki/transformers/transformAsciidocCallout.ts
|
|
383
|
+
function transformAsciidocCallout({
|
|
384
|
+
node,
|
|
385
|
+
cssClasses = "pointer-events-none select-none ml-2"
|
|
386
|
+
}) {
|
|
387
|
+
const lineComments = ["//", "#", ";;"];
|
|
388
|
+
const customLineComment = node.getAttribute("line-comment");
|
|
389
|
+
if (customLineComment) {
|
|
390
|
+
lineComments.push(escapeRegexCharacters(customLineComment));
|
|
391
|
+
}
|
|
392
|
+
const calloutReList = [
|
|
393
|
+
// Handles C-style and similar comments like Perl, Python...
|
|
394
|
+
new RegExp(`(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
|
|
395
|
+
// Handles XML comments
|
|
396
|
+
new RegExp(/((?:\s*<!--(\d+)-->)+)/)
|
|
397
|
+
];
|
|
398
|
+
const linesWithCallout = {};
|
|
399
|
+
return {
|
|
400
|
+
preprocess(code) {
|
|
401
|
+
return code.split("\n").map((line, idx) => {
|
|
402
|
+
for (const re of calloutReList) {
|
|
403
|
+
const match = line.match(re);
|
|
404
|
+
if (!match) continue;
|
|
405
|
+
const callouts = match[0].trim().replaceAll(/(?:<!--|-->|[<>])/g, "").split(" ");
|
|
406
|
+
linesWithCallout[idx + 1] = callouts;
|
|
407
|
+
return line.replace(re, "");
|
|
408
|
+
}
|
|
409
|
+
return line;
|
|
410
|
+
}).join("\n");
|
|
411
|
+
},
|
|
412
|
+
line(hast, line) {
|
|
413
|
+
const callouts = linesWithCallout[line];
|
|
414
|
+
if (!callouts) return;
|
|
415
|
+
callouts.forEach((calloutId) => {
|
|
416
|
+
hast.properties[`data-callout-${calloutId}`] = "";
|
|
417
|
+
hast.children.push({
|
|
418
|
+
type: "element",
|
|
419
|
+
tagName: "i",
|
|
420
|
+
properties: {
|
|
421
|
+
class: `conum ${cssClasses}`,
|
|
422
|
+
"data-value": calloutId
|
|
423
|
+
},
|
|
424
|
+
children: [
|
|
425
|
+
{
|
|
426
|
+
type: "element",
|
|
427
|
+
tagName: "b",
|
|
428
|
+
properties: {},
|
|
429
|
+
children: [
|
|
430
|
+
{
|
|
431
|
+
type: "text",
|
|
432
|
+
value: calloutId
|
|
433
|
+
}
|
|
434
|
+
]
|
|
435
|
+
}
|
|
436
|
+
]
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/lib/shiki/transformers/transformConsoleCodeBlock.ts
|
|
444
|
+
function transformConsoleCodeBlock(options = {
|
|
445
|
+
cssClasses: "pointer-events-none select-none mr-2 opacity-50"
|
|
446
|
+
}) {
|
|
447
|
+
const unselectablePrompt = `<span $1 class="${options.cssClasses}">$</span>`;
|
|
448
|
+
const linePrefix = '<span class="line[^>]+?>';
|
|
449
|
+
const splitPrompt = new RegExp(
|
|
450
|
+
`(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\$\\s+?([^<]))`
|
|
451
|
+
);
|
|
452
|
+
const trimWhitespace = new RegExp(
|
|
453
|
+
`(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\$\\s*?<\\/span>(?:<span>\\s+<\\/span>)?)`
|
|
454
|
+
);
|
|
455
|
+
const trimWhitespaceAhead = new RegExp(
|
|
456
|
+
`(?<=${linePrefix}<span [^>]+?>\\$<\\/span>)(<span style="[^"]+?">)\\s+?`
|
|
457
|
+
);
|
|
458
|
+
return {
|
|
459
|
+
postprocess: (html, { lang }) => {
|
|
460
|
+
if (lang === "console") {
|
|
461
|
+
return html.split("\n").map((line) => {
|
|
462
|
+
return line.replace(
|
|
463
|
+
splitPrompt,
|
|
464
|
+
unselectablePrompt + "<span $1>$2"
|
|
465
|
+
).replace(trimWhitespace, unselectablePrompt).replace(trimWhitespaceAhead, "$1");
|
|
466
|
+
}).join("\n");
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/lib/asciidoc/converters/sourceCodeConverter.ts
|
|
473
|
+
var sourceCodeConverter = ({ nodeContext, transformers, template }) => {
|
|
474
|
+
return (options, highlighter) => {
|
|
475
|
+
return {
|
|
476
|
+
nodeContext: nodeContext ?? "listing",
|
|
477
|
+
convert(node, templateEngine) {
|
|
478
|
+
const input = node.getSourceLines().join("\n");
|
|
479
|
+
const lang = node.getAttribute("language");
|
|
480
|
+
const output = highlighter.codeToHtml(input, {
|
|
481
|
+
...options.syntaxHighlighting,
|
|
482
|
+
lang,
|
|
483
|
+
transformers: [
|
|
484
|
+
...transformers ?? [],
|
|
485
|
+
(0, import_transformers.transformerNotationDiff)(),
|
|
486
|
+
(0, import_transformers.transformerNotationHighlight)(),
|
|
487
|
+
(0, import_transformers.transformerNotationFocus)(),
|
|
488
|
+
transformAsciidocCallout({ node }),
|
|
489
|
+
transformConsoleCodeBlock()
|
|
490
|
+
]
|
|
491
|
+
});
|
|
492
|
+
if (templateEngine && template) {
|
|
493
|
+
const { extension } = splitFilenameComponents(template);
|
|
494
|
+
const engine = templateEngine.getEngineByExtension(
|
|
495
|
+
extension || ""
|
|
496
|
+
);
|
|
497
|
+
if (engine) {
|
|
498
|
+
const templateFile = (0, import_node_path2.resolve)(process.cwd(), template);
|
|
499
|
+
if (engine.canRenderFile) {
|
|
500
|
+
return engine.renderFile(templateFile, {
|
|
501
|
+
content: output,
|
|
502
|
+
lang
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return output;
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
// src/lib/asciidoc/templates/engines/Handlebars.ts
|
|
514
|
+
var import_node_fs2 = require("fs");
|
|
515
|
+
|
|
516
|
+
// src/lib/asciidoc/templates/engines/Base.ts
|
|
517
|
+
var AbstractEngine = class {
|
|
518
|
+
constructor(_name, _extensions) {
|
|
519
|
+
this._name = _name;
|
|
520
|
+
this._extensions = _extensions;
|
|
521
|
+
this.templateList = /* @__PURE__ */ new Map();
|
|
522
|
+
}
|
|
523
|
+
templateList;
|
|
524
|
+
/**
|
|
525
|
+
* Returns the given name to this template engine.
|
|
526
|
+
*/
|
|
527
|
+
get name() {
|
|
528
|
+
return this._name;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Returns the list of extensions this template engine supports.
|
|
532
|
+
*/
|
|
533
|
+
get extensions() {
|
|
534
|
+
return this._extensions;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Accessor method to check if instance implements the
|
|
538
|
+
* TemplateModule interface.
|
|
539
|
+
*/
|
|
540
|
+
get canLoad() {
|
|
541
|
+
return "load" in this && typeof this.load === "function";
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Accessor method to check if instance implements the
|
|
545
|
+
* AsciidocTemplate interface.
|
|
546
|
+
*/
|
|
547
|
+
get canRenderNode() {
|
|
548
|
+
return "renderNode" in this && typeof this.renderNode === "function";
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Accessor method to check if instance implements the
|
|
552
|
+
* FilesystemTemplate interface.
|
|
553
|
+
*/
|
|
554
|
+
get canRenderFile() {
|
|
555
|
+
return "renderFile" in this && typeof this.renderFile === "function";
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Accessor method to check if instance implements the
|
|
559
|
+
* RawTemplate interface.
|
|
560
|
+
*/
|
|
561
|
+
get canRenderString() {
|
|
562
|
+
return "renderString" in this && typeof this.renderString === "function";
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Appends a new context that this template engine will act upon.
|
|
566
|
+
*/
|
|
567
|
+
addContext(context, filepath) {
|
|
568
|
+
this.templateList.set(context, filepath);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Verifies whether the specified context is being tracked or not.
|
|
572
|
+
*/
|
|
573
|
+
hasContext(context) {
|
|
574
|
+
return typeof context === "string" ? this.templateList.has(context) : this.templateList.has(context.getNodeName());
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Verifies if the specified file extension is supported
|
|
578
|
+
* by this template engine.
|
|
579
|
+
*/
|
|
580
|
+
supportsExt(extension) {
|
|
581
|
+
return this.extensions.includes(extension);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
// src/lib/asciidoc/templates/engines/Handlebars.ts
|
|
586
|
+
var HandlebarsEngine = class extends AbstractEngine {
|
|
587
|
+
render;
|
|
588
|
+
constructor(name = "handlebars", extensions = ["handlebars", "hbs"]) {
|
|
589
|
+
super(name, extensions);
|
|
590
|
+
this.render = null;
|
|
591
|
+
}
|
|
592
|
+
async load() {
|
|
593
|
+
const Handlebars = await import("handlebars");
|
|
594
|
+
this.render = (input, opts) => {
|
|
595
|
+
return Handlebars.default.compile(input)(opts);
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
renderNode(node, options = {}) {
|
|
599
|
+
const context = node.getNodeName();
|
|
600
|
+
return this.renderFile(this.templateList.get(context), options);
|
|
601
|
+
}
|
|
602
|
+
renderFile(filepath, options = {}) {
|
|
603
|
+
const fileContents = (0, import_node_fs2.readFileSync)(filepath, { encoding: "utf8" });
|
|
604
|
+
return this.renderString(fileContents, options);
|
|
605
|
+
}
|
|
606
|
+
renderString(str, options = {}) {
|
|
607
|
+
if (this.render === null) {
|
|
608
|
+
throw new Error("This template doesn't have a render method!");
|
|
609
|
+
}
|
|
610
|
+
return this.render(str, options);
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
// src/lib/asciidoc/templates/engines/Nunjucks.ts
|
|
615
|
+
var import_node_fs3 = require("fs");
|
|
616
|
+
var NunjucksEngine = class extends AbstractEngine {
|
|
617
|
+
render;
|
|
618
|
+
constructor(name = "nunjucks", extensions = ["nunjucks", "njk"]) {
|
|
619
|
+
super(name, extensions);
|
|
620
|
+
this.render = null;
|
|
621
|
+
}
|
|
622
|
+
async load() {
|
|
623
|
+
const nunjucks = await import("nunjucks");
|
|
624
|
+
this.render = nunjucks.default.renderString;
|
|
625
|
+
}
|
|
626
|
+
renderNode(node, options = {}) {
|
|
627
|
+
const context = node.getNodeName();
|
|
628
|
+
return this.renderFile(this.templateList.get(context), options);
|
|
629
|
+
}
|
|
630
|
+
renderFile(filepath, options = {}) {
|
|
631
|
+
const fileContents = (0, import_node_fs3.readFileSync)(filepath, { encoding: "utf8" });
|
|
632
|
+
return this.renderString(fileContents, options);
|
|
633
|
+
}
|
|
634
|
+
renderString(str, options = {}) {
|
|
635
|
+
if (this.render === null) {
|
|
636
|
+
throw new Error("This template doesn't have a render method!");
|
|
637
|
+
}
|
|
638
|
+
return this.render(str, options);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// src/loader.ts
|
|
643
|
+
function asciidocLoader(options) {
|
|
644
|
+
const parsedOpts = loaderOptionsSchema.parse(options);
|
|
645
|
+
if (parsedOpts.document.converters === void 0) {
|
|
646
|
+
parsedOpts.document.converters = [
|
|
647
|
+
sourceCodeConverter({ nodeContext: "listing" })
|
|
648
|
+
];
|
|
649
|
+
}
|
|
650
|
+
if (parsedOpts.document.templateEngines === void 0) {
|
|
651
|
+
parsedOpts.document.templateEngines = [
|
|
652
|
+
new HandlebarsEngine(),
|
|
653
|
+
new NunjucksEngine()
|
|
654
|
+
];
|
|
655
|
+
}
|
|
656
|
+
return {
|
|
657
|
+
name: "asciidoc-loader",
|
|
658
|
+
async load({ config, parseData, store, logger }) {
|
|
659
|
+
const root = config.root.pathname;
|
|
660
|
+
const base = parsedOpts.base.startsWith(".") ? (0, import_node_fs4.realpathSync)(options.base) : root + options.base;
|
|
661
|
+
const docs = (0, import_node_fs4.readdirSync)(base, "utf8").filter((file) => file.match(/(?:\.a(?:scii)?doc)$/)).map((filename) => new AsciidocDocument(`${base}/${filename}`));
|
|
662
|
+
if (docs.length === 0) {
|
|
663
|
+
logger.warn("No documents found for this collection.");
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
let templateEngine = void 0;
|
|
667
|
+
if (parsedOpts.document.template) {
|
|
668
|
+
templateEngine = new TemplateEngineRegistry(
|
|
669
|
+
parsedOpts.document.templateEngines,
|
|
670
|
+
{
|
|
671
|
+
rootDir: parsedOpts.document.template,
|
|
672
|
+
recursive: parsedOpts.document.recursive
|
|
673
|
+
}
|
|
674
|
+
);
|
|
675
|
+
await templateEngine.loadEngines();
|
|
676
|
+
}
|
|
677
|
+
const highlighter = await createHighlighter(
|
|
678
|
+
docs,
|
|
679
|
+
parsedOpts.syntaxHighlighting.themes
|
|
680
|
+
);
|
|
681
|
+
const converters = parsedOpts.document.converters.map(
|
|
682
|
+
(converter) => converter(parsedOpts, highlighter)
|
|
683
|
+
);
|
|
684
|
+
docs.forEach(async (doc) => {
|
|
685
|
+
const data = await parseData({
|
|
686
|
+
id: doc.slug,
|
|
687
|
+
data: {
|
|
688
|
+
title: doc.title,
|
|
689
|
+
createdAt: new Date(doc.createdAt),
|
|
690
|
+
description: doc.preamble
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
store.set({
|
|
694
|
+
id: doc.slug,
|
|
695
|
+
data,
|
|
696
|
+
rendered: {
|
|
697
|
+
html: doc.convert(converters, templateEngine)
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
(0, import_node_process.nextTick)(highlighter.dispose);
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
706
|
+
0 && (module.exports = {
|
|
707
|
+
asciidocLoader
|
|
708
|
+
});
|