@d10f/asciidoc-astro-loader 0.0.1 → 0.0.3

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.
@@ -21,7 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var transformers_exports = {};
22
22
  __export(transformers_exports, {
23
23
  transformAsciidocCallout: () => transformAsciidocCallout,
24
- transformConsoleCodeBlock: () => transformConsoleCodeBlock
24
+ transformConsolePrompt: () => transformConsolePrompt
25
25
  });
26
26
  module.exports = __toCommonJS(transformers_exports);
27
27
 
@@ -32,84 +32,93 @@ function escapeRegexCharacters(str) {
32
32
  }
33
33
 
34
34
  // src/lib/shiki/transformers/transformAsciidocCallout.ts
35
- function transformAsciidocCallout({
36
- node,
37
- cssClasses = "pointer-events-none select-none ml-2"
38
- }) {
39
- const lineComments = ["//", "#", ";;"];
40
- const customLineComment = node.getAttribute("line-comment");
41
- if (customLineComment) {
42
- lineComments.push(escapeRegexCharacters(customLineComment));
43
- }
44
- const calloutReList = [
45
- // Handles C-style and similar comments like Perl, Python...
46
- new RegExp(`(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
47
- // Handles XML comments
48
- new RegExp(/((?:\s*<!--(\d+)-->)+)/)
49
- ];
50
- const linesWithCallout = {};
51
- return {
52
- preprocess(code) {
53
- return code.split("\n").map((line, idx) => {
54
- for (const re of calloutReList) {
55
- const match = line.match(re);
56
- if (!match) continue;
57
- const callouts = match[0].trim().replaceAll(/(?:<!--|-->|[<>])/g, "").split(" ");
58
- linesWithCallout[idx + 1] = callouts;
59
- return line.replace(re, "");
60
- }
61
- return line;
62
- }).join("\n");
63
- },
64
- line(hast, line) {
65
- const callouts = linesWithCallout[line];
66
- if (!callouts) return;
67
- callouts.forEach((calloutId) => {
68
- hast.properties[`data-callout-${calloutId}`] = "";
69
- hast.children.push({
70
- type: "element",
71
- tagName: "i",
72
- properties: {
73
- class: `conum ${cssClasses}`,
74
- "data-value": calloutId
75
- },
76
- children: [
77
- {
78
- type: "element",
79
- tagName: "b",
80
- properties: {},
81
- children: [
82
- {
83
- type: "text",
84
- value: calloutId
85
- }
86
- ]
87
- }
88
- ]
89
- });
90
- });
35
+ var transformAsciidocCallout = (options) => {
36
+ return (node) => {
37
+ const lineComments = ["//", "#", ";;"];
38
+ const customLineComment = node.getAttribute("line-comment");
39
+ if (customLineComment) {
40
+ lineComments.push(escapeRegexCharacters(customLineComment));
91
41
  }
42
+ const calloutReList = [
43
+ // Handles C-style and similar comments like Perl, Python...
44
+ new RegExp(`\\s+(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
45
+ // Handles XML comments
46
+ new RegExp(/((?:\s*<!--(\d+)-->)+)/)
47
+ ];
48
+ const commentTokensRe = new RegExp(
49
+ `(?:${lineComments.join("|")}|<!--|-->|[<>])`,
50
+ "g"
51
+ );
52
+ const linesWithCallout = {};
53
+ return {
54
+ preprocess(code) {
55
+ return code.split("\n").map((line, idx) => {
56
+ for (const re of calloutReList) {
57
+ const match = line.match(re);
58
+ if (!match) continue;
59
+ const callouts = match[0].replaceAll(commentTokensRe, "").trim().split(" ");
60
+ linesWithCallout[idx + 1] = callouts;
61
+ return line.replace(re, "");
62
+ }
63
+ return line;
64
+ }).join("\n");
65
+ },
66
+ line(hast, line) {
67
+ const callouts = linesWithCallout[line];
68
+ if (!callouts) return;
69
+ callouts.forEach((calloutId) => {
70
+ hast.properties[`data-callout-${calloutId}`] = "";
71
+ hast.children.push({
72
+ type: "element",
73
+ tagName: "span",
74
+ properties: {
75
+ class: options?.cssClasses ?? "conum",
76
+ style: options?.cssClasses ? "" : "user-select:none; pointer-events:none; opacity:0.5; margin-inline:8px;",
77
+ "data-value": calloutId
78
+ },
79
+ children: [
80
+ {
81
+ type: "text",
82
+ value: calloutId
83
+ }
84
+ ]
85
+ });
86
+ });
87
+ }
88
+ };
92
89
  };
93
- }
90
+ };
94
91
 
