@antora/site-generator-default 3.0.0-alpha.9 → 3.0.0-beta.1
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 +3 -3
- package/lib/generate-site.js +26 -39
- package/lib/generator-context.js +160 -0
- package/lib/index.js +3 -4
- package/package.json +18 -15
- package/lib/pipeline.js +0 -90
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Antora Default Site Generator
|
|
2
2
|
|
|
3
|
-
This is the default site generator
|
|
4
|
-
This
|
|
3
|
+
This is the default site generator for Antora.
|
|
4
|
+
This generator is invoked by the `generate` command of Antora's CLI to produce and publish static documentation sites.
|
|
5
5
|
|
|
6
6
|
[Antora](https://antora.org) is a modular static site generator designed for creating documentation sites from AsciiDoc documents.
|
|
7
|
-
Its site generator
|
|
7
|
+
Its site generator aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
|
|
8
8
|
|
|
9
9
|
## Copyright and License
|
|
10
10
|
|
package/lib/generate-site.js
CHANGED
|
@@ -1,74 +1,61 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const GeneratorContext = require('./generator-context')
|
|
4
4
|
const SiteCatalog = require('./site-catalog')
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
const buildNavigation = require('@antora/navigation-builder')
|
|
8
|
-
const buildPlaybook = require('@antora/playbook-builder')
|
|
9
|
-
const classifyContent = require('@antora/content-classifier')
|
|
10
|
-
const convertDocuments = require('@antora/document-converter')
|
|
11
|
-
const createPageComposer = require('@antora/page-composer')
|
|
12
|
-
const loadUi = require('@antora/ui-loader')
|
|
13
|
-
const mapSite = require('@antora/site-mapper')
|
|
14
|
-
const produceRedirects = require('@antora/redirect-producer')
|
|
15
|
-
const publishSite = require('@antora/site-publisher')
|
|
16
|
-
const { resolveAsciiDocConfig } = require('@antora/asciidoc-loader')
|
|
17
|
-
|
|
18
|
-
async function generateSite (args, env) {
|
|
19
|
-
let playbook = buildPlaybook(args, env)
|
|
6
|
+
async function generateSite (playbook) {
|
|
20
7
|
try {
|
|
21
|
-
const
|
|
22
|
-
const vars =
|
|
23
|
-
await
|
|
8
|
+
const context = new GeneratorContext(playbook, module)
|
|
9
|
+
const { fxns, vars } = context
|
|
10
|
+
await context.notify('playbookBuilt')
|
|
24
11
|
playbook = vars.lock('playbook')
|
|
25
|
-
vars.asciidocConfig = resolveAsciiDocConfig(playbook)
|
|
12
|
+
vars.asciidocConfig = fxns.resolveAsciiDocConfig(playbook)
|
|
26
13
|
vars.siteCatalog = new SiteCatalog()
|
|
27
|
-
await
|
|
14
|
+
await context.notify('beforeProcess')
|
|
28
15
|
const asciidocConfig = vars.lock('asciidocConfig')
|
|
29
16
|
await Promise.all([
|
|
30
|
-
aggregateContent(playbook).then((contentAggregate) =>
|
|
31
|
-
|
|
32
|
-
vars.contentCatalog = classifyContent(playbook, vars.remove('contentAggregate'), asciidocConfig)
|
|
17
|
+
fxns.aggregateContent(playbook).then((contentAggregate) =>
|
|
18
|
+
context.notify('contentAggregated', Object.assign(vars, { contentAggregate })).then(() => {
|
|
19
|
+
vars.contentCatalog = fxns.classifyContent(playbook, vars.remove('contentAggregate'), asciidocConfig)
|
|
33
20
|
})
|
|
34
21
|
),
|
|
35
|
-
loadUi(playbook).then((uiCatalog) =>
|
|
22
|
+
fxns.loadUi(playbook).then((uiCatalog) => context.notify('uiLoaded', Object.assign(vars, { uiCatalog }))),
|
|
36
23
|
])
|
|
37
|
-
await
|
|
24
|
+
await context.notify('contentClassified')
|
|
38
25
|
const contentCatalog = vars.lock('contentCatalog')
|
|
39
26
|
const uiCatalog = vars.lock('uiCatalog')
|
|
40
|
-
convertDocuments(contentCatalog, asciidocConfig)
|
|
41
|
-
await
|
|
42
|
-
vars.navigationCatalog = buildNavigation(contentCatalog, asciidocConfig)
|
|
43
|
-
await
|
|
27
|
+
fxns.convertDocuments(contentCatalog, asciidocConfig)
|
|
28
|
+
await context.notify('documentsConverted')
|
|
29
|
+
vars.navigationCatalog = fxns.buildNavigation(contentCatalog, asciidocConfig)
|
|
30
|
+
await context.notify('navigationBuilt')
|
|
44
31
|
;(() => {
|
|
45
32
|
const navigationCatalog = vars.remove('navigationCatalog')
|
|
46
|
-
const composePage = createPageComposer(playbook, contentCatalog, uiCatalog, playbook.env)
|
|
33
|
+
const composePage = fxns.createPageComposer(playbook, contentCatalog, uiCatalog, playbook.env)
|
|
47
34
|
contentCatalog.getPages((page) => page.out && composePage(page, contentCatalog, navigationCatalog))
|
|
48
35
|
if (playbook.site.url) vars.siteCatalog.addFile(composePage(create404Page()))
|
|
49
36
|
})()
|
|
50
|
-
await
|
|
51
|
-
vars.siteCatalog.addFiles(produceRedirects(playbook, contentCatalog))
|
|
52
|
-
await
|
|
37
|
+
await context.notify('pagesComposed')
|
|
38
|
+
vars.siteCatalog.addFiles(fxns.produceRedirects(playbook, contentCatalog))
|
|
39
|
+
await context.notify('redirectsProduced')
|
|
53
40
|
if (playbook.site.url) {
|
|
54
41
|
const publishablePages = contentCatalog.getPages((page) => page.out)
|
|
55
|
-
vars.siteCatalog.addFiles(mapSite(playbook, publishablePages))
|
|
56
|
-
await
|
|
42
|
+
vars.siteCatalog.addFiles(fxns.mapSite(playbook, publishablePages))
|
|
43
|
+
await context.notify('siteMapped')
|
|
57
44
|
}
|
|
58
|
-
await
|
|
59
|
-
return publishSite(playbook, [contentCatalog, uiCatalog, vars.lock('siteCatalog')]).then((publications) => {
|
|
45
|
+
await context.notify('beforePublish')
|
|
46
|
+
return fxns.publishSite(playbook, [contentCatalog, uiCatalog, vars.lock('siteCatalog')]).then((publications) => {
|
|
60
47
|
if (!playbook.runtime.quiet && process.stdout.isTTY) {
|
|
61
48
|
process.stdout.write('Site generation complete!\n')
|
|
62
49
|
publications.forEach(
|
|
63
50
|
({ fileUri }) => fileUri && process.stdout.write(`View the site by visiting ${fileUri} in a browser.\n`)
|
|
64
51
|
)
|
|
65
52
|
}
|
|
66
|
-
return
|
|
53
|
+
return context
|
|
67
54
|
.notify('sitePublished', Object.assign(vars, { publications }))
|
|
68
55
|
.then(() => vars.remove('publications'))
|
|
69
56
|
})
|
|
70
57
|
} catch (err) {
|
|
71
|
-
if (!
|
|
58
|
+
if (!GeneratorContext.isHaltSignal(err)) throw err
|
|
72
59
|
}
|
|
73
60
|
}
|
|
74
61
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const EventEmitter = require('events')
|
|
4
|
+
const getLogger = require('@antora/logger')
|
|
5
|
+
const userRequire = require('@antora/user-require-helper')
|
|
6
|
+
|
|
7
|
+
const FUNCTION_PROVIDERS = {
|
|
8
|
+
aggregateContent: 'content-aggregator',
|
|
9
|
+
buildNavigation: 'navigation-builder',
|
|
10
|
+
classifyContent: 'content-classifier',
|
|
11
|
+
convertDocument: 'document-converter',
|
|
12
|
+
convertDocuments: 'document-converter',
|
|
13
|
+
createPageComposer: 'page-composer',
|
|
14
|
+
extractAsciiDocMetadata: 'asciidoc-loader',
|
|
15
|
+
loadAsciiDoc: 'asciidoc-loader',
|
|
16
|
+
loadUi: 'ui-loader',
|
|
17
|
+
mapSite: 'site-mapper',
|
|
18
|
+
produceRedirects: 'redirect-producer',
|
|
19
|
+
publishSite: 'site-publisher',
|
|
20
|
+
resolveAsciiDocConfig: 'asciidoc-loader',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class HaltSignal extends Error {}
|
|
24
|
+
|
|
25
|
+
class GeneratorContext extends EventEmitter {
|
|
26
|
+
#fxns
|
|
27
|
+
#vars
|
|
28
|
+
|
|
29
|
+
constructor (playbook, module_) {
|
|
30
|
+
super()
|
|
31
|
+
if (!('path' in (this.module = module_))) module_.path = require('path').dirname(module_.filename)
|
|
32
|
+
this._registerFunctions(module_)
|
|
33
|
+
this._registerExtensions(playbook, this._initVariables(playbook), module_)
|
|
34
|
+
Object.defineProperties(this, { _initVariables: {}, _registerExtensions: {}, _registerFunctions: {} })
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getFunctions () {
|
|
38
|
+
return arguments.length ? this.#fxns : Object.assign({}, this.#fxns)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getLogger (name = 'antora') {
|
|
42
|
+
return getLogger(name)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getVariables () {
|
|
46
|
+
return Object.assign({}, this.#vars)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
halt () {
|
|
50
|
+
throw new HaltSignal()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async notify (eventName) {
|
|
54
|
+
if (!this.listenerCount(eventName)) return
|
|
55
|
+
for (const listener of this.rawListeners(eventName)) {
|
|
56
|
+
const outcome = listener.length === 1 ? listener.call(this, this.getVariables()) : listener.call(this)
|
|
57
|
+
if (outcome instanceof Promise) await outcome
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
replaceFunctions (updates) {
|
|
62
|
+
const fxns = this.#fxns
|
|
63
|
+
Object.entries(updates).map(([name, fxn]) => {
|
|
64
|
+
if (name in fxns) fxns[name] = fxn.bind(this)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
require (request) {
|
|
69
|
+
return this.module.require(request)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
updateVariables (updates) {
|
|
73
|
+
try {
|
|
74
|
+
Object.assign(this.#vars, updates)
|
|
75
|
+
} catch (err) {
|
|
76
|
+
if (err instanceof TypeError) {
|
|
77
|
+
err.message = err.message.replace(/ assign to read.only property '(.+)' .*/, " update read-only var '$1'")
|
|
78
|
+
}
|
|
79
|
+
throw err
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// TODO remove updateVars before Antora 3.0.0
|
|
84
|
+
updateVars (updates) {
|
|
85
|
+
return this.updateVariables(updates)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static isHaltSignal (err) {
|
|
89
|
+
return err instanceof HaltSignal
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
_initVariables (playbook) {
|
|
93
|
+
Object.defineProperty(this, 'vars', {
|
|
94
|
+
configurable: true,
|
|
95
|
+
get: () => {
|
|
96
|
+
delete this.vars
|
|
97
|
+
return Object.setPrototypeOf(this.#vars, {
|
|
98
|
+
lock (name) {
|
|
99
|
+
return Object.defineProperty(this, name, { configurable: false, writable: false })[name]
|
|
100
|
+
},
|
|
101
|
+
remove (name) {
|
|
102
|
+
const currentValue = this[name]
|
|
103
|
+
delete this[name]
|
|
104
|
+
return currentValue
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
return (this.#vars = { playbook })
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
_registerExtensions (playbook, vars, module_) {
|
|
113
|
+
const extensions = (playbook.antora || {}).extensions || []
|
|
114
|
+
if (extensions.length) {
|
|
115
|
+
const requireContext = { dot: playbook.dir, paths: [playbook.dir || '', module_.path] }
|
|
116
|
+
extensions.forEach((ext) => {
|
|
117
|
+
const { enabled = true, id, require: request, ...config } = ext.constructor === String ? { require: ext } : ext
|
|
118
|
+
if (!enabled) return
|
|
119
|
+
const { register } = userRequire(request, requireContext)
|
|
120
|
+
if (typeof register !== 'function') return
|
|
121
|
+
if (register.length) {
|
|
122
|
+
if (/^(?:function *)?(?:\w+ *)?\( *\w|^\w+(?: *, *\w+)* *=>/.test(register.toString().replace(/\r?\n/g, ' '))) {
|
|
123
|
+
register.length === 1 ? register(this) : register(this, Object.assign({ config }, vars))
|
|
124
|
+
} else {
|
|
125
|
+
register.call(this, Object.assign({ config }, vars))
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
register.call(this)
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
this.notify = this.eventNames().length ? this.notify.bind(this) : async () => undefined
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
_registerFunctions (module_) {
|
|
136
|
+
this.#fxns = Object.entries(
|
|
137
|
+
Object.entries(FUNCTION_PROVIDERS).reduce((accum, [fxnName, moduleKey]) => {
|
|
138
|
+
accum[moduleKey] = (accum[moduleKey] || []).concat(fxnName)
|
|
139
|
+
return accum
|
|
140
|
+
}, {})
|
|
141
|
+
).reduce((accum, [moduleKey, fxnNames]) => {
|
|
142
|
+
const defaultExport = module_.require('@antora/' + moduleKey)
|
|
143
|
+
const defaultExportName = defaultExport.name
|
|
144
|
+
fxnNames.forEach((fxnName) => {
|
|
145
|
+
const fxn = fxnName === defaultExportName ? defaultExport : defaultExport[fxnName]
|
|
146
|
+
accum[fxnName] = fxn.bind(this)
|
|
147
|
+
})
|
|
148
|
+
return accum
|
|
149
|
+
}, {})
|
|
150
|
+
Object.defineProperty(this, 'fxns', {
|
|
151
|
+
configurable: true,
|
|
152
|
+
get: () => {
|
|
153
|
+
delete this.fxns
|
|
154
|
+
return this.#fxns
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = GeneratorContext
|
package/lib/index.js
CHANGED
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Default Site Generator component for Antora
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* pipeline.
|
|
6
|
+
* Coordinates a default set of software components to produce and publish a
|
|
7
|
+
* documentation site. This component represents just one way the Antora
|
|
8
|
+
* components can be organized to make a documentation generator.
|
|
10
9
|
*
|
|
11
10
|
* @namespace site-generator-default
|
|
12
11
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/site-generator-default",
|
|
3
|
-
"version": "3.0.0-
|
|
4
|
-
"description": "The default site generator
|
|
3
|
+
"version": "3.0.0-beta.1",
|
|
4
|
+
"description": "The default site generator for producing and publishing static documentation sites with Antora.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "OpenDevise Inc. (https://opendevise.com)",
|
|
7
7
|
"contributors": [
|
|
@@ -15,21 +15,24 @@
|
|
|
15
15
|
},
|
|
16
16
|
"main": "lib/index.js",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@antora/asciidoc-loader": "3.0.0-
|
|
19
|
-
"@antora/content-aggregator": "3.0.0-
|
|
20
|
-
"@antora/content-classifier": "3.0.0-
|
|
21
|
-
"@antora/document-converter": "3.0.0-
|
|
22
|
-
"@antora/
|
|
23
|
-
"@antora/
|
|
24
|
-
"@antora/
|
|
25
|
-
"@antora/redirect-producer": "3.0.0-
|
|
26
|
-
"@antora/site-mapper": "3.0.0-
|
|
27
|
-
"@antora/site-publisher": "3.0.0-
|
|
28
|
-
"@antora/ui-loader": "3.0.0-
|
|
18
|
+
"@antora/asciidoc-loader": "3.0.0-beta.1",
|
|
19
|
+
"@antora/content-aggregator": "3.0.0-beta.1",
|
|
20
|
+
"@antora/content-classifier": "3.0.0-beta.1",
|
|
21
|
+
"@antora/document-converter": "3.0.0-beta.1",
|
|
22
|
+
"@antora/logger": "3.0.0-beta.1",
|
|
23
|
+
"@antora/navigation-builder": "3.0.0-beta.1",
|
|
24
|
+
"@antora/page-composer": "3.0.0-beta.1",
|
|
25
|
+
"@antora/redirect-producer": "3.0.0-beta.1",
|
|
26
|
+
"@antora/site-mapper": "3.0.0-beta.1",
|
|
27
|
+
"@antora/site-publisher": "3.0.0-beta.1",
|
|
28
|
+
"@antora/ui-loader": "3.0.0-beta.1",
|
|
29
29
|
"@antora/user-require-helper": "~2.0"
|
|
30
30
|
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@antora/playbook-builder": "3.0.0-beta.1"
|
|
33
|
+
},
|
|
31
34
|
"engines": {
|
|
32
|
-
"node": ">=
|
|
35
|
+
"node": ">=12.21.0"
|
|
33
36
|
},
|
|
34
37
|
"files": [
|
|
35
38
|
"lib/"
|
|
@@ -43,5 +46,5 @@
|
|
|
43
46
|
"static site",
|
|
44
47
|
"web publishing"
|
|
45
48
|
],
|
|
46
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "7c5ef1ea93dd489af533c80a936c736013c41769"
|
|
47
50
|
}
|
package/lib/pipeline.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const EventEmitter = require('events')
|
|
4
|
-
const userRequire = require('@antora/user-require-helper')
|
|
5
|
-
|
|
6
|
-
class HaltPipelineSignal extends Error {}
|
|
7
|
-
|
|
8
|
-
class Pipeline extends EventEmitter {
|
|
9
|
-
constructor (playbook, module_) {
|
|
10
|
-
super()
|
|
11
|
-
if (!('path' in (this.module = module_))) module_.path = require('path').dirname(module_.filename)
|
|
12
|
-
_registerExtensions.bind(this)(playbook, module_, _initVars.bind(this)(playbook))
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
halt () {
|
|
16
|
-
throw new HaltPipelineSignal()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async notify (vars, eventName) {
|
|
20
|
-
if (this.listenerCount(eventName)) {
|
|
21
|
-
for (const listener of this.rawListeners(eventName)) {
|
|
22
|
-
const outcome = listener.call(this, Object.assign({}, vars))
|
|
23
|
-
if (outcome instanceof Promise) await outcome
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
require (request) {
|
|
29
|
-
return this.module.require(request)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
updateVars (vars, updates) {
|
|
33
|
-
try {
|
|
34
|
-
Object.assign(vars, updates)
|
|
35
|
-
} catch (err) {
|
|
36
|
-
if (err instanceof TypeError) {
|
|
37
|
-
err.message = err.message.replace(/ assign to read.only property '(.+)' .*/, " update read-only var '$1'")
|
|
38
|
-
}
|
|
39
|
-
throw err
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
static isHaltSignal (err) {
|
|
44
|
-
return err instanceof HaltPipelineSignal
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function _initVars (playbook) {
|
|
49
|
-
const vars = Object.setPrototypeOf(
|
|
50
|
-
{ playbook },
|
|
51
|
-
{
|
|
52
|
-
lock (name) {
|
|
53
|
-
return Object.defineProperty(this, name, { configurable: false, writable: false })[name]
|
|
54
|
-
},
|
|
55
|
-
remove (name) {
|
|
56
|
-
const currentValue = this[name]
|
|
57
|
-
delete this[name]
|
|
58
|
-
return currentValue
|
|
59
|
-
},
|
|
60
|
-
}
|
|
61
|
-
)
|
|
62
|
-
Object.defineProperty(this, 'vars', {
|
|
63
|
-
configurable: true,
|
|
64
|
-
get: () => {
|
|
65
|
-
delete this.vars
|
|
66
|
-
return vars
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
this.updateVars = this.updateVars.bind(this, vars)
|
|
70
|
-
return vars
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function _registerExtensions (playbook, module_, vars) {
|
|
74
|
-
const extensions = (playbook.pipeline || {}).extensions
|
|
75
|
-
if (extensions.length) {
|
|
76
|
-
const requireContext = { dot: playbook.dir, paths: [playbook.dir || '', module_.path] }
|
|
77
|
-
extensions.forEach((ext) => {
|
|
78
|
-
const { enabled = true, id, require: request, ...config } = ext.constructor === String ? { require: ext } : ext
|
|
79
|
-
if (enabled) {
|
|
80
|
-
const { register } = userRequire(request, requireContext)
|
|
81
|
-
if (typeof register === 'function') {
|
|
82
|
-
register.length === 1 ? register(this) : register(this, Object.assign({ config }, vars))
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
this.notify = this.eventNames().length ? this.notify.bind(this, vars) : async () => undefined
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
module.exports = Pipeline
|