@antora/assembler 1.0.0-beta.13 → 1.0.0-beta.15
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 +2 -2
- package/lib/load-config.js +22 -11
- package/lib/produce-assembly-file.js +45 -22
- package/lib/produce-assembly-files.js +2 -1
- package/package.json +1 -1
package/lib/assemble-content.js
CHANGED
|
@@ -16,8 +16,6 @@ const PACKAGE_NAME = require('../package.json').name
|
|
|
16
16
|
const NEWLINE_RX = /(?:\r?\n)+/
|
|
17
17
|
|
|
18
18
|
async function assembleContent (playbook, contentCatalog, converter, { configSource, navigationCatalog }) {
|
|
19
|
-
const assemblerConfig = await loadConfig(playbook, configSource)
|
|
20
|
-
if (!assemblerConfig) return [] // TODO consider removing and doing this another way
|
|
21
19
|
const context = isBound(this)
|
|
22
20
|
? this
|
|
23
21
|
: {
|
|
@@ -25,6 +23,8 @@ async function assembleContent (playbook, contentCatalog, converter, { configSou
|
|
|
25
23
|
getLogger: invariably.void,
|
|
26
24
|
getVariables: invariably.new,
|
|
27
25
|
}
|
|
26
|
+
const assemblerConfig = await loadConfig.call(context, playbook, configSource)
|
|
27
|
+
if (assemblerConfig.enabled === false) return []
|
|
28
28
|
const generatorFunctions = context.getFunctions()
|
|
29
29
|
const { loadAsciiDoc = require('@antora/asciidoc-loader') } = generatorFunctions
|
|
30
30
|
const {
|
package/lib/load-config.js
CHANGED
|
@@ -5,6 +5,8 @@ const fsp = require('node:fs/promises')
|
|
|
5
5
|
const os = require('node:os')
|
|
6
6
|
const yaml = require('js-yaml')
|
|
7
7
|
|
|
8
|
+
const PACKAGE_NAME = require('../package.json').name
|
|
9
|
+
|
|
8
10
|
const ASSEMBLY_KEYS = [
|
|
9
11
|
'rootLevel',
|
|
10
12
|
'insertStartPage',
|
|
@@ -13,25 +15,34 @@ const ASSEMBLY_KEYS = [
|
|
|
13
15
|
'dropExplicitXrefText',
|
|
14
16
|
]
|
|
15
17
|
|
|
16
|
-
function loadConfig (playbook, configSource
|
|
18
|
+
function loadConfig (playbook, configSource) {
|
|
19
|
+
let resolvedConfigSource
|
|
17
20
|
return (
|
|
18
|
-
configSource
|
|
21
|
+
configSource?.constructor === Object
|
|
19
22
|
? Promise.resolve(configSource)
|
|
20
23
|
: fsp
|
|
21
|
-
.access((
|
|
24
|
+
.access((resolvedConfigSource = expandPath(configSource ?? './antora-assembler.yml', { dot: playbook.dir })))
|
|
22
25
|
.then(
|
|
23
26
|
() => true,
|
|
24
27
|
() => false
|
|
25
28
|
)
|
|
26
|
-
.then((exists) =>
|
|
27
|
-
exists
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
.then((exists) => {
|
|
30
|
+
if (!exists) {
|
|
31
|
+
let logger
|
|
32
|
+
if (configSource && (logger = this?.getLogger?.(PACKAGE_NAME))) {
|
|
33
|
+
const ctx = { file: { path: configSource } }
|
|
34
|
+
logger.warn(ctx, 'Could not resolve config file; reverting to default settings')
|
|
35
|
+
}
|
|
36
|
+
return {}
|
|
37
|
+
}
|
|
38
|
+
return fsp
|
|
39
|
+
.readFile(resolvedConfigSource)
|
|
40
|
+
.then((data) =>
|
|
41
|
+
Object.assign(camelCaseKeys(yaml.load(data), ['asciidoc']), { file: resolvedConfigSource })
|
|
42
|
+
)
|
|
43
|
+
})
|
|
33
44
|
).then((config) => {
|
|
34
|
-
if (config.enabled === false) return
|
|
45
|
+
if (config.enabled === false) return config
|
|
35
46
|
let asciidocAttrs
|
|
36
47
|
if (!config.asciidoc) {
|
|
37
48
|
config.asciidoc = { attributes: (asciidocAttrs = {}) }
|
|
@@ -121,6 +121,7 @@ function mergeAsciiDoc (
|
|
|
121
121
|
outDirname,
|
|
122
122
|
siteRoot,
|
|
123
123
|
xmlIds,
|
|
124
|
+
logger,
|
|
124
125
|
} = assemblyModel
|
|
125
126
|
// FIXME: ideally, resource ID would be stored in navigation so we can look up the page more efficiently
|
|
126
127
|
const page = urlType === 'internal' && !unresolved ? pagesInOutline.get(url) : undefined
|
|
@@ -142,6 +143,16 @@ function mergeAsciiDoc (
|
|
|
142
143
|
Object.assign({}, page, { contents: trimAsciiDoc(contents), mediaType })
|
|
143
144
|
)
|
|
144
145
|
const doc = loadAsciiDoc(pageAsAsciiDoc, contentCatalog, asciidocConfig)
|
|
146
|
+
let asciidoctorLogger = doc.getLogger()
|
|
147
|
+
if (logger) {
|
|
148
|
+
asciidoctorLogger = Object.assign(asciidoctorLogger.$dup(), {
|
|
149
|
+
delegate: {
|
|
150
|
+
warn () {
|
|
151
|
+
return logger.warn.apply(logger, arguments)
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
})
|
|
155
|
+
}
|
|
145
156
|
if (doc.hasAttribute('assembly-navtitle')) {
|
|
146
157
|
navtitleAsciiDoc = doc.getAttribute('assembly-navtitle')
|
|
147
158
|
navtitlePlain = sanitize((navtitle = doc.$apply_reftext_subs(navtitleAsciiDoc)))
|
|
@@ -374,7 +385,7 @@ function mergeAsciiDoc (
|
|
|
374
385
|
}
|
|
375
386
|
if (~line.indexOf('xref:')) {
|
|
376
387
|
// Q: should we allow : as first character of target?
|
|
377
|
-
line = line.replace(/(?<![\\+])xref:((?:\.\/)?[\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (
|
|
388
|
+
line = line.replace(/(?<![\\+])xref:((?:\.\/)?[\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (_, target, text) => {
|
|
378
389
|
let fragment, resource, resourceRef
|
|
379
390
|
const hashIdx = target.indexOf('#')
|
|
380
391
|
if (~hashIdx) {
|
|
@@ -389,21 +400,23 @@ function mergeAsciiDoc (
|
|
|
389
400
|
// Q: should we validate the internal ID here?
|
|
390
401
|
if (!resourceRef) return `xref:${idPrefix}${fragment}[${text}]`
|
|
391
402
|
const resourceId = parseResourceRef(resourceRef, page.src, 'page', contentCatalog)
|
|
392
|
-
if (resourceId.family !== 'page') {
|
|
393
|
-
if (
|
|
394
|
-
text ||= resource.asciidoc?.xreftext || target
|
|
395
|
-
return `${resolveLinkTarget(resource, siteRoot, pubRoot, linkRefStyle)}${fragment && '#' + fragment}[${text}]`
|
|
396
|
-
}
|
|
397
|
-
// TODO: handle unresolved resource better
|
|
398
|
-
return m
|
|
399
|
-
}
|
|
400
|
-
if (!(resource = pagesInOutline.get(createResourceKey(resourceId)))) {
|
|
401
|
-
if (siteRoot && (resource = contentCatalog.getById(resourceId))?.pub) {
|
|
403
|
+
if (resourceId.family !== 'page' || !(resource = pagesInOutline.get(createResourceKey(resourceId)))) {
|
|
404
|
+
if ((resource = contentCatalog.getById(resourceId))?.pub) {
|
|
402
405
|
text ||= resource.asciidoc?.xreftext || target
|
|
403
|
-
|
|
406
|
+
if (siteRoot || linkRefStyle === 'relative') {
|
|
407
|
+
return `${resolveLinkTarget(resource, siteRoot, pubRoot, linkRefStyle)}${fragment && '#' + fragment}[${text}]`
|
|
408
|
+
}
|
|
409
|
+
asciidoctorLogger.warn(
|
|
410
|
+
doc.createLogMessage(
|
|
411
|
+
`Cannot create external ${resourceId.family} reference in assembly because site URL is unknown: ${target}`,
|
|
412
|
+
{ source_location: { file: relative, lineno: idx + 1 } }
|
|
413
|
+
)
|
|
414
|
+
)
|
|
404
415
|
}
|
|
405
|
-
|
|
406
|
-
|
|
416
|
+
const linkAttrlist = text
|
|
417
|
+
? (~text.indexOf(',') ? `"${text}"` : text) + ',role=unresolved'
|
|
418
|
+
: 'role=unresolved'
|
|
419
|
+
return `link:${target}[${linkAttrlist}]`
|
|
407
420
|
}
|
|
408
421
|
if (fragment === resource.asciidoc.id) fragment = ''
|
|
409
422
|
if (
|
|
@@ -427,7 +440,7 @@ function mergeAsciiDoc (
|
|
|
427
440
|
if (~line.indexOf('link:{attachmentsdir}/')) {
|
|
428
441
|
line = line.replace(/(?<![\\+])link:\{attachmentsdir\}\/([^\s[]+)\[(|.*?[^\\])\]/g, (m, relative, text) => {
|
|
429
442
|
const attachment =
|
|
430
|
-
siteRoot &&
|
|
443
|
+
(siteRoot || linkRefStyle === 'relative') &&
|
|
431
444
|
contentCatalog.getById({
|
|
432
445
|
component: componentVersion.name,
|
|
433
446
|
version: componentVersion.version,
|
|
@@ -441,15 +454,25 @@ function mergeAsciiDoc (
|
|
|
441
454
|
}
|
|
442
455
|
if (~line.indexOf('image:') && !line.startsWith('image::')) {
|
|
443
456
|
line = line.replace(/(?<![\\+])image:([^:\s[](?:[^[]*[^\s[])?)\[([^\]]*)\]/g, (m, target, attrlist) => {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
457
|
+
let image
|
|
458
|
+
if (
|
|
459
|
+
isResourceSpec(target) &&
|
|
460
|
+
(image = contentCatalog.resolveResource(target, page.src, 'image', ['image']))?.out
|
|
461
|
+
) {
|
|
462
|
+
if (filetype !== 'html') {
|
|
463
|
+
pagesInOutline.assembled.assets.add(image)
|
|
464
|
+
return `image:${resolveEmbedTarget(image, outDirname, embedRefStyle, true)}[${attrlist}]`
|
|
465
|
+
}
|
|
466
|
+
if (siteRoot || linkRefStyle === 'relative') {
|
|
448
467
|
pagesInOutline.assembled.assets.add(image)
|
|
449
|
-
return
|
|
450
|
-
? `image:${resolveLinkTarget(image, siteRoot, pubRoot, linkRefStyle)}[${attrlist}]`
|
|
451
|
-
: `image:${resolveEmbedTarget(image, outDirname, embedRefStyle, true)}[${attrlist}]`
|
|
468
|
+
return `image:${resolveLinkTarget(image, siteRoot, pubRoot, linkRefStyle)}[${attrlist}]`
|
|
452
469
|
}
|
|
470
|
+
asciidoctorLogger.warn(
|
|
471
|
+
doc.createLogMessage(
|
|
472
|
+
`Cannot create external image reference in assembly because site URL is unknown: ${target}`,
|
|
473
|
+
{ source_location: { file: relative, lineno: idx + 1 } }
|
|
474
|
+
)
|
|
475
|
+
)
|
|
453
476
|
}
|
|
454
477
|
return m
|
|
455
478
|
})
|
|
@@ -21,6 +21,7 @@ function produceAssemblyFiles (loadAsciiDoc, contentCatalog, assemblerConfig, re
|
|
|
21
21
|
embedReferenceStyle: assemblyConfig.embedReferenceStyle,
|
|
22
22
|
linkReferenceStyle: assemblyConfig.linkReferenceStyle,
|
|
23
23
|
dropExplicitXrefText: assemblyConfig.dropExplicitXrefText,
|
|
24
|
+
logger: assemblyConfig.logger, // for tests
|
|
24
25
|
})
|
|
25
26
|
const assemblerAsciiDocAttributes = Object.assign({}, assemblerAsciiDocConfig.attributes)
|
|
26
27
|
const { revdate, 'source-highlighter': sourceHighlighter } = assemblerAsciiDocAttributes
|
|
@@ -64,7 +65,7 @@ function produceAssemblyFiles (loadAsciiDoc, contentCatalog, assemblerConfig, re
|
|
|
64
65
|
if (linkRefStyle === 'absolute' && siteRoot?.url == null) linkRefStyle = 'root-relative'
|
|
65
66
|
if (linkRefStyle === 'root-relative' && siteRoot?.path == null) linkRefStyle = 'relative'
|
|
66
67
|
assemblyModel.linkReferenceStyle = linkRefStyle
|
|
67
|
-
} else {
|
|
68
|
+
} else if (!(assemblyModel.filetype === 'pdf' && assemblyModel.linkReferenceStyle === 'relative')) {
|
|
68
69
|
assemblyModel.linkReferenceStyle = 'absolute'
|
|
69
70
|
}
|
|
70
71
|
const auxiliaryImages = new Set()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/assembler",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"description": "A JavaScript library that merges AsciiDoc content from multiple pages in an Antora site into assembly files and delegates to an exporter to convert those files to another format, such as PDF.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "OpenDevise Inc. (https://opendevise.com)",
|