@antora/assembler 1.0.0-alpha.6 → 1.0.0-alpha.7
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/lib/assemble-content.js
CHANGED
|
@@ -31,7 +31,7 @@ async function assembleContent (playbook, contentCatalog, converter, { siteCatal
|
|
|
31
31
|
})
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
// TODO: if no workspace dir is defined
|
|
34
|
+
// TODO: if no workspace dir is defined, we shouldn't continue
|
|
35
35
|
function prepareWorkspace (publishFiles, aggregateDocuments, contentCatalog, buildConfig) {
|
|
36
36
|
const { dir, clean, keepAggregateSource } = buildConfig
|
|
37
37
|
const files = contentCatalog.findBy({ family: 'image' }).filter(({ out }) => out?.assembled)
|
package/lib/load-config.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const expandPath = require('@antora/expand-path-helper')
|
|
4
|
-
const
|
|
5
|
-
const os = require('os')
|
|
4
|
+
const fsp = require('node:fs/promises')
|
|
5
|
+
const os = require('node:os')
|
|
6
6
|
const yaml = require('js-yaml')
|
|
7
7
|
|
|
8
8
|
function loadConfig (playbook, configSource = './antora-assembler.yml') {
|
|
@@ -27,7 +27,7 @@ function loadConfig (playbook, configSource = './antora-assembler.yml') {
|
|
|
27
27
|
config.asciidoc.attributes = asciidocAttrs = {}
|
|
28
28
|
}
|
|
29
29
|
if (!('doctype' in asciidocAttrs)) asciidocAttrs.doctype = 'book'
|
|
30
|
-
asciidocAttrs.revdate =
|
|
30
|
+
if (!('revdate' in asciidocAttrs)) asciidocAttrs.revdate = getLocalDate()
|
|
31
31
|
asciidocAttrs['page-partial'] = null
|
|
32
32
|
if (config.componentVersions == null) {
|
|
33
33
|
config.componentVersions = ['*']
|
|
@@ -68,4 +68,8 @@ function camelCaseKeys (o, stopPaths = [], p) {
|
|
|
68
68
|
return accum
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
function getLocalDate (now = new Date()) {
|
|
72
|
+
return new Date(now - now.getTimezoneOffset() * 60000).toISOString().split('T')[0]
|
|
73
|
+
}
|
|
74
|
+
|
|
71
75
|
module.exports = loadConfig
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const File = require('vinyl')
|
|
4
|
-
const
|
|
4
|
+
const path = require('node:path/posix')
|
|
5
5
|
|
|
6
6
|
function produceAggregateDocument (
|
|
7
7
|
loadAsciiDoc,
|
|
@@ -14,7 +14,10 @@ function produceAggregateDocument (
|
|
|
14
14
|
mutableAttributes,
|
|
15
15
|
sectionMergeStrategy = 'discrete'
|
|
16
16
|
) {
|
|
17
|
-
const pagesInOutline = selectPagesInOutline(
|
|
17
|
+
const pagesInOutline = selectPagesInOutline(
|
|
18
|
+
outline,
|
|
19
|
+
pages.filter((it) => it.out)
|
|
20
|
+
)
|
|
18
21
|
const navtitle = outline.content
|
|
19
22
|
const stem = generateStem(componentVersion, navtitle)
|
|
20
23
|
const header = buildAsciiDocHeader(componentVersion, navtitle, doctype)
|
|
@@ -50,8 +53,9 @@ function buildAsciiDocHeader (componentVersion, navtitle, doctype = 'book') {
|
|
|
50
53
|
const version = componentVersion.version === 'master' ? '' : componentVersion.version
|
|
51
54
|
return [
|
|
52
55
|
`= ${doctitle}`,
|
|
53
|
-
...(version ? [
|
|
56
|
+
...(version ? [`:revnumber: ${version}`] : []),
|
|
54
57
|
...(doctype === 'article' ? [] : [`:doctype: ${doctype}`]),
|
|
58
|
+
':underscore: _',
|
|
55
59
|
// Q: should we pass these via the CLI so they cannot be modified?
|
|
56
60
|
`:page-component-name: ${componentVersion.name}`,
|
|
57
61
|
`:page-component-version:${version ? ' ' + version : ''}`,
|
|
@@ -109,9 +113,8 @@ function aggregateAsciiDoc (
|
|
|
109
113
|
const refs = doc.getCatalog().refs
|
|
110
114
|
// NOTE: in Antora, docname is relative src path from module without file extension
|
|
111
115
|
const docname = doc.getAttribute('docname')
|
|
112
|
-
|
|
113
|
-
const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${
|
|
114
|
-
//const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${docname.replace(/[/]/g, ':-:')}:--:`
|
|
116
|
+
const docnameForId = docname.replace(/[/]/g, '::').replace(/[.]/g, '-')
|
|
117
|
+
const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${docnameForId}:::`
|
|
115
118
|
buffer.push('')
|
|
116
119
|
buffer.push(`:docname: ${docname}`)
|
|
117
120
|
buffer.push(`:page-module: ${module_}`)
|
|
@@ -206,9 +209,23 @@ function aggregateAsciiDoc (
|
|
|
206
209
|
for (let i = idx; i < block.lines.length + (delimited ? idx + 2 : idx); i++) ignoreLines.push(i)
|
|
207
210
|
}
|
|
208
211
|
})
|
|
212
|
+
let skipping
|
|
209
213
|
for (let idx = 0, len = lines.length; idx < len; idx++) {
|
|
210
214
|
if (~ignoreLines.indexOf(idx)) continue
|
|
211
215
|
let line = lines[idx]
|
|
216
|
+
if (line.startsWith('//')) {
|
|
217
|
+
if (line[2] !== '/') continue
|
|
218
|
+
if (line.length > 3 && line === '/'.repeat(line.length)) {
|
|
219
|
+
if (skipping) {
|
|
220
|
+
if (line === skipping) skipping = undefined
|
|
221
|
+
} else {
|
|
222
|
+
skipping = line
|
|
223
|
+
}
|
|
224
|
+
continue
|
|
225
|
+
}
|
|
226
|
+
} else if (skipping) {
|
|
227
|
+
continue
|
|
228
|
+
}
|
|
212
229
|
if (line.charAt() === ':' && /^:(?:leveloffset: .*|!leveloffset:|leveloffset!:)$/.test(line)) {
|
|
213
230
|
if (lines[idx - 1] === '') lines[idx - 1] = undefined
|
|
214
231
|
lines[idx] = undefined
|
|
@@ -251,7 +268,7 @@ function aggregateAsciiDoc (
|
|
|
251
268
|
}
|
|
252
269
|
if (~pagePart.indexOf('@') || /:.*:/.test(pagePart)) {
|
|
253
270
|
// TODO: handle unresolved page better
|
|
254
|
-
return siteUrl && (targetPage = contentCatalog.resolvePage(pagePart, page.src))
|
|
271
|
+
return siteUrl && (targetPage = contentCatalog.resolvePage(pagePart, page.src)) && targetPage.out
|
|
255
272
|
? `${siteUrl}${targetPage.pub.url}${fragment && '#' + fragment}[${text}]`
|
|
256
273
|
: m
|
|
257
274
|
} else if (pagePart.indexOf(':') < 0) {
|
|
@@ -261,11 +278,14 @@ function aggregateAsciiDoc (
|
|
|
261
278
|
}
|
|
262
279
|
if (!(targetPage = pagesInOutline.get(pagePart))) {
|
|
263
280
|
// TODO: handle unresolved page better
|
|
264
|
-
return siteUrl && (targetPage = contentCatalog.resolvePage(target, page.src))
|
|
281
|
+
return siteUrl && (targetPage = contentCatalog.resolvePage(target, page.src)) && targetPage.out
|
|
265
282
|
? `${siteUrl}${targetPage.pub.url}${fragment && '#' + fragment}[${text}]`
|
|
266
283
|
: m
|
|
267
284
|
}
|
|
268
|
-
pagePart = pagePart
|
|
285
|
+
pagePart = pagePart
|
|
286
|
+
.replace(/[/]/g, '::')
|
|
287
|
+
.replace(/\.adoc$/, '')
|
|
288
|
+
.replace(/[.]/g, '-')
|
|
269
289
|
const refid = `${pagePart}:::${fragment}`
|
|
270
290
|
return `<<${refid}${text && text !== targetPage.title ? ',' + text.replace(/\\]/g, ']') : ''}>>`
|
|
271
291
|
})
|
|
@@ -281,7 +301,9 @@ function aggregateAsciiDoc (
|
|
|
281
301
|
family: 'attachment',
|
|
282
302
|
relative,
|
|
283
303
|
})
|
|
284
|
-
return attachment
|
|
304
|
+
return attachment && attachment.out
|
|
305
|
+
? `${siteUrl}${attachment.pub.url.replace(/_/g, '{underscore}')}[${text}]`
|
|
306
|
+
: m
|
|
285
307
|
})
|
|
286
308
|
}
|
|
287
309
|
if (~line.indexOf('image:') && !line.startsWith('image::')) {
|
|
@@ -289,9 +311,9 @@ function aggregateAsciiDoc (
|
|
|
289
311
|
if (isResourceSpec(target)) {
|
|
290
312
|
const image = contentCatalog.resolveResource(target, page.src, 'image', ['image'])
|
|
291
313
|
// TODO: handle (or report) unresolved image better
|
|
292
|
-
if (image) {
|
|
314
|
+
if (image && image.out) {
|
|
293
315
|
image.out.assembled = true
|
|
294
|
-
return `image:${image.
|
|
316
|
+
return `image:${image.out.path.replace(/_/g, '{underscore}')}[${attrlist}]`
|
|
295
317
|
}
|
|
296
318
|
}
|
|
297
319
|
return m
|
|
@@ -348,9 +370,10 @@ function aggregateAsciiDoc (
|
|
|
348
370
|
if (isResourceSpec(target)) {
|
|
349
371
|
const image = contentCatalog.resolveResource(target, page.src, 'image', ['image'])
|
|
350
372
|
// FIXME: handle (or report) case when image is not resolved
|
|
351
|
-
if (image) {
|
|
352
|
-
|
|
373
|
+
if (image && image.out) {
|
|
374
|
+
const boxedAttrlist = line.substr(line.indexOf('['))
|
|
353
375
|
image.out.assembled = true
|
|
376
|
+
lines[idx] = `${prefix}image::${image.out.path}${boxedAttrlist}`
|
|
354
377
|
}
|
|
355
378
|
}
|
|
356
379
|
lastImageMacroAt = [idx, imageMacroOffset]
|
|
@@ -500,7 +523,7 @@ function rewriteStyleAttribute (block, lines, idx, idprefix, replacementStyle =
|
|
|
500
523
|
if (replacementStyle) prevLine = prevLine.replace(/^[^#.%,\]]+/, `[${replacementStyle}`)
|
|
501
524
|
} else {
|
|
502
525
|
prevLine = `[${
|
|
503
|
-
replacementStyle ? rawStyle.replace(/^[^.%]
|
|
526
|
+
replacementStyle ? rawStyle.replace(/^[^.%]*/, replacementStyle) : rawStyle
|
|
504
527
|
}#${idprefix}${block.getId()}${prevLine.substr(rawStyle.length + 1)}`
|
|
505
528
|
}
|
|
506
529
|
} else {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const File = require('vinyl')
|
|
3
4
|
const filterComponentVersions = require('./filter-component-versions')
|
|
4
5
|
const produceAggregateDocument = require('./produce-aggregate-document')
|
|
5
6
|
const selectMutableAttributes = require('./select-mutable-attributes')
|
|
@@ -7,8 +8,9 @@ const selectMutableAttributes = require('./select-mutable-attributes')
|
|
|
7
8
|
function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfig) {
|
|
8
9
|
const { insertStartPage, rootLevel, sectionMergeStrategy, asciidoc: assemblerAsciiDocConfig } = assemblerConfig
|
|
9
10
|
const assemblerAsciiDocAttributes = Object.assign({}, assemblerAsciiDocConfig.attributes)
|
|
10
|
-
const { doctype, 'source-highlighter': sourceHighlighter } = assemblerAsciiDocAttributes
|
|
11
|
+
const { doctype, revdate, 'source-highlighter': sourceHighlighter } = assemblerAsciiDocAttributes
|
|
11
12
|
delete assemblerAsciiDocAttributes.doctype
|
|
13
|
+
delete assemblerAsciiDocAttributes.revdate
|
|
12
14
|
delete assemblerAsciiDocAttributes['source-highlighter']
|
|
13
15
|
return filterComponentVersions(contentCatalog.getComponents(), assemblerConfig.componentVersions).reduce(
|
|
14
16
|
(accum, componentVersion) => {
|
|
@@ -16,7 +18,7 @@ function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfi
|
|
|
16
18
|
if (!navigation) return accum
|
|
17
19
|
const componentVersionAsciiDocConfig = getAsciiDocConfigWithAsciidoctorReducerExtension(componentVersion)
|
|
18
20
|
const mergedAsciiDocConfig = Object.assign({}, componentVersionAsciiDocConfig, {
|
|
19
|
-
attributes: Object.assign({}, componentVersionAsciiDocConfig.attributes, assemblerAsciiDocAttributes),
|
|
21
|
+
attributes: Object.assign({ revdate }, componentVersionAsciiDocConfig.attributes, assemblerAsciiDocAttributes),
|
|
20
22
|
})
|
|
21
23
|
const rootEntry = { content: title }
|
|
22
24
|
const startPage = contentCatalog.getComponentVersionStartPage(componentName, version)
|
|
@@ -28,10 +30,16 @@ function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfi
|
|
|
28
30
|
Object.assign(rootEntry, { url: startPageUrl, urlType: 'internal' })
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
// Q: should we use
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
// Q: should we always use a reference page here?
|
|
34
|
+
const startPage_ =
|
|
35
|
+
startPage ??
|
|
36
|
+
createFile({
|
|
37
|
+
component: componentVersion.name,
|
|
38
|
+
version: componentVersion.version,
|
|
39
|
+
relative: '.reference-page.adoc',
|
|
40
|
+
origin: (componentVersion.origins || [])[0],
|
|
41
|
+
})
|
|
42
|
+
const mutableAttributes = selectMutableAttributes(loadAsciiDoc, contentCatalog, startPage_, mergedAsciiDocConfig)
|
|
35
43
|
delete mutableAttributes.doctype
|
|
36
44
|
accum = accum.concat(
|
|
37
45
|
prepareOutlines(navigation, rootEntry, rootLevel).map((outline) =>
|
|
@@ -58,6 +66,30 @@ function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfi
|
|
|
58
66
|
)
|
|
59
67
|
}
|
|
60
68
|
|
|
69
|
+
function createFile (src) {
|
|
70
|
+
const familySegment = (src.family ??= 'page') + 's'
|
|
71
|
+
const path = `modules/${(src.module ??= 'ROOT')}/${familySegment}/${src.relative}`
|
|
72
|
+
const moduleRootPath = Array(src.relative.split('/').length - 1)
|
|
73
|
+
.fill('..')
|
|
74
|
+
.join('/')
|
|
75
|
+
const outPath = [
|
|
76
|
+
src.component === 'ROOT' ? '' : src.component,
|
|
77
|
+
src.version,
|
|
78
|
+
src.module === 'ROOT' ? '' : src.module,
|
|
79
|
+
src.family === 'page' ? '' : '_' + familySegment,
|
|
80
|
+
src.family === 'page' ? src.relative.replace(/\.adoc$/, '.html') : src.relative,
|
|
81
|
+
]
|
|
82
|
+
.filter((it) => it)
|
|
83
|
+
.join('/')
|
|
84
|
+
return new File({
|
|
85
|
+
path,
|
|
86
|
+
contents: src.contents ?? Buffer.alloc(0),
|
|
87
|
+
src,
|
|
88
|
+
out: { path: outPath },
|
|
89
|
+
pub: { url: '/' + outPath, moduleRootPath },
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
61
93
|
function getAsciiDocConfigWithAsciidoctorReducerExtension (componentVersion) {
|
|
62
94
|
const asciidoctorReducerExtension = require('./asciidoctor/reducer-extension') // NOTE: must be required lazily
|
|
63
95
|
const asciidocConfig = componentVersion.asciidoc
|
|
@@ -81,13 +113,16 @@ function includedInNav (items, url) {
|
|
|
81
113
|
return items.find((it) => it.url === url || includedInNav(it.items || [], url))
|
|
82
114
|
}
|
|
83
115
|
|
|
116
|
+
// when root level is 0, merge the navigation into the rootEntry
|
|
117
|
+
// when root level is 1, create navigation per navigation menu
|
|
118
|
+
// in this case, if there's only a single navigation menu with no title, promote each top-level item to a menu
|
|
84
119
|
function prepareOutlines (navigation, rootEntry, rootLevel) {
|
|
85
120
|
if (rootLevel === 0 || navigation.length === 1) {
|
|
86
121
|
const navBranch =
|
|
87
122
|
navigation.length === 1
|
|
88
123
|
? navigation[0]
|
|
89
124
|
: { items: navigation.reduce((navTree, it) => navTree.concat(it.content ? it : it.items), []) }
|
|
90
|
-
return [Object.assign(rootEntry, navBranch)]
|
|
125
|
+
return rootLevel === 0 || navBranch.content ? [Object.assign(rootEntry, navBranch)] : navBranch.items
|
|
91
126
|
}
|
|
92
127
|
return navigation.reduce((navTree, it) => navTree.concat(it.content ? it : it.items), [rootEntry])
|
|
93
128
|
}
|
package/lib/util/run-command.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const fs = require('fs')
|
|
3
|
+
const fs = require('node:fs')
|
|
4
4
|
const LazyReadable = require('./lazy-readable')
|
|
5
|
-
const { spawn } = require('child_process')
|
|
5
|
+
const { spawn } = require('node:child_process')
|
|
6
6
|
|
|
7
7
|
const IS_WIN = process.platform === 'win32'
|
|
8
8
|
const DBL_QUOTE_RX = /"/g
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/assembler",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.7",
|
|
4
4
|
"description": "An extension library for Antora that assembles content from multiple pages into a single AsciiDoc file to converted and publish.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "OpenDevise Inc. (https://opendevise.com)",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@antora/expand-path-helper": "~2.0",
|
|
33
33
|
"braces": "~3.0",
|
|
34
|
-
"picomatch": "~
|
|
34
|
+
"picomatch": "~3.0",
|
|
35
35
|
"vinyl": "~2.2",
|
|
36
36
|
"js-yaml": "~4.1"
|
|
37
37
|
},
|