@d10f/asciidoc-astro-loader 0.0.3 → 0.0.4

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/README.md CHANGED
@@ -290,16 +290,33 @@ Custom converters are refined versions of templates. The main difference is that
290
290
 
291
291
  For maximum flexibility, both custom converters and templates can be used at the same time. You can even define templates that aren't designed to be used to render nodes directly, but called directly from within your custom converters. This is why the use of interfaces when defining custom templates is important, to ensure consistency and type-safety.
292
292
 
293
- In general, prefer using converters for anything that requires heavy use of logic, and templates for simpler HTML output.
293
+ In general, prefer using converters for anything that requires heavy use of logic or that reads configuration options provided by the user, and templates for simpler HTML output.
294
+
295
+ Custom converters are provided as an array to the `document.converters` option.
296
+
297
+ ```ts
298
+ // src/content.config.ts
299
+
300
+ const blog = defineCollection({
301
+ loader: asciidocLoader({
302
+ base: ".src/content/blog",
303
+ document: {
304
+ converters: [
305
+ myCustomConverter({ /* ... */ })
306
+ ]
307
+ },
308
+ }),
309
+ });
310
+ ```
294
311
 
295
312
  ### Registering a custom converter
296
313
 
297
- A custom converter is declared as a factory function that returns another function. This allows you to provide whatever configuration options you want when registering this converter in the loader configuration.
314
+ A custom converter is declared as a factory function that accepts a configuration object, and returns an inner function that gets called automatically, receiving the options provided to the loader and the instance of the Shiki highlighter.
298
315
 
299
316
  ```ts
300
317
  import type { CustomConverterFactoryFn, NodeContext } from '@d10f/asciidoc-astro-loader';
301
318
 
302
- export const customConverter: CustomConverterFactoryFn = ({ nodeContext }) => {
319
+ export const myCustomConverter: CustomConverterFactoryFn = ({ nodeContext }) => {
303
320
  return (options, highlighter) => {
304
321
  return {
305
322
 
@@ -324,3 +341,4 @@ export const customConverter: CustomConverterFactoryFn = ({ nodeContext }) => {
324
341
  }
325
342
  ```
326
343
 
