eleventy-plugin-asciidoc 5.0.1 → 6.0.0
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/.eslintrc.cjs +11 -0
- package/README.md +31 -10
- package/index.js +19 -30
- package/lefthook.yml +16 -0
- package/lib/eleventy-asciidoc.js +87 -59
- package/lib/utils/asciidoc.js +1 -5
- package/lib/utils/object.js +3 -9
- package/package.json +12 -21
package/.eslintrc.cjs
ADDED
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ module.exports = function (eleventyConfig) {
|
|
|
35
35
|
};
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
## Front Matter
|
|
39
39
|
|
|
40
40
|
You can use either [Eleventy style front matter](https://www.11ty.dev/docs/data-frontmatter/#front-matter-formats) or AsciiDoc document attributes to write front matter.
|
|
41
41
|
|
|
@@ -68,7 +68,7 @@ Hello everyone!
|
|
|
68
68
|
> [!WARNING]
|
|
69
69
|
> Asciidoctor.js converts all attribute names to lower case letters. Example `:eleventy-aTitle:` will be made available as `atitle` in front matter data (also as `eleventy-atitle` in document attributes).
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
### Data Cascade
|
|
72
72
|
|
|
73
73
|
Data specified using AsciiDoc style front matter override YAML (or front matter in other Eleventy supported formats).
|
|
74
74
|
|
|
@@ -87,9 +87,36 @@ In the above case, front matter data will have `{ layout: layout-b.njk }`.
|
|
|
87
87
|
|
|
88
88
|
In the case of `title`, [the AsciiDoc document title](https://docs.asciidoctor.org/asciidoc/latest/document/title/) (including `title` and `doctitle` attributes) takes precedence over front matter.
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
## Options
|
|
91
|
+
|
|
92
|
+
You can pass options as the second argument in `addPlugin()`.
|
|
93
|
+
|
|
94
|
+
### Options for this plugin
|
|
95
|
+
|
|
96
|
+
#### `eleventyAttributesPrefix`
|
|
97
|
+
|
|
98
|
+
Default value is `eleventy-`.
|
|
99
|
+
|
|
100
|
+
This config can be used to change the prefix string for [AsciiDoc style front matter](#front-matter).
|
|
101
|
+
|
|
102
|
+
#### `resolveDocumentTitle`
|
|
103
|
+
|
|
104
|
+
Default value is `false`.
|
|
105
|
+
|
|
106
|
+
If enabled, the title will be resolved from the heading of the first section in the document. Otherwise, the title will be the Level 0 heading.
|
|
107
|
+
|
|
108
|
+
```adoc
|
|
109
|
+
== A second level heading
|
|
110
|
+
|
|
111
|
+
This text is written in AsciiDoc format.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
With `resolveDocumentTitle: true`, the above document will have a title (in page data). `A second level heading`.
|
|
115
|
+
|
|
116
|
+
### Options for Asciidoctor.js
|
|
117
|
+
|
|
118
|
+
All properties other than [the ones specific to the plugin](#options-for-this-plugin) will be passed to Asciidoctor.js.
|
|
91
119
|
|
|
92
|
-
You can pass options to `convert()` of Asciidoctor.js as second argument in `addPlugin()`.
|
|
93
120
|
These are the [available options](https://docs.asciidoctor.org/asciidoctor.js/latest/processor/convert-options/).
|
|
94
121
|
|
|
95
122
|
```js
|
|
@@ -144,12 +171,6 @@ module.exports = function (eleventyConfig) {
|
|
|
144
171
|
|
|
145
172
|
Refer to [Asciidoctor.js documentation](https://docs.asciidoctor.org/asciidoctor.js/latest/extend/extensions/) to know more about extensions.
|
|
146
173
|
|
|
147
|
-
#### `eleventyAttributesPrefix`
|
|
148
|
-
|
|
149
|
-
Default value is `eleventy-`.
|
|
150
|
-
|
|
151
|
-
This config can be used to change the prefix string for [AsciiDoc style front matter](#front-matter).
|
|
152
|
-
|
|
153
174
|
### CSS Styles
|
|
154
175
|
|
|
155
176
|
The plugin does not include any CSS styles. It is up to you to style the content.
|
package/index.js
CHANGED
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
3
|
-
const pkg = require("./package.json");
|
|
2
|
+
import eleventyAsciidoc from "./lib/eleventy-asciidoc.js";
|
|
4
3
|
|
|
5
4
|
/** @typedef {import('./lib/eleventy-asciidoc.js').EleventyAsciidocOptions} EleventyAsciidocOptions} */
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} catch (e) {
|
|
18
|
-
console.log(
|
|
19
|
-
`WARN: Eleventy Plugin (${pkg.name}) Compatibility: ${e.message}`,
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (converterOptions?.extension_registry !== undefined) {
|
|
24
|
-
console.log(
|
|
25
|
-
`WARN: 'extension_registry' doesn't work well with Asciidoctor.js v3+. Use 'configure_extension_registry'.`,
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
eleventyConfig.addTemplateFormats(["adoc", "asciidoc", "ad"]);
|
|
30
|
-
eleventyConfig.addExtension(
|
|
31
|
-
["adoc", "asciidoc", "ad"],
|
|
32
|
-
eleventyAsciidoc(converterOptions),
|
|
6
|
+
/**
|
|
7
|
+
* Plugin config function
|
|
8
|
+
*
|
|
9
|
+
* @param {object} eleventyConfig The eleventy configuration object
|
|
10
|
+
* @param {EleventyAsciidocOptions} converterOptions Options for Asciidoctor.converter()
|
|
11
|
+
*/
|
|
12
|
+
export default function config(eleventyConfig, converterOptions) {
|
|
13
|
+
if (converterOptions?.extension_registry !== undefined) {
|
|
14
|
+
console.log(
|
|
15
|
+
`WARN: 'extension_registry' doesn't work well with Asciidoctor.js v3+. Use 'configure_extension_registry'.`,
|
|
33
16
|
);
|
|
34
|
-
}
|
|
35
|
-
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
eleventyConfig.addTemplateFormats(["adoc", "asciidoc", "ad"]);
|
|
20
|
+
eleventyConfig.addExtension(
|
|
21
|
+
["adoc", "asciidoc", "ad"],
|
|
22
|
+
eleventyAsciidoc(converterOptions),
|
|
23
|
+
);
|
|
24
|
+
}
|
package/lefthook.yml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
pre-commit:
|
|
2
|
+
commands:
|
|
3
|
+
# Prettier for JS is included in ESlint
|
|
4
|
+
prettier:
|
|
5
|
+
glob: "*.{md,json}"
|
|
6
|
+
run: npx prettier --write {staged_files}
|
|
7
|
+
stage_fixed: true
|
|
8
|
+
|
|
9
|
+
eslint:
|
|
10
|
+
glob: "*.{js,mjs,cjs}"
|
|
11
|
+
run: npx eslint --fix {staged_files}
|
|
12
|
+
stage_fixed: true
|
|
13
|
+
|
|
14
|
+
tests:
|
|
15
|
+
glob: "*.{js,mjs,cjs}"
|
|
16
|
+
run: npm run test
|
package/lib/eleventy-asciidoc.js
CHANGED
|
@@ -1,35 +1,55 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/* eslint camelcase: ["error", {allow: ["base_dir", "extension_registry", "configure_extension_registry"]}] */
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const processor = asciidoctor();
|
|
4
|
+
import { load, Extensions, convert } from "@asciidoctor/core";
|
|
5
|
+
import libDebug from "debug";
|
|
6
|
+
import fs from "node:fs/promises";
|
|
7
|
+
import matter from "gray-matter";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import nunjucks from "nunjucks";
|
|
10
|
+
import { parseDocumentAttributes } from "./utils/asciidoc.js";
|
|
11
|
+
import { pickByKeyPrefix, mapKeys, pick } from "./utils/object.js";
|
|
12
|
+
|
|
13
|
+
const debug = libDebug("eleventy-plugin-asciidoc");
|
|
15
14
|
|
|
16
15
|
/** @typedef {import('gray-matter').GrayMatterFile} GrayMatterFile */
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* @typedef {Object} ExtraProcessorOptions
|
|
20
19
|
* @property {string=} eleventyAttributesPrefix
|
|
20
|
+
* @property {Boolean} [resolveDocumentTitle=false]
|
|
21
21
|
* @typedef {import('@asciidoctor/core').ProcessorOptions & ExtraProcessorOptions} EleventyAsciidocOptions
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Reads
|
|
25
|
+
* Reads files and separates front matter and content asynchronously.
|
|
26
26
|
*
|
|
27
|
-
* @param {string}
|
|
28
|
-
* @return {GrayMatterFile}
|
|
27
|
+
* @param {string} inputPath Path to file
|
|
28
|
+
* @return {Promise<GrayMatterFile>}
|
|
29
|
+
*/
|
|
30
|
+
async function readFileAsync(inputPath) {
|
|
31
|
+
try {
|
|
32
|
+
const fileContent = await fs.readFile(inputPath);
|
|
33
|
+
return matter(fileContent);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new Error(`Unable to read path. ${e.error}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Gets the title from ascii document document.
|
|
41
|
+
*
|
|
42
|
+
* @param {object} document The document
|
|
43
|
+
* @param {boolean} [resolve=false] The resolve
|
|
44
|
+
* @return {string | undefined} The title of the document.
|
|
29
45
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
function getTitleFromAsciiDocDocument(document, resolve = false) {
|
|
47
|
+
if (resolve) {
|
|
48
|
+
return document.getDocumentTitle();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return document.getHeader()?.title;
|
|
52
|
+
}
|
|
33
53
|
|
|
34
54
|
/** @typedef {(inputPath: string) => Object.<string, any>} GetDataFn
|
|
35
55
|
* Gets front-matter data from the file synchronously
|
|
@@ -42,46 +62,54 @@ const readFileSync = (inputPath) => {
|
|
|
42
62
|
* @return {GetDataFn}
|
|
43
63
|
*/
|
|
44
64
|
|
|
45
|
-
const generateGetDataFromInputPath =
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
const generateGetDataFromInputPath =
|
|
66
|
+
(converterOptions) => async (inputPath) => {
|
|
67
|
+
const { content } = await readFileAsync(inputPath);
|
|
68
|
+
const {
|
|
69
|
+
eleventyAttributesPrefix = "eleventy-",
|
|
70
|
+
resolveDocumentTitle = false,
|
|
71
|
+
...restOfConverterOptions
|
|
72
|
+
} = converterOptions;
|
|
73
|
+
|
|
74
|
+
const doc = await load(content, {
|
|
75
|
+
...restOfConverterOptions,
|
|
76
|
+
base_dir: getBaseDir(inputPath, restOfConverterOptions.base_dir),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const title = getTitleFromAsciiDocDocument(doc, resolveDocumentTitle);
|
|
80
|
+
|
|
81
|
+
const attributes = doc.getAttributes();
|
|
82
|
+
|
|
83
|
+
let eleventyAttributes = pickByKeyPrefix(
|
|
84
|
+
attributes,
|
|
85
|
+
eleventyAttributesPrefix,
|
|
86
|
+
);
|
|
87
|
+
eleventyAttributes = mapKeys(eleventyAttributes, (k) =>
|
|
88
|
+
k.slice(eleventyAttributesPrefix.length),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
debug(`Document title ${title}`);
|
|
92
|
+
debug(`Document attributes: ${JSON.stringify(attributes)}`);
|
|
93
|
+
debug(
|
|
94
|
+
`Document Eleventy attributes: ${JSON.stringify(eleventyAttributes)}`,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
let data = {
|
|
98
|
+
asciidocAttributes: attributes,
|
|
99
|
+
...eleventyAttributes,
|
|
100
|
+
// Pass title only if defined. Otherwise, `undefined`
|
|
101
|
+
// will override the title in `eleventyAttributes`
|
|
102
|
+
...(title === undefined ? {} : { title }),
|
|
103
|
+
};
|
|
76
104
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
105
|
+
// Removes undefined values
|
|
106
|
+
// that may override Eleventy page data.
|
|
107
|
+
data = pick(data, (k, v) => v !== undefined);
|
|
80
108
|
|
|
81
|
-
|
|
82
|
-
|
|
109
|
+
return {
|
|
110
|
+
data,
|
|
111
|
+
};
|
|
83
112
|
};
|
|
84
|
-
};
|
|
85
113
|
|
|
86
114
|
/**
|
|
87
115
|
* Gets the base directory if available, otherwise from input path
|
|
@@ -107,9 +135,9 @@ function eleventyAsciidoctor(convertOptions = {}) {
|
|
|
107
135
|
...convertOptions,
|
|
108
136
|
};
|
|
109
137
|
|
|
110
|
-
const compile = (_contents, inputPath) => (data) => {
|
|
138
|
+
const compile = (_contents, inputPath) => async (data) => {
|
|
111
139
|
debug(`Reading ${inputPath}`);
|
|
112
|
-
const { content } =
|
|
140
|
+
const { content } = await readFileAsync(inputPath);
|
|
113
141
|
|
|
114
142
|
let { base_dir, configure_extension_registry } = options;
|
|
115
143
|
const attributes = parseDocumentAttributes(options.attributes ?? {});
|
|
@@ -145,11 +173,11 @@ function eleventyAsciidoctor(convertOptions = {}) {
|
|
|
145
173
|
let registry;
|
|
146
174
|
if (typeof configure_extension_registry === "function") {
|
|
147
175
|
debug(`Creating an extension registry`);
|
|
148
|
-
registry =
|
|
176
|
+
registry = Extensions.create();
|
|
149
177
|
configure_extension_registry(registry);
|
|
150
178
|
}
|
|
151
179
|
|
|
152
|
-
return
|
|
180
|
+
return convert(content, {
|
|
153
181
|
...converterOptions,
|
|
154
182
|
extension_registry: registry,
|
|
155
183
|
});
|
|
@@ -181,4 +209,4 @@ function eleventyAsciidoctor(convertOptions = {}) {
|
|
|
181
209
|
};
|
|
182
210
|
}
|
|
183
211
|
|
|
184
|
-
|
|
212
|
+
export default eleventyAsciidoctor;
|
package/lib/utils/asciidoc.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @param {Attributes | string[] | string} attrs AsciiDoc Document Attributes
|
|
9
9
|
* @return {Attributes} Attributes as Object
|
|
10
10
|
*/
|
|
11
|
-
function parseDocumentAttributes(attrs) {
|
|
11
|
+
export function parseDocumentAttributes(attrs) {
|
|
12
12
|
if (Array.isArray(attrs)) {
|
|
13
13
|
return Object.fromEntries(attrs.map((a) => a.split("=")));
|
|
14
14
|
}
|
|
@@ -19,7 +19,3 @@ function parseDocumentAttributes(attrs) {
|
|
|
19
19
|
|
|
20
20
|
return attrs;
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
module.exports = {
|
|
24
|
-
parseDocumentAttributes,
|
|
25
|
-
};
|
package/lib/utils/object.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @param {(key: string, value: any, obj: object ) => boolean | Array<string>} keys The keys
|
|
8
8
|
* @return {object} Copy of the object with filtered values
|
|
9
9
|
*/
|
|
10
|
-
function pick(obj, keys = (_k, v) => Boolean(v)) {
|
|
10
|
+
export function pick(obj, keys = (_k, v) => Boolean(v)) {
|
|
11
11
|
if (Array.isArray(keys)) {
|
|
12
12
|
return pick(obj, (key) => keys.includes(key));
|
|
13
13
|
}
|
|
@@ -31,7 +31,7 @@ function pick(obj, keys = (_k, v) => Boolean(v)) {
|
|
|
31
31
|
* @param {string} prefix The key prefix
|
|
32
32
|
* @return {object} Copy of the object with filtered values
|
|
33
33
|
*/
|
|
34
|
-
function pickByKeyPrefix(obj, prefix) {
|
|
34
|
+
export function pickByKeyPrefix(obj, prefix) {
|
|
35
35
|
return pick(obj, (k) => k.startsWith(prefix));
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -42,7 +42,7 @@ function pickByKeyPrefix(obj, prefix) {
|
|
|
42
42
|
* @param {(k: string, v: any)=> string} [mapKey=(k)=>k] The function to map the keys
|
|
43
43
|
* @return {object} { Copy of the object with mapped keys }
|
|
44
44
|
*/
|
|
45
|
-
function mapKeys(obj, mapKey = (k) => k) {
|
|
45
|
+
export function mapKeys(obj, mapKey = (k) => k) {
|
|
46
46
|
return Object.entries(obj).reduce((acc, [k, v]) => {
|
|
47
47
|
const newKey = mapKey(k, v);
|
|
48
48
|
return {
|
|
@@ -51,9 +51,3 @@ function mapKeys(obj, mapKey = (k) => k) {
|
|
|
51
51
|
};
|
|
52
52
|
}, {});
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
module.exports = {
|
|
56
|
-
pickByKeyPrefix,
|
|
57
|
-
pick,
|
|
58
|
-
mapKeys,
|
|
59
|
-
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eleventy-plugin-asciidoc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Adds support for AsciiDoc to Eleventy",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"funding": "https://github.com/sponsors/saneef/",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
@@ -10,8 +11,7 @@
|
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
13
|
"lint": "eslint lib/**.js tests/**.js",
|
|
13
|
-
"test": "
|
|
14
|
-
"prepare": "husky install"
|
|
14
|
+
"test": "ava -v --color"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
17
17
|
"asciidoc",
|
|
@@ -22,31 +22,22 @@
|
|
|
22
22
|
],
|
|
23
23
|
"author": "Saneef Ansari <hello@saneef.com> (https://saneef.com/)",
|
|
24
24
|
"license": "MIT",
|
|
25
|
-
"11ty": {
|
|
26
|
-
"compatibility": ">=2.0.0-canary.19"
|
|
27
|
-
},
|
|
28
25
|
"dependencies": {
|
|
29
|
-
"@asciidoctor/core": "^
|
|
30
|
-
"debug": "^4.4.
|
|
26
|
+
"@asciidoctor/core": "^4.0.0",
|
|
27
|
+
"debug": "^4.4.3",
|
|
31
28
|
"gray-matter": "^4.0.3",
|
|
32
29
|
"nunjucks": "^3.2.4"
|
|
33
30
|
},
|
|
34
31
|
"devDependencies": {
|
|
35
|
-
"@11ty/eleventy": "^3.
|
|
36
|
-
"ava": "^
|
|
32
|
+
"@11ty/eleventy": "^3.1.6",
|
|
33
|
+
"ava": "^8.0.1",
|
|
37
34
|
"eslint": "^8.56.0",
|
|
38
|
-
"eslint-config-prettier": "^10.
|
|
35
|
+
"eslint-config-prettier": "^10.1.8",
|
|
39
36
|
"eslint-config-xo-space": "^0.35.0",
|
|
40
|
-
"eslint-plugin-prettier": "^5.
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"prettier": "^3.5.2",
|
|
45
|
-
"rimraf": "^6.0.1"
|
|
46
|
-
},
|
|
47
|
-
"lint-staged": {
|
|
48
|
-
"*.{js,mjs,cjs}": "eslint --cache --fix",
|
|
49
|
-
"*.{js,md,json}": "prettier --write"
|
|
37
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
38
|
+
"lefthook": "^2.1.9",
|
|
39
|
+
"prettier": "^3.9.4",
|
|
40
|
+
"rimraf": "^6.1.3"
|
|
50
41
|
},
|
|
51
42
|
"ava": {
|
|
52
43
|
"files": [
|