/
gatsby-node.js
140 lines (118 loc) · 3.88 KB
/
gatsby-node.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const asciidoc = require(`asciidoctor`)()
const _ = require(`lodash`)
function shouldOnCreateNode({ node }, pluginOptions = {}) {
const extensionsConfig = pluginOptions.fileExtensions
// make extensions configurable and use adoc and asciidoc as default
const supportedExtensions =
extensionsConfig instanceof Array ? extensionsConfig : [`adoc`, `asciidoc`]
return supportedExtensions.includes(node.extension)
}
async function onCreateNode(
{
node,
actions,
pathPrefix,
loadNodeContent,
createNodeId,
reporter,
createContentDigest,
},
pluginOptions
) {
// register custom converter if given
if (pluginOptions.converterFactory) {
asciidoc.ConverterFactory.register(
new pluginOptions.converterFactory(asciidoc),
[`html5`]
)
}
// changes the incoming imagesdir option to take the
const asciidocOptions = processPluginOptions(pluginOptions, pathPrefix)
const { createNode, createParentChildLink } = actions
// Load Asciidoc contents
const content = await loadNodeContent(node)
// Load Asciidoc file for extracting
// https://asciidoctor-docs.netlify.app/asciidoctor.js/processor/extract-api/
// We use a `let` here as a warning: some operations, like .convert() mutate the document
const doc = await asciidoc.load(content, {
base_dir: node.dir,
...asciidocOptions,
})
try {
const html = doc.convert()
// Use "partition" option to be able to get title, subtitle, combined
const title = doc.getDocumentTitle({ partition: true })
let revision = null
let author = null
if (doc.hasRevisionInfo()) {
revision = {
date: doc.getRevisionDate(),
number: doc.getRevisionNumber(),
remark: doc.getRevisionRemark(),
}
}
if (doc.getAuthor()) {
author = {
fullName: doc.getAttribute(`author`),
firstName: doc.getAttribute(`firstname`),
lastName: doc.getAttribute(`lastname`) || ``,
middleName: doc.getAttribute(`middlename`) || ``,
authorInitials: doc.getAttribute(`authorinitials`) || ``,
email: doc.getAttribute(`email`) || ``,
}
}
const pageAttributes = extractPageAttributes(doc.getAttributes())
const asciiNode = {
id: createNodeId(`${node.id} >>> ASCIIDOC`),
parent: node.id,
internal: {
type: `Asciidoc`,
mediaType: `text/html`,
},
children: [],
html,
document: {
title: title?.getCombined() ?? ``,
subtitle: title?.hasSubtitle() ? title.getSubtitle() : ``,
main: title?.getMain() ?? ``,
},
revision,
author,
pageAttributes,
}
asciiNode.internal.contentDigest = createContentDigest(asciiNode)
createNode(asciiNode)
createParentChildLink({ parent: node, child: asciiNode })
} catch (err) {
reporter.panicOnBuild(
`Error processing Asciidoc ${
node.absolutePath ? `file ${node.absolutePath}` : `in node ${node.id}`
}:\n
${err.message}`
)
}
}
const processPluginOptions = _.memoize((pluginOptions, pathPrefix) => {
const defaultImagesDir = `/images@`
const currentPathPrefix = pathPrefix || ``
const clonedPluginOptions = _.cloneDeep(pluginOptions)
if (clonedPluginOptions.attributes === undefined) {
clonedPluginOptions.attributes = {}
}
clonedPluginOptions.attributes.imagesdir = withPathPrefix(
currentPathPrefix,
clonedPluginOptions.attributes.imagesdir || defaultImagesDir
)
return clonedPluginOptions
})
const withPathPrefix = (pathPrefix, url) =>
(pathPrefix + url).replace(/\/\//, `/`)
const extractPageAttributes = allAttributes =>
Object.entries(allAttributes).reduce((pageAttributes, [key, value]) => {
if (key.startsWith(`page-`)) {
pageAttributes[key.replace(/^page-/, ``)] = value
}
return pageAttributes
}, {})
exports.shouldOnCreateNode = shouldOnCreateNode
exports.onCreateNode = onCreateNode