344
+ In addition, the `convert` method receives the node that is being processed, as well as an instance of the template engine registry. You can use this to render the HTML from a template as well, combining both to get the best of both worlds.
@@ -4,7 +4,9 @@ import {
4
4
 
5
5
  // src/lib/asciidoc/converters/sourceCodeConverter.ts
6
6
  import { resolve } from "path";
7
- var sourceCodeConverter = ({ transformers, template }) => {
7
+ var sourceCodeConverter = (converterOptions) => {
8
+ const transformers = converterOptions?.transformers;
9
+ const template = converterOptions?.template;
8
10
  return (options, highlighter) => {
9
11
  return {
10
12
  nodeContext: "listing",
@@ -333,6 +333,22 @@ declare class TemplateEngineRegistry {
333
333
  private loadTemplates;
334
334
  }
335
335
 
336
+ /**
337
+ * Checks if the given property K is required in object T.
338
+ *
339
+ * @credit Chris Cook
340
+ * @see https://zirkelc.dev/posts/typescript-how-to-check-for-optional-properties
341
+ */
342
+ type IsRequired<T, K extends keyof T> = undefined extends T[K] ? object extends Pick<T, K> ? false : true : true;
343
+ /**
344
+ * Checks if any of the properties in T are required.
345
+ *
346
+ * @credit Chris Cook
347
+ * @see https://zirkelc.dev/posts/typescript-how-to-check-for-optional-properties
348
+ */
349
+ type HasRequiredKeys<T extends object> = keyof {
350
+ [K in keyof T as IsRequired<T, K> extends true ? K : never]: T[K];
351
+ } extends never ? false : true;
336
352
  type CustomConverter = {
337
353
  /**
338
354
  * The node context, or node type, that this converter will act upon.
@@ -353,9 +369,9 @@ type CustomConverter = {
353
369
  */
354
370
  convert(node: AbstractNode, templateEngine?: TemplateEngineRegistry): string | null | undefined;
355
371
  };
356
- type CustomConverterFactoryFn<T extends object | undefined> = (converterOptions: T) => CustomConverterFn;
372
+ type CustomConverterFactoryFn<T extends object> = HasRequiredKeys<T> extends true ? (converterOptions: T) => CustomConverterFn : (converterOptions?: T) => CustomConverterFn;
357
373
  type CustomConverterFn = (opts: RequiredOptions, highlighter: HighlighterCore) => CustomConverter;
358
- type ShikiTransformerFactory<T extends object> = (options?: T) => ShikiTransformerFactoryFn;
374
+ type ShikiTransformerFactory<T extends object> = HasRequiredKeys<T> extends true ? (options: T) => ShikiTransformerFactoryFn : (options?: T) => ShikiTransformerFactoryFn;
359
375
  type ShikiTransformerFactoryFn = (node: AbstractNode) => ShikiTransformer;
360
376
  type CalloutOptions = Partial<{
361
377
  /**
@@ -333,6 +333,22 @@ declare class TemplateEngineRegistry {
333
333
  private loadTemplates;
334
334
  }
335
335
 
336
+ /**
337
+ * Checks if the given property K is required in object T.
338
+ *
339
+ * @credit Chris Cook
340
+ * @see https://zirkelc.dev/posts/typescript-how-to-check-for-optional-properties
341
+ */
342
+ type IsRequired<T, K extends keyof T> = undefined extends T[K] ? object extends Pick<T, K> ? false : true : true;
343
+ /**
344
+ * Checks if any of the properties in T are required.
345
+ *
346
+ * @credit Chris Cook
347
+ * @see https://zirkelc.dev/posts/typescript-how-to-check-for-optional-properties
348
+ */
349
+ type HasRequiredKeys<T extends object> = keyof {
350
+ [K in keyof T as IsRequired<T, K> extends true ? K : never]: T[K];
351
+ } extends never ? false : true;
336
352
  type CustomConverter = {
337
353
  /**
338
354
  * The node context, or node type, that this converter will act upon.
@@ -353,9 +369,9 @@ type CustomConverter = {
353
369
  */
354
370
  convert(node: AbstractNode, templateEngine?: TemplateEngineRegistry): string | null | undefined;
355
371
  };
356
- type CustomConverterFactoryFn<T extends object | undefined> = (converterOptions: T) => CustomConverterFn;
372
+ type CustomConverterFactoryFn<T extends object> = HasRequiredKeys<T> extends true ? (converterOptions: T) => CustomConverterFn : (converterOptions?: T) => CustomConverterFn;
357
373
  type CustomConverterFn = (opts: RequiredOptions, highlighter: HighlighterCore) => CustomConverter;
358
- type ShikiTransformerFactory<T extends object> = (options?: T) => ShikiTransformerFactoryFn;
374
+ type ShikiTransformerFactory<T extends object> = HasRequiredKeys<T> extends true ? (options: T) => ShikiTransformerFactoryFn : (options?: T) => ShikiTransformerFactoryFn;
359
375
  type ShikiTransformerFactoryFn = (node: AbstractNode) => ShikiTransformer;
360
376
  type CalloutOptions = Partial<{
361
377
  /**
package/dist/index.cjs CHANGED
@@ -519,7 +519,9 @@ async function createHighlighter(documents, themes) {
519
519
 
520
520
  // src/lib/asciidoc/converters/sourceCodeConverter.ts
521
521
  var import_node_path2 = require("path");
522
- var sourceCodeConverter = ({ transformers, template }) => {
522
+ var sourceCodeConverter = (converterOptions) => {
523
+ const transformers = converterOptions?.transformers;
524
+ const template = converterOptions?.template;
523
525
  return (options, highlighter) => {
524
526
  return {
525
527
  nodeContext: "listing",
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { LoaderContext } from 'astro/loaders';
2
- import { A as AsciidocLoader } from './index-sFlXF8Qm.cjs';
3
- export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-sFlXF8Qm.cjs';
2
+ import { A as AsciidocLoader } from './index-CS3PBqxf.cjs';
3
+ export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-CS3PBqxf.cjs';
4
4
  import 'shiki';
5
5
  import 'asciidoctor';
6
6
  import 'astro/zod';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { LoaderContext } from 'astro/loaders';
2
- import { A as AsciidocLoader } from './index-sFlXF8Qm.js';
3
- export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-sFlXF8Qm.js';
2
+ import { A as AsciidocLoader } from './index-CS3PBqxf.js';
3
+ export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-CS3PBqxf.js';
4
4
  import 'shiki';
5
5
  import 'asciidoctor';
6
6
  import 'astro/zod';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sourceCodeConverter
3
- } from "./chunk-KZRXEKZK.js";
3
+ } from "./chunk-NC6IZHLR.js";
4
4
  import {
5
5
  transformAsciidocCallout
6
6
  } from "./chunk-5P6LDJGO.js";
@@ -38,7 +38,9 @@ function splitFilenameComponents(filename) {
38
38
  }
39
39
 
40
40
  // src/lib/asciidoc/converters/sourceCodeConverter.ts
41
- var sourceCodeConverter = ({ transformers, template }) => {
41
+ var sourceCodeConverter = (converterOptions) => {
42
+ const transformers = converterOptions?.transformers;
43
+ const template = converterOptions?.template;
42
44
  return (options, highlighter) => {
43
45
  return {
44
46
  nodeContext: "listing",
@@ -1,12 +1,12 @@
1
1
  import { ShikiTransformer } from 'shiki';
2
- import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-sFlXF8Qm.cjs';
2
+ import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-CS3PBqxf.cjs';
3
3
  import 'asciidoctor';
4
4
  import 'astro/zod';
5
5
 
6
- type CodeBlockConverterOptions = {
6
+ type CodeBlockConverterOptions = Partial<{
7
7
  transformers: Array<ShikiTransformer | ShikiTransformerFactoryFn>;
8
8
  template: string;
9
- };
10
- declare const sourceCodeConverter: CustomConverterFactoryFn<Partial<CodeBlockConverterOptions>>;
9
+ }>;
10
+ declare const sourceCodeConverter: CustomConverterFactoryFn<CodeBlockConverterOptions>;
11
11
 
12
12
  export { sourceCodeConverter };
@@ -1,12 +1,12 @@
1
1
  import { ShikiTransformer } from 'shiki';
2
- import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-sFlXF8Qm.js';
2
+ import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-CS3PBqxf.js';
3
3
  import 'asciidoctor';
4
4
  import 'astro/zod';
5
5
 
6
- type CodeBlockConverterOptions = {
6
+ type CodeBlockConverterOptions = Partial<{
7
7
  transformers: Array<ShikiTransformer | ShikiTransformerFactoryFn>;
8
8
  template: string;
9
- };
10
- declare const sourceCodeConverter: CustomConverterFactoryFn<Partial<CodeBlockConverterOptions>>;
9
+ }>;
10
+ declare const sourceCodeConverter: CustomConverterFactoryFn<CodeBlockConverterOptions>;
11
11
 
12
12
  export { sourceCodeConverter };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sourceCodeConverter
3
- } from "../../../chunk-KZRXEKZK.js";
3
+ } from "../../../chunk-NC6IZHLR.js";
4
4
  import "../../../chunk-2UGTFP4R.js";
5
5
  export {
6
6
  sourceCodeConverter
@@ -1,4 +1,4 @@
1
- import { c as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-sFlXF8Qm.cjs';
1
+ import { c as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-CS3PBqxf.cjs';
2
2
  import { AbstractBlock } from 'asciidoctor';
3
3
  import 'shiki';
4
4
  import 'astro/zod';
@@ -1,4 +1,4 @@
1
- import { c as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-sFlXF8Qm.js';
1
+ import { c as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-CS3PBqxf.js';
2
2
  import { AbstractBlock } from 'asciidoctor';
3
3
  import 'shiki';
4
4
  import 'astro/zod';
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var transformers_exports = {};
22
22
  __export(transformers_exports, {
23
23
  transformAsciidocCallout: () => transformAsciidocCallout,
24
- transformConsolePrompt: () => transformConsolePrompt
24
+ transformConsolePrompt: () => transformConsolePrompt,
25
+ transformerPrompt: () => transformerPrompt
25
26
  });
26
27
  module.exports = __toCommonJS(transformers_exports);
27
28
 
@@ -129,8 +130,39 @@ var transformConsolePrompt = (options) => {
129
130
  };
130
131
  };
131
132
  };
133
+
134
+ // src/lib/shiki/transformers/transformerPrompt.ts
135
+ var transformerPrompt = (options) => {
136
+ return (node) => {
137
+ const language = node.getAttribute("language");
138
+ const customPrompt = node.getAttribute(
139
+ options?.promptAttribute ?? "custom-prompt"
140
+ );
141
+ const promptToAdd = customPrompt ?? (options?.prompts && options.prompts[language]);
142
+ const cssClasses = typeof promptToAdd === "object" ? promptToAdd.cssClasses : options?.cssClasses;
143
+ return {
144
+ line(hast) {
145
+ if (!promptToAdd) return;
146
+ hast.children.unshift({
147
+ type: "element",
148
+ tagName: "span",
149
+ properties: {
150
+ class: cssClasses
151
+ },
152
+ children: [
153
+ {
154
+ type: "text",
155
+ value: typeof promptToAdd === "object" ? promptToAdd.prompt : promptToAdd
156
+ }
157
+ ]
158
+ });
159
+ }
160
+ };
161
+ };
162
+ };
132
163
  // Annotate the CommonJS export names for ESM import in node:
133
164
  0 && (module.exports = {
134
165
  transformAsciidocCallout,
135
- transformConsolePrompt
166
+ transformConsolePrompt,
167
+ transformerPrompt
136
168
  });
@@ -1,4 +1,5 @@
1
- import { b as ShikiTransformerFactory } from '../../../index-sFlXF8Qm.cjs';
1
+ import { b as ShikiTransformerFactory } from '../../../index-CS3PBqxf.cjs';
2
+ import { BundledLanguage } from 'shiki/types';
2
3
  import 'shiki';
3
4
  import 'asciidoctor';
4
5
  import 'astro/zod';
@@ -8,7 +9,7 @@ type TransformerOptions = Partial<{
8
9
  }>;
9
10
  declare const transformAsciidocCallout: ShikiTransformerFactory<TransformerOptions>;
10
11
 
11
- type TransformOptions = {
12
+ type TransformOptions$1 = {
12
13
  /**
13
14
  * String of CSS classes to apply to leading prompt character(s) on
14
15
  * source code blocks of type console.
@@ -45,6 +46,34 @@ type TransformOptions = {
45
46
  * before: <span>$</span><span> npm run dev</span>
46
47
  * after: <span>$</span><span>npm run dev</span>
47
48
  */
48
- declare const transformConsolePrompt: ShikiTransformerFactory<TransformOptions>;
49
+ declare const transformConsolePrompt: ShikiTransformerFactory<TransformOptions$1>;
50
+
51
+ type PromptOptions = {
52
+ prompt: string;
53
+ cssClasses: string;
54
+ };
55
+ type TransformOptions = {
56
+ /**
57
+ * String of CSS classes to apply to leading prompt character(s) on
58
+ * source code blocks of type console.
59
+ */
60
+ cssClasses?: string;
61
+ /**
62
+ * An object mapping each language block to a prompt string. An object
63
+ * can also be provided specified with two keys, the prompt and the
64
+ * css classes that modify this prompt in particular. Useful when you
65
+ * want to style them differently from the
66
+ * If not provided, it will default to look at the block attribute.
67
+ */
68
+ prompts?: Partial<Record<BundledLanguage, PromptOptions | string>>;
69
+ /**
70
+ * The name of the block attribute on the original document to look
71
+ * for and use as the prompt for this block.
72
+ *
73
+ * @default custom-prompt
74
+ */
75
+ promptAttribute?: string;
76
+ };
77
+ declare const transformerPrompt: ShikiTransformerFactory<TransformOptions>;
49
78
 
50
- export { transformAsciidocCallout, transformConsolePrompt };
79
+ export { transformAsciidocCallout, transformConsolePrompt, transformerPrompt };
@@ -1,4 +1,5 @@
1
- import { b as ShikiTransformerFactory } from '../../../index-sFlXF8Qm.js';
1
+ import { b as ShikiTransformerFactory } from '../../../index-CS3PBqxf.js';
2
+ import { BundledLanguage } from 'shiki/types';
2
3
  import 'shiki';
3
4
  import 'asciidoctor';
4
5
  import 'astro/zod';
@@ -8,7 +9,7 @@ type TransformerOptions = Partial<{
8
9
  }>;
9
10
  declare const transformAsciidocCallout: ShikiTransformerFactory<TransformerOptions>;
10
11
 
11
- type TransformOptions = {
12
+ type TransformOptions$1 = {
12
13
  /**
13
14
  * String of CSS classes to apply to leading prompt character(s) on
14
15
  * source code blocks of type console.
@@ -45,6 +46,34 @@ type TransformOptions = {
45
46
  * before: <span>$</span><span> npm run dev</span>
46
47
  * after: <span>$</span><span>npm run dev</span>
47
48
  */
48
- declare const transformConsolePrompt: ShikiTransformerFactory<TransformOptions>;
49
+ declare const transformConsolePrompt: ShikiTransformerFactory<TransformOptions$1>;
50
+
51
+ type PromptOptions = {
52
+ prompt: string;
53
+ cssClasses: string;
54
+ };
55
+ type TransformOptions = {
56
+ /**
57
+ * String of CSS classes to apply to leading prompt character(s) on
58
+ * source code blocks of type console.
59
+ */
60
+ cssClasses?: string;
61
+ /**
62
+ * An object mapping each language block to a prompt string. An object
63
+ * can also be provided specified with two keys, the prompt and the
64
+ * css classes that modify this prompt in particular. Useful when you
65
+ * want to style them differently from the
66
+ * If not provided, it will default to look at the block attribute.
67
+ */
68
+ prompts?: Partial<Record<BundledLanguage, PromptOptions | string>>;
69
+ /**
70
+ * The name of the block attribute on the original document to look
71
+ * for and use as the prompt for this block.
72
+ *
73
+ * @default custom-prompt
74
+ */
75
+ promptAttribute?: string;
76
+ };
77
+ declare const transformerPrompt: ShikiTransformerFactory<TransformOptions>;
49
78
 
50
- export { transformAsciidocCallout, transformConsolePrompt };
79
+ export { transformAsciidocCallout, transformConsolePrompt, transformerPrompt };
@@ -43,7 +43,38 @@ var transformConsolePrompt = (options) => {
43
43
  };
44
44
  };
45
45
  };
46
+
47
+ // src/lib/shiki/transformers/transformerPrompt.ts
48
+ var transformerPrompt = (options) => {
49
+ return (node) => {
50
+ const language = node.getAttribute("language");
51
+ const customPrompt = node.getAttribute(
52
+ options?.promptAttribute ?? "custom-prompt"
53
+ );
54
+ const promptToAdd = customPrompt ?? (options?.prompts && options.prompts[language]);
55
+ const cssClasses = typeof promptToAdd === "object" ? promptToAdd.cssClasses : options?.cssClasses;
56
+ return {
57
+ line(hast) {
58
+ if (!promptToAdd) return;
59
+ hast.children.unshift({
60
+ type: "element",
61
+ tagName: "span",
62
+ properties: {
63
+ class: cssClasses
64
+ },
65
+ children: [
66
+ {
67
+ type: "text",
68
+ value: typeof promptToAdd === "object" ? promptToAdd.prompt : promptToAdd
69
+ }
70
+ ]
71
+ });
72
+ }
73
+ };
74
+ };
75
+ };
46
76
  export {
47
77
  transformAsciidocCallout,
48
- transformConsolePrompt
78
+ transformConsolePrompt,
79
+ transformerPrompt
49
80
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d10f/asciidoc-astro-loader",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "An Astro collections loader for Asciidoc files",
5
5
  "author": "D10f",
6
6
  "license": "MIT",