-
Notifications
You must be signed in to change notification settings - Fork 0
/
.eleventy.js
90 lines (75 loc) · 2.22 KB
/
.eleventy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const fs = require('node:fs')
const { parseHTML } = require('linkedom')
const frontMatter = require('gray-matter')
const MarkdownIt = require('markdown-it')
/**
* @callback EleventyCustomTemplateFilter
* @param {string} inputContent
* @param {string} inputPath
* @returns {boolean}
*/
/**
* @callback EleventyCustomTemplateRender
* @param {any} data
* @returns {string}
*/
/**
* @callback EleventyCustomTransform
* @param {Window} DOM
* @param {string} inputContent
* @param {string} inputPath
* @param {any} data
* @returns {void}
*/
/**
* @callback EleventyDataParser
* @param {Window} DOM
* @returns {Object}
*/
/**
* @typedef {Object} Options
* @property {EleventyCustomTemplateFilter} [filter]
* @property {EleventyCustomTemplateRender} [render]
* @property {Array<EleventyCustomTransform>} [transforms]
* @property {Array<EleventyDataParser>} [dataParsers]
*/
module.exports = function(eleventyConfig, /** @type {Options} */options = {}) {
eleventyConfig.addExtension('md', {
read: true,
encoding: 'utf-8',
async getData(inputPath) {
if (!options.dataParsers) {
return {}
}
const { content: markdown } = frontMatter(await fs.promises.readFile(inputPath, 'utf-8'))
const markdownLib = new MarkdownIt()
const html = markdownLib.render(markdown)
const DOM = parseHTML(html)
const data = {}
for (const parser of options.dataParsers) {
Object.assign(data, parser(DOM))
}
return data
},
async compile(inputContent, inputPath) {
if (typeof options.filter === 'function' && !options.filter(inputContent, inputPath)) {
return
}
return async function(data) {
const markdownRenderer = options.render
? options.render(inputContent, inputPath)
: this.defaultRenderer
const content = await markdownRenderer.call(this, data)
if (options.transforms && options.transforms.length > 0) {
const DOM = parseHTML(content)
for (const transform of options.transforms) {
await transform(DOM, inputContent, inputPath, data)
}
return DOM.document.toString()
} else {
return content
}
}
}
})
}