@d10f/asciidoc-astro-loader 0.0.10 → 0.0.11

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
@@ -35,10 +35,9 @@ const blog = defineCollection({
35
35
  base: ".src/content/blog",
36
36
  }),
37
37
  schema: z.object({
38
- title: z.string(),
39
- preamble: z.string().optional(),
40
- createdAt: z.coerce.date(),
41
- updatedAt: z.coerce.date().optional(),
38
+ doctitle: z.string(),
39
+ description: z.string(),
40
+ revdate: z.coerce.date(),
42
41
  }),
43
42
  });
44
43
  ```
@@ -317,7 +316,12 @@ A custom converter is declared as a factory function that accepts a configuratio
317
316
  ```ts
318
317
  import type { CustomConverterFactoryFn, NodeContext } from '@d10f/asciidoc-astro-loader';
319
318
 
320
- export const myCustomConverter: CustomConverterFactoryFn = ({ nodeContext }) => {
319
+ type MyConverterOpts = {
320
+ name?: string;
321
+ description?: string;
322
+ };
323
+
324
+ export const myCustomConverter: CustomConverterFactoryFn<MyConverterOpts> = ({ name, description }) => {
321
325
  return (options, highlighter) => {
322
326
  return {
323
327
 
@@ -325,7 +329,7 @@ export const myCustomConverter: CustomConverterFactoryFn = ({ nodeContext }) =>
325
329
  * The type of node that this converter will act upon. It
326
330
  * can either be hard-coded here, or passed as an option.
327
331
  */
328
- nodeContext,
332
+ nodeContext: 'admonition',
329
333
 
330
334
  /**
331
335
  * The convert function that will produce the HTML output.
@@ -343,3 +347,44 @@ export const myCustomConverter: CustomConverterFactoryFn = ({ nodeContext }) =>
343
347
  ```
344
348
 
345
349
  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.
350
+
351
+ Using a converter might make more sense if you need to keep some state as the document is being processed. With templates, each invocation is a brand-new state for each block. A converter encapsulates variables declared within it and this can be used to do things like count how many blocks of a given type there are in the whole document. A more practical example might be if you need to position (through CSS styles) an element left or right based on whether it's even or odd. This can be tricky to do with CSS alone because the `:nth-child()` selector accounts only for elements under the same parent, and not the whole document.
352
+
353
+ ## Example
354
+
355
+ This is an example taken from my own website to showcase how to use it in a real world setting. This configuration uses a custom converter, a custom Shiki transformer and points to a folder where custom templates are found:
356
+
357
+ ```ts
358
+ const blog = defineCollection({
359
+ loader: asciidocLoader({
360
+ base: 'src/content/blog',
361
+ document: {
362
+ template: './src/templates',
363
+ converters: [admonitionConverter()],
364
+ },
365
+ syntaxHighlighting: {
366
+ theme: 'catppuccin-frappe',
367
+ transformers: [
368
+ transformerNotationDiff(),
369
+ transformerNotationErrorLevel(),
370
+ transformerNotationFocus(),
371
+ transformerNotationHighlight(),
372
+ transformerPrompt({
373
+ langs: {
374
+ console: '$',
375
+ },
376
+ cssClasses: 'unselectable mr-2 opacity-50',
377
+ }),
378
+ ],
379
+ callouts: {
380
+ cssClasses: 'conum unselectable',
381
+ },
382
+ },
383
+ }),
384
+ schema: z.object({
385
+ doctitle: z.string(),
386
+ description: z.string(),
387
+ revdate: z.coerce.date(),
388
+ }),
389
+ });
390
+ ```
@@ -5,14 +5,14 @@ import {
5
5
  // src/lib/shiki/transformers/transformAsciidocCallout.ts
6
6
  var transformAsciidocCallout = (options) => {
7
7
  return (node) => {
8
- const lineComments = ["//", "#", ";;"];
8
+ const lineComments = ["//", "#", ";;", "%"];
9
9
  const customLineComment = node.getAttribute("line-comment");
10
10
  if (customLineComment) {
11
11
  lineComments.push(escapeRegexCharacters(customLineComment));
12
12
  }
13
13
  const calloutReList = [
14
14
  // Handles C-style and similar comments like Perl, Python...
15
- new RegExp(`\\s+(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
15
+ new RegExp(`\\s*(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
16
16
  // Handles XML comments
17
17
  new RegExp(/((?:\s*<!--(\d+)-->)+)/)
18
18
  ];
@@ -72,9 +72,19 @@ var transformerPrompt = (options) => {
72
72
  if (customPrompt && options?.langs && typeof options.langs[language] === "object") {
73
73
  cssClasses = options.langs[language].cssClasses;
74
74
  }
75
+ let skipNext = false;
75
76
  return {
77
+ enforce: "pre",
76
78
  line(hast) {
77
79
  if (!promptToAdd) return;
80
+ const skipCurrent = skipNext;
81
+ skipNext = false;
82
+ const lastChild = hast.children.at(-1);
83
+ if (lastChild && // @ts-expect-error property "children" does exist
84
+ lastChild.children[0].value.match(/\s+\\(?:\\)?\s*$/)) {
85
+ skipNext = true;
86
+ }
87
+ if (skipCurrent) return;
78
88
  hast.children.unshift({
79
89
  type: "element",
80
90
  tagName: "span",
@@ -1,4 +1,4 @@
1
- import { HighlighterCore, CodeToHastOptions, CodeOptionsMultipleThemes, ThemeRegistrationAny, StringLiteralUnion, BundledTheme, ShikiTransformer } from 'shiki';
1
+ import { HighlighterCore, CodeToHastOptions, CodeOptionsMultipleThemes, StringLiteralUnion, BundledTheme, ShikiTransformer } from 'shiki';
2
2
  import { AbstractNode, AbstractBlock } from 'asciidoctor';
3
3
  import { z } from 'astro/zod';
4
4
 
@@ -474,7 +474,7 @@ type AsciidocLoader = {
474
474
  *
475
475
  * @default 'light-dark()'
476
476
  */
477
- defaultColor: Partial<Record<string, ThemeRegistrationAny | StringLiteralUnion<string>>>;
477
+ defaultColor?: StringLiteralUnion<'light' | 'dark'> | 'light-dark()' | false;
478
478
  /**
479
479
  * The syntax highlighter theme to use. It can be either a
480
480
  * string that will apply for both light and dark mode by
@@ -1,4 +1,4 @@
1
- import { HighlighterCore, CodeToHastOptions, CodeOptionsMultipleThemes, ThemeRegistrationAny, StringLiteralUnion, BundledTheme, ShikiTransformer } from 'shiki';
1
+ import { HighlighterCore, CodeToHastOptions, CodeOptionsMultipleThemes, StringLiteralUnion, BundledTheme, ShikiTransformer } from 'shiki';
2
2
  import { AbstractNode, AbstractBlock } from 'asciidoctor';
3
3
  import { z } from 'astro/zod';
4
4
 
@@ -474,7 +474,7 @@ type AsciidocLoader = {
474
474
  *
475
475
  * @default 'light-dark()'
476
476
  */
477
- defaultColor: Partial<Record<string, ThemeRegistrationAny | StringLiteralUnion<string>>>;
477
+ defaultColor?: StringLiteralUnion<'light' | 'dark'> | 'light-dark()' | false;
478
478
  /**
479
479
  * The syntax highlighter theme to use. It can be either a
480
480
  * string that will apply for both light and dark mode by
package/dist/index.cjs CHANGED
@@ -255,6 +255,9 @@ var AsciidocDocument = class {
255
255
  partition: true
256
256
  });
257
257
  }
258
+ get attributes() {
259
+ return this.document.getAttributes();
260
+ }
258
261
  get title() {
259
262
  return this.documentTitle.getMain();
260
263
  }
@@ -603,14 +606,14 @@ var sourceCodeConverter = (converterOptions) => {
603
606
  // src/lib/shiki/transformers/transformAsciidocCallout.ts
604
607
  var transformAsciidocCallout = (options) => {
605
608
  return (node) => {
606
- const lineComments = ["//", "#", ";;"];
609
+ const lineComments = ["//", "#", ";;", "%"];
607
610
  const customLineComment = node.getAttribute("line-comment");
608
611
  if (customLineComment) {
609
612
  lineComments.push(escapeRegexCharacters(customLineComment));
610
613
  }
611
614
  const calloutReList = [
612
615
  // Handles C-style and similar comments like Perl, Python...
613
- new RegExp(`\\s+(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
616
+ new RegExp(`\\s*(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
614
617
  // Handles XML comments
615
618
  new RegExp(/((?:\s*<!--(\d+)-->)+)/)
616
619
  ];
@@ -757,19 +760,20 @@ function asciidocLoader(_options) {
757
760
  async function setDocument(doc, converters, templateEngine, { parseData, store }) {
758
761
  const data = await parseData({
759
762
  id: doc.slug,
760
- data: {
761
- title: doc.title,
762
- subtitle: doc.subtitle,
763
- author: doc.author,
764
- authors: doc.authors,
765
- version: doc.version,
766
- createdAt: new Date(doc.createdAt),
767
- email: doc.authors.at(0)?.getEmail(),
768
- description: doc.description,
769
- slug: doc.slug,
770
- preamble: doc.preamble,
771
- keywords: doc.keywords
772
- }
763
+ data: doc.attributes
764
+ // data: {
765
+ // title: doc.title,
766
+ // subtitle: doc.subtitle,
767
+ // author: doc.author,
768
+ // authors: doc.authors,
769
+ // version: doc.version,
770
+ // createdAt: new Date(doc.createdAt),
771
+ // email: doc.authors.at(0)?.getEmail(),
772
+ // description: doc.description,
773
+ // slug: doc.slug,
774
+ // preamble: doc.preamble,
775
+ // keywords: doc.keywords,
776
+ // },
773
777
  });
774
778
  store.set({
775
779
  id: doc.slug,
@@ -792,9 +796,19 @@ var transformerPrompt = (options) => {
792
796
  if (customPrompt && options?.langs && typeof options.langs[language] === "object") {
793
797
  cssClasses = options.langs[language].cssClasses;
794
798
  }
799
+ let skipNext = false;
795
800
  return {
801
+ enforce: "pre",
796
802
  line(hast) {
797
803
  if (!promptToAdd) return;
804
+ const skipCurrent = skipNext;
805
+ skipNext = false;
806
+ const lastChild = hast.children.at(-1);
807
+ if (lastChild && // @ts-expect-error property "children" does exist
808
+ lastChild.children[0].value.match(/\s+\\(?:\\)?\s*$/)) {
809
+ skipNext = true;
810
+ }
811
+ if (skipCurrent) return;
798
812
  hast.children.unshift({
799
813
  type: "element",
800
814
  tagName: "span",
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { LoaderContext } from 'astro/loaders';
2
- import { A as AsciidocLoader } from './index-C8nJcG2h.cjs';
3
- export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-C8nJcG2h.cjs';
2
+ import { A as AsciidocLoader } from './index-C1F2jTPD.cjs';
3
+ export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-C1F2jTPD.cjs';
4
4
  export { transformAsciidocCallout, transformerPrompt } from './lib/shiki/transformers/index.cjs';
5
5
  import 'shiki';
6
6
  import 'asciidoctor';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { LoaderContext } from 'astro/loaders';
2
- import { A as AsciidocLoader } from './index-C8nJcG2h.js';
3
- export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-C8nJcG2h.js';
2
+ import { A as AsciidocLoader } from './index-C1F2jTPD.js';
3
+ export { a as AsciidocTemplate, C as CustomConverterFactoryFn, F as FilesystemTemplate, N as NodeContext, R as RawTemplate } from './index-C1F2jTPD.js';
4
4
  export { transformAsciidocCallout, transformerPrompt } from './lib/shiki/transformers/index.js';
5
5
  import 'shiki';
6
6
  import 'asciidoctor';
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  transformAsciidocCallout,
6
6
  transformerPrompt
7
- } from "./chunk-IWQC3MJM.js";
7
+ } from "./chunk-KPEWXJBE.js";
8
8
  import {
9
9
  slugify,
10
10
  splitFilenameComponents
@@ -217,6 +217,9 @@ var AsciidocDocument = class {
217
217
  partition: true
218
218
  });
219
219
  }
220
+ get attributes() {
221
+ return this.document.getAttributes();
222
+ }
220
223
  get title() {
221
224
  return this.documentTitle.getMain();
222
225
  }
@@ -467,19 +470,20 @@ function asciidocLoader(_options) {
467
470
  async function setDocument(doc, converters, templateEngine, { parseData, store }) {
468
471
  const data = await parseData({
469
472
  id: doc.slug,
470
- data: {
471
- title: doc.title,
472
- subtitle: doc.subtitle,
473
- author: doc.author,
474
- authors: doc.authors,
475
- version: doc.version,
476
- createdAt: new Date(doc.createdAt),
477
- email: doc.authors.at(0)?.getEmail(),
478
- description: doc.description,
479
- slug: doc.slug,
480
- preamble: doc.preamble,
481
- keywords: doc.keywords
482
- }
473
+ data: doc.attributes
474
+ // data: {
475
+ // title: doc.title,
476
+ // subtitle: doc.subtitle,
477
+ // author: doc.author,
478
+ // authors: doc.authors,
479
+ // version: doc.version,
480
+ // createdAt: new Date(doc.createdAt),
481
+ // email: doc.authors.at(0)?.getEmail(),
482
+ // description: doc.description,
483
+ // slug: doc.slug,
484
+ // preamble: doc.preamble,
485
+ // keywords: doc.keywords,
486
+ // },
483
487
  });
484
488
  store.set({
485
489
  id: doc.slug,
@@ -1,5 +1,5 @@
1
1
  import { ShikiTransformer } from 'shiki';
2
- import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-C8nJcG2h.cjs';
2
+ import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-C1F2jTPD.cjs';
3
3
  import 'asciidoctor';
4
4
  import 'astro/zod';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { ShikiTransformer } from 'shiki';
2
- import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-C8nJcG2h.js';
2
+ import { C as CustomConverterFactoryFn, S as ShikiTransformerFactoryFn } from '../../../index-C1F2jTPD.js';
3
3
  import 'asciidoctor';
4
4
  import 'astro/zod';
5
5
 
@@ -1,4 +1,4 @@
1
- import { b as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-C8nJcG2h.cjs';
1
+ import { b as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-C1F2jTPD.cjs';
2
2
  import { AbstractBlock } from 'asciidoctor';
3
3
  import 'shiki';
4
4
  import 'astro/zod';
@@ -1,4 +1,4 @@
1
- import { b as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-C8nJcG2h.js';
1
+ import { b as AbstractEngine, a as AsciidocTemplate, T as TemplateModule, F as FilesystemTemplate, R as RawTemplate } from '../../../../index-C1F2jTPD.js';
2
2
  import { AbstractBlock } from 'asciidoctor';
3
3
  import 'shiki';
4
4
  import 'astro/zod';
@@ -34,14 +34,14 @@ function escapeRegexCharacters(str) {
34
34
  // src/lib/shiki/transformers/transformAsciidocCallout.ts
35
35
  var transformAsciidocCallout = (options) => {
36
36
  return (node) => {
37
- const lineComments = ["//", "#", ";;"];
37
+ const lineComments = ["//", "#", ";;", "%"];
38
38
  const customLineComment = node.getAttribute("line-comment");
39
39
  if (customLineComment) {
40
40
  lineComments.push(escapeRegexCharacters(customLineComment));
41
41
  }
42
42
  const calloutReList = [
43
43
  // Handles C-style and similar comments like Perl, Python...
44
- new RegExp(`\\s+(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
44
+ new RegExp(`\\s*(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
45
45
  // Handles XML comments
46
46
  new RegExp(/((?:\s*<!--(\d+)-->)+)/)
47
47
  ];
@@ -101,9 +101,19 @@ var transformerPrompt = (options) => {
101
101
  if (customPrompt && options?.langs && typeof options.langs[language] === "object") {
102
102
  cssClasses = options.langs[language].cssClasses;
103
103
  }
104
+ let skipNext = false;
104
105
  return {
106
+ enforce: "pre",
105
107
  line(hast) {
106
108
  if (!promptToAdd) return;
109
+ const skipCurrent = skipNext;
110
+ skipNext = false;
111
+ const lastChild = hast.children.at(-1);
112
+ if (lastChild && // @ts-expect-error property "children" does exist
113
+ lastChild.children[0].value.match(/\s+\\(?:\\)?\s*$/)) {
114
+ skipNext = true;
115
+ }
116
+ if (skipCurrent) return;
107
117
  hast.children.unshift({
108
118
  type: "element",
109
119
  tagName: "span",
@@ -1,4 +1,4 @@
1
- import { c as ShikiTransformerFactory } from '../../../index-C8nJcG2h.cjs';
1
+ import { c as ShikiTransformerFactory } from '../../../index-C1F2jTPD.cjs';
2
2
  import { BundledLanguage } from 'shiki/types';
3
3
  import 'shiki';
4
4
  import 'asciidoctor';
@@ -1,4 +1,4 @@
1
- import { c as ShikiTransformerFactory } from '../../../index-C8nJcG2h.js';
1
+ import { c as ShikiTransformerFactory } from '../../../index-C1F2jTPD.js';
2
2
  import { BundledLanguage } from 'shiki/types';
3
3
  import 'shiki';
4
4
  import 'asciidoctor';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  transformAsciidocCallout,
3
3
  transformerPrompt
4
- } from "../../../chunk-IWQC3MJM.js";
4
+ } from "../../../chunk-KPEWXJBE.js";
5
5
  import "../../../chunk-2UGTFP4R.js";
6
6
  export {
7
7
  transformAsciidocCallout,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d10f/asciidoc-astro-loader",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "An Astro collections loader for Asciidoc files",
5
5
  "author": "D10f",
6
6
  "license": "MIT",