95
- // src/lib/shiki/transformers/transformConsoleCodeBlock.ts
96
- function transformConsoleCodeBlock(options = {
97
- cssClasses: "pointer-events-none select-none mr-2 opacity-50"
98
- }) {
99
- const unselectablePrompt = `<span $1 class="${options.cssClasses}">$</span>`;
100
- const linePrefix = '<span class="line[^>]+?>';
101
- const splitPrompt = new RegExp(
102
- `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\$\\s+?([^<]))`
103
- );
104
- const trimWhitespace = new RegExp(
105
- `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\$\\s*?<\\/span>(?:<span>\\s+<\\/span>)?)`
106
- );
107
- const trimWhitespaceAhead = new RegExp(
108
- `(?<=${linePrefix}<span [^>]+?>\\$<\\/span>)(<span style="[^"]+?">)\\s+?`
109
- );
110
- return {
111
- postprocess: (html, { lang }) => {
112
- if (lang === "console") {
92
+ // src/lib/shiki/transformers/transformConsolePrompt.ts
93
+ var transformConsolePrompt = (options) => {
94
+ return (node) => {
95
+ const language = node.getAttribute("language");
96
+ const cssClasses = options?.cssClasses;
97
+ const promptChar = options?.promptChar ?? "$";
98
+ const unselectablePrompt = `<span $1 class="${cssClasses}">${promptChar}</span>`;
99
+ const linePrefix = '<span class="line[^>]+?>';
100
+ const splitPrompt = new RegExp(
101
+ `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\${promptChar}\\s+?([^<]))`
102
+ );
103
+ const trimWhitespace = new RegExp(
104
+ `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\${promptChar}\\s*?<\\/span>(?:<span>\\s+<\\/span>)?)`
105
+ );
106
+ const trimWhitespaceAhead = new RegExp(
107
+ `(?<=${linePrefix}<span [^>]+?>\\${promptChar}<\\/span>)(<span style="[^"]+?">)\\s+?`
108
+ );
109
+ return {
110
+ line(hast) {
111
+ if (language !== "console") return;
112
+ const textNode = hast.children.at(0)?.children.at(0);
113
+ if (textNode && textNode.type === "text") {
114
+ const leadingChar = textNode.value;
115
+ if (!leadingChar.startsWith(promptChar)) {
116
+ textNode.value = promptChar + " " + textNode.value;
117
+ }
118
+ }
119
+ },
120
+ postprocess: (html) => {
121
+ if (language !== "console") return;
113
122
  return html.split("\n").map((line) => {
114
123
  return line.replace(
115
124
  splitPrompt,
@@ -117,11 +126,11 @@ function transformConsoleCodeBlock(options = {
117
126
  ).replace(trimWhitespace, unselectablePrompt).replace(trimWhitespaceAhead, "$1");
118
127
  }).join("\n");
119
128
  }
120
- }
129
+ };
121
130
  };
122
- }
131
+ };
123
132
  // Annotate the CommonJS export names for ESM import in node:
124
133
  0 && (module.exports = {
125
134
  transformAsciidocCallout,
126
- transformConsoleCodeBlock
135
+ transformConsolePrompt
127
136
  });
@@ -1,43 +1,34 @@
1
- import { Block } from 'asciidoctor';
2
- import { ShikiTransformer } from 'shiki';
3
- import { ShikiTransformer as ShikiTransformer$1 } from 'shiki/types';
1
+ import { b as ShikiTransformerFactory } from '../../../index-sFlXF8Qm.cjs';
2
+ import 'shiki';
3
+ import 'asciidoctor';
4
+ import 'astro/zod';
4
5
 
5
- type TransformOptions$1 = {
6
- /**
7
- * Instance of Asciidoc's Block element to act upon.
8
- */
9
- node: Block;
10
- /**
11
- * String of CSS classes to apply to Asciidoc callout elements.
12
- * Note: this does not override Asciidoctor's default class "conum"
13
- * that applies to callout elements.
14
- *
15
- * @default pointer-events-none select-none ml-2
16
- */
6
+ type TransformerOptions = Partial<{
17
7
  cssClasses?: string;
18
- };
19
- /**
20
- * Transforms source code blocks by converting Asciidoc's callout annotations
21
- * into unselectable tokens.
22
- */
23
- declare function transformAsciidocCallout({ node, cssClasses, }: TransformOptions$1): ShikiTransformer;
8
+ }>;
9
+ declare const transformAsciidocCallout: ShikiTransformerFactory<TransformerOptions>;
24
10
 
25
11
  type TransformOptions = {
26
12
  /**
27
- * String of CSS classes to apply to leading '$' character on console
28
- * code blocks. By default, this transformer makes it unselectable and
29
- * applies 50% opacity.
13
+ * String of CSS classes to apply to leading prompt character(s) on
14
+ * source code blocks of type console.
15
+ */
16
+ cssClasses: string;
17
+ /**
18
+ * The prompt character representing the actual console prompt.
30
19
  *
31
- * @default pointer-events-none select-none mr-2 opacity-50
20
+ * @default $
32
21
  */
33
- cssClasses?: string;
22
+ promptChar?: string;
34
23
  };
35
24
  /**
36
- * For code blocks of language "console", makes the leading prompt
37
- * character "$" unselectable, as it often leads to confusion when
38
- * copying the command and running with the preceding prompt.
25
+ * For code blocks of language "console", prepends each line with a
26
+ * prompt character(s), where applicable. By default, a "$" is used but
27
+ * this can be controlled via the *promptChar* option.
28
+ * Use the *cssClasses* option to style this prompt for things like
29
+ * making it unselectable, or dimmed..
39
30
  *
40
- * Likewise, the leading spaces before the actual command are deleted
31
+ * In addition, the leading spaces before the actual command are deleted
41
32
  * from the span elements generated by Shiki to avoid accidentally
42
33
  * running commands that would not appear in the shell history.
43
34
  *
@@ -54,6 +45,6 @@ type TransformOptions = {
54
45
  * before: <span>$</span><span> npm run dev</span>
55
46
  * after: <span>$</span><span>npm run dev</span>
56
47
  */
57
- declare function transformConsoleCodeBlock(options?: TransformOptions): ShikiTransformer$1;
48
+ declare const transformConsolePrompt: ShikiTransformerFactory<TransformOptions>;
58
49
 
59
- export { transformAsciidocCallout, transformConsoleCodeBlock };
50
+ export { transformAsciidocCallout, transformConsolePrompt };
@@ -1,43 +1,34 @@
1
- import { Block } from 'asciidoctor';
2
- import { ShikiTransformer } from 'shiki';
3
- import { ShikiTransformer as ShikiTransformer$1 } from 'shiki/types';
1
+ import { b as ShikiTransformerFactory } from '../../../index-sFlXF8Qm.js';
2
+ import 'shiki';
3
+ import 'asciidoctor';
4
+ import 'astro/zod';
4
5
 
5
- type TransformOptions$1 = {
6
- /**
7
- * Instance of Asciidoc's Block element to act upon.
8
- */
9
- node: Block;
10
- /**
11
- * String of CSS classes to apply to Asciidoc callout elements.
12
- * Note: this does not override Asciidoctor's default class "conum"
13
- * that applies to callout elements.
14
- *
15
- * @default pointer-events-none select-none ml-2
16
- */
6
+ type TransformerOptions = Partial<{
17
7
  cssClasses?: string;
18
- };
19
- /**
20
- * Transforms source code blocks by converting Asciidoc's callout annotations
21
- * into unselectable tokens.
22
- */
23
- declare function transformAsciidocCallout({ node, cssClasses, }: TransformOptions$1): ShikiTransformer;
8
+ }>;
9
+ declare const transformAsciidocCallout: ShikiTransformerFactory<TransformerOptions>;
24
10
 
25
11
  type TransformOptions = {
26
12
  /**
27
- * String of CSS classes to apply to leading '$' character on console
28
- * code blocks. By default, this transformer makes it unselectable and
29
- * applies 50% opacity.
13
+ * String of CSS classes to apply to leading prompt character(s) on
14
+ * source code blocks of type console.
15
+ */
16
+ cssClasses: string;
17
+ /**
18
+ * The prompt character representing the actual console prompt.
30
19
  *
31
- * @default pointer-events-none select-none mr-2 opacity-50
20
+ * @default $
32
21
  */
33
- cssClasses?: string;
22
+ promptChar?: string;
34
23
  };
35
24
  /**
36
- * For code blocks of language "console", makes the leading prompt
37
- * character "$" unselectable, as it often leads to confusion when
38
- * copying the command and running with the preceding prompt.
25
+ * For code blocks of language "console", prepends each line with a
26
+ * prompt character(s), where applicable. By default, a "$" is used but
27
+ * this can be controlled via the *promptChar* option.
28
+ * Use the *cssClasses* option to style this prompt for things like
29
+ * making it unselectable, or dimmed..
39
30
  *
40
- * Likewise, the leading spaces before the actual command are deleted
31
+ * In addition, the leading spaces before the actual command are deleted
41
32
  * from the span elements generated by Shiki to avoid accidentally
42
33
  * running commands that would not appear in the shell history.
43
34
  *
@@ -54,6 +45,6 @@ type TransformOptions = {
54
45
  * before: <span>$</span><span> npm run dev</span>
55
46
  * after: <span>$</span><span>npm run dev</span>
56
47
  */
57
- declare function transformConsoleCodeBlock(options?: TransformOptions): ShikiTransformer$1;
48
+ declare const transformConsolePrompt: ShikiTransformerFactory<TransformOptions>;
58
49
 
59
- export { transformAsciidocCallout, transformConsoleCodeBlock };
50
+ export { transformAsciidocCallout, transformConsolePrompt };
@@ -1,8 +1,49 @@
1
1
  import {
2
- transformAsciidocCallout,
3
- transformConsoleCodeBlock
4
- } from "../../../chunk-DDIUST2Z.js";
2
+ transformAsciidocCallout
3
+ } from "../../../chunk-5P6LDJGO.js";
4
+ import "../../../chunk-2UGTFP4R.js";
5
+
6
+ // src/lib/shiki/transformers/transformConsolePrompt.ts
7
+ var transformConsolePrompt = (options) => {
8
+ return (node) => {
9
+ const language = node.getAttribute("language");
10
+ const cssClasses = options?.cssClasses;
11
+ const promptChar = options?.promptChar ?? "$";
12
+ const unselectablePrompt = `<span $1 class="${cssClasses}">${promptChar}</span>`;
13
+ const linePrefix = '<span class="line[^>]+?>';
14
+ const splitPrompt = new RegExp(
15
+ `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\${promptChar}\\s+?([^<]))`
16
+ );
17
+ const trimWhitespace = new RegExp(
18
+ `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\${promptChar}\\s*?<\\/span>(?:<span>\\s+<\\/span>)?)`
19
+ );
20
+ const trimWhitespaceAhead = new RegExp(
21
+ `(?<=${linePrefix}<span [^>]+?>\\${promptChar}<\\/span>)(<span style="[^"]+?">)\\s+?`
22
+ );
23
+ return {
24
+ line(hast) {
25
+ if (language !== "console") return;
26
+ const textNode = hast.children.at(0)?.children.at(0);
27
+ if (textNode && textNode.type === "text") {
28
+ const leadingChar = textNode.value;
29
+ if (!leadingChar.startsWith(promptChar)) {
30
+ textNode.value = promptChar + " " + textNode.value;
31
+ }
32
+ }
33
+ },
34
+ postprocess: (html) => {
35
+ if (language !== "console") return;
36
+ return html.split("\n").map((line) => {
37
+ return line.replace(
38
+ splitPrompt,
39
+ unselectablePrompt + "<span $1>$2"
40
+ ).replace(trimWhitespace, unselectablePrompt).replace(trimWhitespaceAhead, "$1");
41
+ }).join("\n");
42
+ }
43
+ };
44
+ };
45
+ };
5
46
  export {
6
47
  transformAsciidocCallout,
7
- transformConsoleCodeBlock
48
+ transformConsolePrompt
8
49
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d10f/asciidoc-astro-loader",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "An Astro collections loader for Asciidoc files",
5
5
  "author": "D10f",
6
6
  "license": "MIT",
@@ -36,6 +36,7 @@
36
36
  "./transformers": "./dist/lib/shiki/transformers/index.js"
37
37
  },
38
38
  "devDependencies": {
39
+ "astro": "^5.15.3",
39
40
  "eslint": "^9.36.0",
40
41
  "eslint-plugin-prettier": "^5.5.4",
41
42
  "globals": "^16.4.0",
@@ -50,9 +51,9 @@
50
51
  "dependencies": {
51
52
  "@shikijs/transformers": "^3.13.0",
52
53
  "asciidoctor": "^3.0.4",
53
- "astro": "^5.14.6",
54
- "shiki": "^3.13.0",
55
- "ventojs": "^2.2.0",
56
- "zod": "^4.1.12"
54
+ "shiki": "^3.13.0"
55
+ },
56
+ "peerDependencies": {
57
+ "astro": "^5.0.0"
57
58
  }
58
59
  }
@@ -1,113 +0,0 @@
1
- // src/lib/utils.ts
2
- function slugify(text) {
3
- return text.trim().normalize().toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]+/g, "").replace(/--+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
4
- }
5
- function escapeRegexCharacters(str) {
6
- const re = /[-\\^$*+?.()|\[\]{}]/g;
7
- return str.replace(re, "\\$&");
8
- }
9
- function splitFilenameComponents(filename) {
10
- const match = filename.match(/^(?<path>.*\/)*(?<name>[^\.]+)\.(?<ext>.*)$/);
11
- return {
12
- filepath: match?.groups?.path ?? null,
13
- filename: match?.groups?.name ?? null,
14
- extension: match?.groups?.ext ?? null
15
- };
16
- }
17
-
18
- // src/lib/shiki/transformers/transformAsciidocCallout.ts
19
- function transformAsciidocCallout({
20
- node,
21
- cssClasses = "pointer-events-none select-none ml-2"
22
- }) {
23
- const lineComments = ["//", "#", ";;"];
24
- const customLineComment = node.getAttribute("line-comment");
25
- if (customLineComment) {
26
- lineComments.push(escapeRegexCharacters(customLineComment));
27
- }
28
- const calloutReList = [
29
- // Handles C-style and similar comments like Perl, Python...
30
- new RegExp(`(?:${lineComments.join("|")})((?:\\s+<(\\d+)>)+)`),
31
- // Handles XML comments
32
- new RegExp(/((?:\s*<!--(\d+)-->)+)/)
33
- ];
34
- const linesWithCallout = {};
35
- return {
36
- preprocess(code) {
37
- return code.split("\n").map((line, idx) => {
38
- for (const re of calloutReList) {
39
- const match = line.match(re);
40
- if (!match) continue;
41
- const callouts = match[0].trim().replaceAll(/(?:<!--|-->|[<>])/g, "").split(" ");
42
- linesWithCallout[idx + 1] = callouts;
43
- return line.replace(re, "");
44
- }
45
- return line;
46
- }).join("\n");
47
- },
48
- line(hast, line) {
49
- const callouts = linesWithCallout[line];
50
- if (!callouts) return;
51
- callouts.forEach((calloutId) => {
52
- hast.properties[`data-callout-${calloutId}`] = "";
53
- hast.children.push({
54
- type: "element",
55
- tagName: "i",
56
- properties: {
57
- class: `conum ${cssClasses}`,
58
- "data-value": calloutId
59
- },
60
- children: [
61
- {
62
- type: "element",
63
- tagName: "b",
64
- properties: {},
65
- children: [
66
- {
67
- type: "text",
68
- value: calloutId
69
- }
70
- ]
71
- }
72
- ]
73
- });
74
- });
75
- }
76
- };
77
- }
78
-
79
- // src/lib/shiki/transformers/transformConsoleCodeBlock.ts
80
- function transformConsoleCodeBlock(options = {
81
- cssClasses: "pointer-events-none select-none mr-2 opacity-50"
82
- }) {
83
- const unselectablePrompt = `<span $1 class="${options.cssClasses}">$</span>`;
84
- const linePrefix = '<span class="line[^>]+?>';
85
- const splitPrompt = new RegExp(
86
- `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\$\\s+?([^<]))`
87
- );
88
- const trimWhitespace = new RegExp(
89
- `(?<=${linePrefix})(?:<span (style="[^"]*?")>\\s*?\\$\\s*?<\\/span>(?:<span>\\s+<\\/span>)?)`
90
- );
91
- const trimWhitespaceAhead = new RegExp(
92
- `(?<=${linePrefix}<span [^>]+?>\\$<\\/span>)(<span style="[^"]+?">)\\s+?`
93
- );
94
- return {
95
- postprocess: (html, { lang }) => {
96
- if (lang === "console") {
97
- return html.split("\n").map((line) => {
98
- return line.replace(
99
- splitPrompt,
100
- unselectablePrompt + "<span $1>$2"
101
- ).replace(trimWhitespace, unselectablePrompt).replace(trimWhitespaceAhead, "$1");
102
- }).join("\n");
103
- }
104
- }
105
- };
106
- }
107
-
108
- export {
109
- slugify,
110
- splitFilenameComponents,
111
- transformAsciidocCallout,
112
- transformConsoleCodeBlock
113
- };