@antora/assembler 1.0.0-alpha.5 → 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/asciidoctor/reducer-extension.js +13 -8
- package/lib/assemble-content.js +1 -1
- package/lib/load-config.js +20 -9
- package/lib/produce-aggregate-document.js +58 -30
- package/lib/produce-aggregate-documents.js +43 -7
- package/lib/util/lazy-readable.js +1 -1
- package/lib/util/run-command.js +2 -2
- package/package.json +2 -3
|
@@ -121,6 +121,7 @@ const IncludeDirectiveTracker = (() => {
|
|
|
121
121
|
this.$$reducer.includePushed = true
|
|
122
122
|
const directiveLineno = this.lineno - 1 // we're below the include line, which is 1-based
|
|
123
123
|
const prevIncDepth = this.include_stack.length
|
|
124
|
+
let offset = lineno > 1 ? lineno - 1 : 0
|
|
124
125
|
const result = Opal.send(this, Opal.find_super_dispatcher(this, 'push_include', pushInclude), [
|
|
125
126
|
data,
|
|
126
127
|
file,
|
|
@@ -128,12 +129,12 @@ const IncludeDirectiveTracker = (() => {
|
|
|
128
129
|
lineno,
|
|
129
130
|
attrs,
|
|
130
131
|
])
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
)
|
|
132
|
+
let incLines = []
|
|
133
|
+
if (this.include_stack.length > prevIncDepth) {
|
|
134
|
+
incLines = this.$lines()
|
|
135
|
+
if (attrs['$key?']('leveloffset') && incLines[0].startsWith(':leveloffset: ') && incLines[1] === '') offset -= 2
|
|
136
|
+
}
|
|
137
|
+
pushIncludeReplacement.call(this, directiveLineno, incLines, offset)
|
|
137
138
|
return result
|
|
138
139
|
})
|
|
139
140
|
|
|
@@ -174,8 +175,12 @@ function treeProcessor () {
|
|
|
174
175
|
let targetLines, idx
|
|
175
176
|
if (into != null) {
|
|
176
177
|
targetLines = incReplacements[into].lines
|
|
177
|
-
// adds assurance that
|
|
178
|
-
if (targetLines[(idx = lineno - 1)] !== line)
|
|
178
|
+
// adds extra assurance that the program is replacing the correct line
|
|
179
|
+
if (targetLines[(idx = lineno - 1)] !== line) {
|
|
180
|
+
const msg = `include directive to reduce not found; expected: "${line}"; got: "${targetLines[idx]}"`
|
|
181
|
+
doc.getLogger().error(msg)
|
|
182
|
+
return
|
|
183
|
+
}
|
|
179
184
|
}
|
|
180
185
|
if ((drop || []).length) {
|
|
181
186
|
drop
|
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,13 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const camelCaseKeys = require('camelcase-keys')
|
|
4
3
|
const expandPath = require('@antora/expand-path-helper')
|
|
5
|
-
const
|
|
6
|
-
const os = require('os')
|
|
4
|
+
const fsp = require('node:fs/promises')
|
|
5
|
+
const os = require('node:os')
|
|
7
6
|
const yaml = require('js-yaml')
|
|
8
7
|
|
|
9
|
-
const CAMEL_CASE_KEYS_OPTS = { deep: true, stopPaths: ['asciidoc'] }
|
|
10
|
-
|
|
11
8
|
function loadConfig (playbook, configSource = './antora-assembler.yml') {
|
|
12
9
|
return (
|
|
13
10
|
configSource.constructor === Object
|
|
@@ -19,9 +16,7 @@ function loadConfig (playbook, configSource = './antora-assembler.yml') {
|
|
|
19
16
|
() => false
|
|
20
17
|
)
|
|
21
18
|
.then((exists) =>
|
|
22
|
-
exists
|
|
23
|
-
? fsp.readFile(configSource).then((data) => camelCaseKeys(yaml.load(data), CAMEL_CASE_KEYS_OPTS))
|
|
24
|
-
: {}
|
|
19
|
+
exists ? fsp.readFile(configSource).then((data) => camelCaseKeys(yaml.load(data), ['asciidoc'])) : {}
|
|
25
20
|
)
|
|
26
21
|
).then((config) => {
|
|
27
22
|
if (config.enabled === false) return undefined
|
|
@@ -32,7 +27,7 @@ function loadConfig (playbook, configSource = './antora-assembler.yml') {
|
|
|
32
27
|
config.asciidoc.attributes = asciidocAttrs = {}
|
|
33
28
|
}
|
|
34
29
|
if (!('doctype' in asciidocAttrs)) asciidocAttrs.doctype = 'book'
|
|
35
|
-
asciidocAttrs.revdate =
|
|
30
|
+
if (!('revdate' in asciidocAttrs)) asciidocAttrs.revdate = getLocalDate()
|
|
36
31
|
asciidocAttrs['page-partial'] = null
|
|
37
32
|
if (config.componentVersions == null) {
|
|
38
33
|
config.componentVersions = ['*']
|
|
@@ -61,4 +56,20 @@ function loadConfig (playbook, configSource = './antora-assembler.yml') {
|
|
|
61
56
|
})
|
|
62
57
|
}
|
|
63
58
|
|
|
59
|
+
function camelCaseKeys (o, stopPaths = [], p) {
|
|
60
|
+
if (Array.isArray(o)) return o.map((it) => camelCaseKeys(it, stopPaths, p))
|
|
61
|
+
if (o == null || o.constructor !== Object) return o
|
|
62
|
+
const pathPrefix = p ? p + '.' : ''
|
|
63
|
+
const accum = {}
|
|
64
|
+
for (const [k, v] of Object.entries(o)) {
|
|
65
|
+
const camelKey = k.charAt() + k.substr(1).replace(/_([a-z])/g, (_, l) => l.toUpperCase())
|
|
66
|
+
accum[camelKey] = ~stopPaths.indexOf(pathPrefix + camelKey) ? v : camelCaseKeys(v, stopPaths, pathPrefix + camelKey)
|
|
67
|
+
}
|
|
68
|
+
return accum
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getLocalDate (now = new Date()) {
|
|
72
|
+
return new Date(now - now.getTimezoneOffset() * 60000).toISOString().split('T')[0]
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
module.exports = loadConfig
|
|
@@ -1,22 +1,26 @@
|
|
|
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,
|
|
8
8
|
contentCatalog,
|
|
9
9
|
componentVersion,
|
|
10
10
|
outline,
|
|
11
|
+
doctype,
|
|
11
12
|
pages,
|
|
12
13
|
asciidocConfig,
|
|
13
14
|
mutableAttributes,
|
|
14
15
|
sectionMergeStrategy = 'discrete'
|
|
15
16
|
) {
|
|
16
|
-
const pagesInOutline = selectPagesInOutline(
|
|
17
|
+
const pagesInOutline = selectPagesInOutline(
|
|
18
|
+
outline,
|
|
19
|
+
pages.filter((it) => it.out)
|
|
20
|
+
)
|
|
17
21
|
const navtitle = outline.content
|
|
18
22
|
const stem = generateStem(componentVersion, navtitle)
|
|
19
|
-
const header = buildAsciiDocHeader(componentVersion, navtitle)
|
|
23
|
+
const header = buildAsciiDocHeader(componentVersion, navtitle, doctype)
|
|
20
24
|
const body = aggregateAsciiDoc(
|
|
21
25
|
loadAsciiDoc,
|
|
22
26
|
contentCatalog,
|
|
@@ -44,13 +48,14 @@ function produceAggregateDocument (
|
|
|
44
48
|
})
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
function buildAsciiDocHeader (componentVersion, navtitle) {
|
|
51
|
+
function buildAsciiDocHeader (componentVersion, navtitle, doctype = 'book') {
|
|
48
52
|
const doctitle = navtitle === componentVersion.title ? navtitle : `${componentVersion.title}: ${navtitle}`
|
|
49
|
-
const version = componentVersion.version
|
|
53
|
+
const version = componentVersion.version === 'master' ? '' : componentVersion.version
|
|
50
54
|
return [
|
|
51
55
|
`= ${doctitle}`,
|
|
52
|
-
...(version ? [
|
|
53
|
-
|
|
56
|
+
...(version ? [`:revnumber: ${version}`] : []),
|
|
57
|
+
...(doctype === 'article' ? [] : [`:doctype: ${doctype}`]),
|
|
58
|
+
':underscore: _',
|
|
54
59
|
// Q: should we pass these via the CLI so they cannot be modified?
|
|
55
60
|
`:page-component-name: ${componentVersion.name}`,
|
|
56
61
|
`:page-component-version:${version ? ' ' + version : ''}`,
|
|
@@ -108,9 +113,8 @@ function aggregateAsciiDoc (
|
|
|
108
113
|
const refs = doc.getCatalog().refs
|
|
109
114
|
// NOTE: in Antora, docname is relative src path from module without file extension
|
|
110
115
|
const docname = doc.getAttribute('docname')
|
|
111
|
-
|
|
112
|
-
const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${
|
|
113
|
-
//const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${docname.replace(/[/]/g, ':-:')}:--:`
|
|
116
|
+
const docnameForId = docname.replace(/[/]/g, '::').replace(/[.]/g, '-')
|
|
117
|
+
const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${docnameForId}:::`
|
|
114
118
|
buffer.push('')
|
|
115
119
|
buffer.push(`:docname: ${docname}`)
|
|
116
120
|
buffer.push(`:page-module: ${module_}`)
|
|
@@ -205,9 +209,28 @@ function aggregateAsciiDoc (
|
|
|
205
209
|
for (let i = idx; i < block.lines.length + (delimited ? idx + 2 : idx); i++) ignoreLines.push(i)
|
|
206
210
|
}
|
|
207
211
|
})
|
|
212
|
+
let skipping
|
|
208
213
|
for (let idx = 0, len = lines.length; idx < len; idx++) {
|
|
209
214
|
if (~ignoreLines.indexOf(idx)) continue
|
|
210
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
|
+
}
|
|
229
|
+
if (line.charAt() === ':' && /^:(?:leveloffset: .*|!leveloffset:|leveloffset!:)$/.test(line)) {
|
|
230
|
+
if (lines[idx - 1] === '') lines[idx - 1] = undefined
|
|
231
|
+
lines[idx] = undefined
|
|
232
|
+
continue
|
|
233
|
+
}
|
|
211
234
|
if (~line.indexOf('<<')) {
|
|
212
235
|
line = line.replace(/(?<![\\+])<<#?([\p{Alpha}0-9_/.:{][^>,]*?)(?:|, *([^>]+?))?>>/gu, (m, refid, text) => {
|
|
213
236
|
// support natural xref
|
|
@@ -223,7 +246,7 @@ function aggregateAsciiDoc (
|
|
|
223
246
|
}
|
|
224
247
|
if (~line.indexOf('xref:')) {
|
|
225
248
|
// Q: should we allow : as first character of target?
|
|
226
|
-
line = line.replace(/xref:([\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (m, target, text) => {
|
|
249
|
+
line = line.replace(/(?<![\\+])xref:([\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (m, target, text) => {
|
|
227
250
|
let pagePart, fragment, targetPage
|
|
228
251
|
const hashIdx = target.indexOf('#')
|
|
229
252
|
if (~hashIdx) {
|
|
@@ -245,7 +268,7 @@ function aggregateAsciiDoc (
|
|
|
245
268
|
}
|
|
246
269
|
if (~pagePart.indexOf('@') || /:.*:/.test(pagePart)) {
|
|
247
270
|
// TODO: handle unresolved page better
|
|
248
|
-
return siteUrl && (targetPage = contentCatalog.resolvePage(pagePart, page.src))
|
|
271
|
+
return siteUrl && (targetPage = contentCatalog.resolvePage(pagePart, page.src)) && targetPage.out
|
|
249
272
|
? `${siteUrl}${targetPage.pub.url}${fragment && '#' + fragment}[${text}]`
|
|
250
273
|
: m
|
|
251
274
|
} else if (pagePart.indexOf(':') < 0) {
|
|
@@ -255,11 +278,14 @@ function aggregateAsciiDoc (
|
|
|
255
278
|
}
|
|
256
279
|
if (!(targetPage = pagesInOutline.get(pagePart))) {
|
|
257
280
|
// TODO: handle unresolved page better
|
|
258
|
-
return siteUrl && (targetPage = contentCatalog.resolvePage(target, page.src))
|
|
281
|
+
return siteUrl && (targetPage = contentCatalog.resolvePage(target, page.src)) && targetPage.out
|
|
259
282
|
? `${siteUrl}${targetPage.pub.url}${fragment && '#' + fragment}[${text}]`
|
|
260
283
|
: m
|
|
261
284
|
}
|
|
262
|
-
pagePart = pagePart
|
|
285
|
+
pagePart = pagePart
|
|
286
|
+
.replace(/[/]/g, '::')
|
|
287
|
+
.replace(/\.adoc$/, '')
|
|
288
|
+
.replace(/[.]/g, '-')
|
|
263
289
|
const refid = `${pagePart}:::${fragment}`
|
|
264
290
|
return `<<${refid}${text && text !== targetPage.title ? ',' + text.replace(/\\]/g, ']') : ''}>>`
|
|
265
291
|
})
|
|
@@ -275,7 +301,9 @@ function aggregateAsciiDoc (
|
|
|
275
301
|
family: 'attachment',
|
|
276
302
|
relative,
|
|
277
303
|
})
|
|
278
|
-
return attachment
|
|
304
|
+
return attachment && attachment.out
|
|
305
|
+
? `${siteUrl}${attachment.pub.url.replace(/_/g, '{underscore}')}[${text}]`
|
|
306
|
+
: m
|
|
279
307
|
})
|
|
280
308
|
}
|
|
281
309
|
if (~line.indexOf('image:') && !line.startsWith('image::')) {
|
|
@@ -283,9 +311,9 @@ function aggregateAsciiDoc (
|
|
|
283
311
|
if (isResourceSpec(target)) {
|
|
284
312
|
const image = contentCatalog.resolveResource(target, page.src, 'image', ['image'])
|
|
285
313
|
// TODO: handle (or report) unresolved image better
|
|
286
|
-
if (image) {
|
|
314
|
+
if (image && image.out) {
|
|
287
315
|
image.out.assembled = true
|
|
288
|
-
return `image:${image.
|
|
316
|
+
return `image:${image.out.path.replace(/_/g, '{underscore}')}[${attrlist}]`
|
|
289
317
|
}
|
|
290
318
|
}
|
|
291
319
|
return m
|
|
@@ -305,19 +333,17 @@ function aggregateAsciiDoc (
|
|
|
305
333
|
let idx = lineno - 1
|
|
306
334
|
if (context === 'section' && !block.getDocument().isNested()) {
|
|
307
335
|
if (block.getSectionName() === 'header') {
|
|
308
|
-
lines
|
|
336
|
+
lines[idx] = undefined
|
|
309
337
|
return
|
|
310
338
|
}
|
|
311
339
|
let blockStyle = sectionMergeStrategy === 'discrete' ? 'discrete' : undefined
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
lines[idx] = lines[idx].replace(/^=+( .+)/, (_, rest) => {
|
|
315
|
-
let targetMarkerLength = block.level + (1 - leveloffset) + level + (enclosed ? 1 : 0)
|
|
340
|
+
lines[idx] = lines[idx].replace(/^=+ (.+)/, (_, rest) => {
|
|
341
|
+
let targetMarkerLength = block.level + 1 + level + (enclosed ? 1 : 0)
|
|
316
342
|
if (targetMarkerLength > 6) {
|
|
317
343
|
targetMarkerLength = 6
|
|
318
344
|
blockStyle = 'discrete'
|
|
319
345
|
}
|
|
320
|
-
return '='.repeat(targetMarkerLength) + rest
|
|
346
|
+
return '='.repeat(targetMarkerLength) + ' ' + rest
|
|
321
347
|
})
|
|
322
348
|
// NOTE: ID will be undefined if sectids are turned off
|
|
323
349
|
if (block.getId()) rewriteStyleAttribute(block, lines, idx, idprefix, blockStyle)
|
|
@@ -327,7 +353,7 @@ function aggregateAsciiDoc (
|
|
|
327
353
|
let prefix = ''
|
|
328
354
|
// Q: can we use startsWith('image::') in certain cases?
|
|
329
355
|
let imageMacroOffset = (
|
|
330
|
-
lastImageMacroAt
|
|
356
|
+
lastImageMacroAt?.[0] === idx ? line.substr(0, lastImageMacroAt[1]) : line
|
|
331
357
|
).lastIndexOf('image::')
|
|
332
358
|
if (imageMacroOffset > 0) {
|
|
333
359
|
if (
|
|
@@ -344,9 +370,10 @@ function aggregateAsciiDoc (
|
|
|
344
370
|
if (isResourceSpec(target)) {
|
|
345
371
|
const image = contentCatalog.resolveResource(target, page.src, 'image', ['image'])
|
|
346
372
|
// FIXME: handle (or report) case when image is not resolved
|
|
347
|
-
if (image) {
|
|
348
|
-
|
|
373
|
+
if (image && image.out) {
|
|
374
|
+
const boxedAttrlist = line.substr(line.indexOf('['))
|
|
349
375
|
image.out.assembled = true
|
|
376
|
+
lines[idx] = `${prefix}image::${image.out.path}${boxedAttrlist}`
|
|
350
377
|
}
|
|
351
378
|
}
|
|
352
379
|
lastImageMacroAt = [idx, imageMacroOffset]
|
|
@@ -358,7 +385,7 @@ function aggregateAsciiDoc (
|
|
|
358
385
|
if (block.getId()) rewriteStyleAttribute(block, lines, idx, idprefix)
|
|
359
386
|
}
|
|
360
387
|
})
|
|
361
|
-
buffer.push(...lines)
|
|
388
|
+
buffer.push(...lines.filter((it) => it !== undefined))
|
|
362
389
|
const attributeEntries = Object.entries(doc.attributes_defined_in_header || {})
|
|
363
390
|
if (attributeEntries.length) {
|
|
364
391
|
const resolvedAttributeEntries = attributeEntries.reduce(
|
|
@@ -371,7 +398,7 @@ function aggregateAsciiDoc (
|
|
|
371
398
|
} else if (val !== initialVal) {
|
|
372
399
|
accum.push(`:${name}:${initialVal ? ' ' + initialVal : ''}`)
|
|
373
400
|
}
|
|
374
|
-
} else if (val != null && !(doc.isAttributeLocked(name) || name === 'doctype')) {
|
|
401
|
+
} else if (val != null && !(doc.isAttributeLocked(name) || name === 'doctype' || name === 'leveloffset')) {
|
|
375
402
|
accum.push(`:!${name}:`)
|
|
376
403
|
}
|
|
377
404
|
return accum
|
|
@@ -438,7 +465,8 @@ function aggregateAsciiDoc (
|
|
|
438
465
|
|
|
439
466
|
function generateStem (componentVersion, title) {
|
|
440
467
|
const { name, version } = componentVersion
|
|
441
|
-
const segments = [
|
|
468
|
+
const segments = []
|
|
469
|
+
if (name !== 'ROOT') segments.push(name)
|
|
442
470
|
if (version && version !== 'master') segments.push(version)
|
|
443
471
|
segments.push(
|
|
444
472
|
title
|
|
@@ -495,7 +523,7 @@ function rewriteStyleAttribute (block, lines, idx, idprefix, replacementStyle =
|
|
|
495
523
|
if (replacementStyle) prevLine = prevLine.replace(/^[^#.%,\]]+/, `[${replacementStyle}`)
|
|
496
524
|
} else {
|
|
497
525
|
prevLine = `[${
|
|
498
|
-
replacementStyle ? rawStyle.replace(/^[^.%]
|
|
526
|
+
replacementStyle ? rawStyle.replace(/^[^.%]*/, replacementStyle) : rawStyle
|
|
499
527
|
}#${idprefix}${block.getId()}${prevLine.substr(rawStyle.length + 1)}`
|
|
500
528
|
}
|
|
501
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) =>
|
|
@@ -40,6 +48,7 @@ function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfi
|
|
|
40
48
|
contentCatalog,
|
|
41
49
|
componentVersion,
|
|
42
50
|
outline,
|
|
51
|
+
doctype,
|
|
43
52
|
contentCatalog.getPages((page) => page.out),
|
|
44
53
|
mergedAsciiDocConfig,
|
|
45
54
|
mutableAttributes,
|
|
@@ -57,6 +66,30 @@ function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfi
|
|
|
57
66
|
)
|
|
58
67
|
}
|
|
59
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
|
+
|
|
60
93
|
function getAsciiDocConfigWithAsciidoctorReducerExtension (componentVersion) {
|
|
61
94
|
const asciidoctorReducerExtension = require('./asciidoctor/reducer-extension') // NOTE: must be required lazily
|
|
62
95
|
const asciidocConfig = componentVersion.asciidoc
|
|
@@ -80,13 +113,16 @@ function includedInNav (items, url) {
|
|
|
80
113
|
return items.find((it) => it.url === url || includedInNav(it.items || [], url))
|
|
81
114
|
}
|
|
82
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
|
|
83
119
|
function prepareOutlines (navigation, rootEntry, rootLevel) {
|
|
84
120
|
if (rootLevel === 0 || navigation.length === 1) {
|
|
85
121
|
const navBranch =
|
|
86
122
|
navigation.length === 1
|
|
87
123
|
? navigation[0]
|
|
88
124
|
: { items: navigation.reduce((navTree, it) => navTree.concat(it.content ? it : it.items), []) }
|
|
89
|
-
return [Object.assign(rootEntry, navBranch)]
|
|
125
|
+
return rootLevel === 0 || navBranch.content ? [Object.assign(rootEntry, navBranch)] : navBranch.items
|
|
90
126
|
}
|
|
91
127
|
return navigation.reduce((navTree, it) => navTree.concat(it.content ? it : it.items), [rootEntry])
|
|
92
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,8 +31,7 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@antora/expand-path-helper": "~2.0",
|
|
33
33
|
"braces": "~3.0",
|
|
34
|
-
"
|
|
35
|
-
"picomatch": "~2.3",
|
|
34
|
+
"picomatch": "~3.0",
|
|
36
35
|
"vinyl": "~2.2",
|
|
37
36
|
"js-yaml": "~4.1"
|
|
38
37
|
},
|