@antora/assembler 1.0.0-beta.17 → 1.0.0-beta.18
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/configure.js
CHANGED
|
@@ -16,8 +16,17 @@ function internalConfigure (converter, config = {}, providers = {}) {
|
|
|
16
16
|
|
|
17
17
|
this.once('navigationBuilt', async ({ playbook, contentCatalog }) => {
|
|
18
18
|
const { assembleContent = require('./assemble-content'), ...assembleContentConfig } = providers
|
|
19
|
-
assembleContentConfig.configSource
|
|
20
|
-
|
|
19
|
+
if (assembleContentConfig.configSource?.constructor === Object) {
|
|
20
|
+
await assembleContent.call(this, playbook, contentCatalog, converter, assembleContentConfig)
|
|
21
|
+
} else {
|
|
22
|
+
const singleConfig = !('configFiles' in config)
|
|
23
|
+
const configFiles = singleConfig ? config.configFile : config.configFiles
|
|
24
|
+
for (const configSource of Array.isArray(configFiles) ? configFiles : [configFiles]) {
|
|
25
|
+
const assembleContentConfigWithConfigSource = Object.assign({}, assembleContentConfig, { configSource })
|
|
26
|
+
await assembleContent.call(this, playbook, contentCatalog, converter, assembleContentConfigWithConfigSource)
|
|
27
|
+
if (singleConfig) break
|
|
28
|
+
}
|
|
29
|
+
}
|
|
21
30
|
})
|
|
22
31
|
}
|
|
23
32
|
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const createAsciiDocFile = require('./util/create-asciidoc-file')
|
|
4
4
|
const createResourceKey = require('./util/create-resource-key')
|
|
5
|
-
const
|
|
5
|
+
const generateScopedId = require('./util/generate-scoped-id')
|
|
6
6
|
const { resolveLinkTarget } = require('./util/resolver')
|
|
7
7
|
const { rewriteXrefs, rewriteImageRef, rewriteInlineImages, rewriteStyleAttribute } = require('./util/rewriter')
|
|
8
|
+
const { NamedIdAttrRx } = require('./util/rx')
|
|
8
9
|
const sanitize = require('./util/sanitize')
|
|
9
10
|
const unconvertInlineAsciiDoc = require('./util/unconvert-inline-asciidoc')
|
|
10
11
|
|
|
@@ -25,7 +26,14 @@ function produceAssemblyFile (
|
|
|
25
26
|
) {
|
|
26
27
|
const pagesByUrl = files.reduce((map, it) => (it.src.family === 'page' ? map.set(it.pub.url, it) : map), new Map())
|
|
27
28
|
if (outline.urlType === 'internal' && !pagesByUrl.get(outline.url) && !(outline.items || []).length) return
|
|
28
|
-
const pagesInOutline = selectPagesInOutline(outline, pagesByUrl
|
|
29
|
+
const pagesInOutline = selectPagesInOutline(outline, pagesByUrl)
|
|
30
|
+
pagesInOutline.generateIdFromTitle = generateIdFromTitle.bind(
|
|
31
|
+
loadAsciiDoc(
|
|
32
|
+
{ contents: Buffer.alloc(0), src: { family: 'page', relative: 'generate-id.adoc' } },
|
|
33
|
+
undefined,
|
|
34
|
+
asciidocConfig
|
|
35
|
+
)
|
|
36
|
+
)
|
|
29
37
|
const buffer = mergeAsciiDoc(
|
|
30
38
|
loadAsciiDoc,
|
|
31
39
|
contentCatalog,
|
|
@@ -64,29 +72,30 @@ function buildAsciiDocHeader (componentVersion, navtitle, assemblyModel) {
|
|
|
64
72
|
let doctitle = navtitleAsciiDoc
|
|
65
73
|
if (navtitlePlain !== componentVersion.title) doctitle = `${componentVersion.title}: ${doctitle}`
|
|
66
74
|
const version = componentVersion.version === 'master' ? '' : componentVersion.version
|
|
75
|
+
const displayVersion = componentVersion.displayVersion
|
|
67
76
|
const buffer = [
|
|
68
77
|
`= ${doctitle}`,
|
|
69
|
-
...(version ? [`:revnumber: ${
|
|
78
|
+
...(version ? [`:revnumber: ${displayVersion}`] : []),
|
|
70
79
|
...(doctype === 'article' ? [] : [`:doctype: ${doctype ?? 'book'}`]),
|
|
71
80
|
':underscore: _',
|
|
72
81
|
// Q: should we pass these via the CLI so they cannot be modified?
|
|
73
82
|
`:page-component-name: ${componentVersion.name}`,
|
|
74
83
|
`:page-component-version:${version ? ' ' + version : ''}`,
|
|
75
84
|
':page-version: {page-component-version}',
|
|
76
|
-
`:page-component-display-version: ${
|
|
85
|
+
`:page-component-display-version: ${displayVersion}`,
|
|
77
86
|
`:page-component-title: ${componentVersion.title}`,
|
|
78
87
|
]
|
|
79
88
|
return Object.assign(buffer, { navtitle })
|
|
80
89
|
}
|
|
81
90
|
|
|
82
|
-
function selectPagesInOutline (outlineEntry, pagesByUrl,
|
|
91
|
+
function selectPagesInOutline (outlineEntry, pagesByUrl, accum) {
|
|
83
92
|
accum ??= Object.assign(new Map(), { assembled: { pages: new Map(), assets: new Set() } })
|
|
84
93
|
const page = outlineEntry.urlType === 'internal' ? pagesByUrl.get(outlineEntry.url) : undefined
|
|
85
94
|
if (page) {
|
|
86
95
|
accum.set(createResourceKey(page.src), page)
|
|
87
96
|
accum.set(outlineEntry.url, page)
|
|
88
97
|
}
|
|
89
|
-
for (const item of outlineEntry.items || []) selectPagesInOutline(item, pagesByUrl,
|
|
98
|
+
for (const item of outlineEntry.items || []) selectPagesInOutline(item, pagesByUrl, accum)
|
|
90
99
|
return accum
|
|
91
100
|
}
|
|
92
101
|
|
|
@@ -114,7 +123,7 @@ function mergeAsciiDoc (
|
|
|
114
123
|
let navtitlePlain = sanitize(navtitle)
|
|
115
124
|
let navtitleAsciiDoc = unconvertInlineAsciiDoc(navtitle)
|
|
116
125
|
const { items = [], unresolved, urlType, url } = outlineEntry
|
|
117
|
-
const { doctype, linkReferenceStyle, pubRoot, siteRoot, xmlIds, logger } = assemblyModel
|
|
126
|
+
const { doctype, filetype, linkReferenceStyle, pubRoot, siteRoot, xmlIds, logger } = assemblyModel
|
|
118
127
|
const assembled = pagesInOutline.assembled
|
|
119
128
|
// FIXME: ideally, resource ID would be stored in navigation so we can look up the page more efficiently
|
|
120
129
|
const page = urlType === 'internal' && !unresolved ? pagesInOutline.get(url) : undefined
|
|
@@ -173,12 +182,13 @@ function mergeAsciiDoc (
|
|
|
173
182
|
}
|
|
174
183
|
// NOTE: in Antora, docname is relative src path from module without file extension
|
|
175
184
|
const docname = doc.getAttribute('docname')
|
|
176
|
-
const { idLeader, id: idScope } =
|
|
185
|
+
const { idLeader: idScopeLeader, id: idScope } = generateScopedId(
|
|
177
186
|
page.src,
|
|
178
187
|
componentVersion,
|
|
179
188
|
idCoordinateSeparator,
|
|
180
189
|
idScopeSeparator,
|
|
181
|
-
idPrefix
|
|
190
|
+
idPrefix,
|
|
191
|
+
filetype
|
|
182
192
|
)
|
|
183
193
|
let pageFragment = ''
|
|
184
194
|
let pageRoles = ''
|
|
@@ -235,7 +245,7 @@ function mergeAsciiDoc (
|
|
|
235
245
|
assemblyModel = Object.assign({}, assemblyModel, { sectionMergeStrategy: 'discrete' })
|
|
236
246
|
} else {
|
|
237
247
|
if (atDocumentRoot) {
|
|
238
|
-
pageFragment = `#${
|
|
248
|
+
pageFragment = `#${idScopeLeader}${doc.getId() ?? pageStyle}`
|
|
239
249
|
buffer.unshift(`[#${idScope}]`)
|
|
240
250
|
} else {
|
|
241
251
|
pageFragment = `#${idScope}`
|
|
@@ -268,26 +278,16 @@ function mergeAsciiDoc (
|
|
|
268
278
|
//if (overviewTitle === navtitle) overviewTitle = doc.getAttribute('overview-title', 'Overview')
|
|
269
279
|
const overviewTitle = doc.getAttribute('overview-title', 'Overview')
|
|
270
280
|
buffer.push('')
|
|
271
|
-
|
|
272
|
-
let toggleSectids, syntheticId
|
|
273
|
-
if (doc.isAttribute('sectids')) {
|
|
274
|
-
if (doc.isAttributeLocked('sectids')) {
|
|
275
|
-
syntheticId = `__object-id-${getObjectId(outlineEntry)}`
|
|
276
|
-
} else {
|
|
277
|
-
buffer.push(':!sectids:')
|
|
278
|
-
toggleSectids = true
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
+
const syntheticId = pagesInOutline.generateIdFromTitle(navtitleAsciiDoc, idCoordinateSeparator)
|
|
281
282
|
let hlevel = level + 2
|
|
282
283
|
if (hlevel > 6) {
|
|
283
284
|
const blockStyle = `discrete.h${hlevel}`
|
|
284
285
|
hlevel = 6
|
|
285
|
-
buffer.push(
|
|
286
|
-
} else
|
|
286
|
+
buffer.push(`[${blockStyle}#${syntheticId}]`)
|
|
287
|
+
} else {
|
|
287
288
|
buffer.push(`[#${syntheticId}]`)
|
|
288
289
|
}
|
|
289
290
|
buffer.push(`${'='.repeat(hlevel)} ${overviewTitle}`)
|
|
290
|
-
if (toggleSectids) buffer.push(':sectids:')
|
|
291
291
|
}
|
|
292
292
|
assembled.pages.set(page, pageFragment)
|
|
293
293
|
if (doc.hasSections()) {
|
|
@@ -375,13 +375,13 @@ function mergeAsciiDoc (
|
|
|
375
375
|
if (!refs['$key?'](refid) && (~refid.indexOf(' ') || refid.toLowerCase() !== refid)) {
|
|
376
376
|
if ((refid = doc.$resolve_id(refid))['$nil?']()) return m
|
|
377
377
|
}
|
|
378
|
-
return `<<${
|
|
378
|
+
return `<<${idScopeLeader}${refid}${text ? ',' + text : ''}>>`
|
|
379
379
|
})
|
|
380
380
|
}
|
|
381
381
|
// NOTE: the next check takes care of inline and block anchors
|
|
382
382
|
if (~line.indexOf('[[')) {
|
|
383
383
|
line = line.replace(/\[\[([\p{Alpha}_:][\p{Alpha}0-9_\-:.]*)(|, *.+?)\]\]/gu, (_, refid, text) => {
|
|
384
|
-
return `[[${
|
|
384
|
+
return `[[${idScopeLeader}${refid}${text}]]`
|
|
385
385
|
})
|
|
386
386
|
}
|
|
387
387
|
if (~line.indexOf('xref:')) {
|
|
@@ -394,7 +394,7 @@ function mergeAsciiDoc (
|
|
|
394
394
|
idCoordinateSeparator,
|
|
395
395
|
idScopeSeparator,
|
|
396
396
|
idPrefix,
|
|
397
|
-
|
|
397
|
+
idScopeLeader,
|
|
398
398
|
pagesInOutline,
|
|
399
399
|
doc,
|
|
400
400
|
{ file: relative, lineno: idx + 1 }
|
|
@@ -427,7 +427,7 @@ function mergeAsciiDoc (
|
|
|
427
427
|
return '='.repeat(targetMarkerLength) + ' ' + rest
|
|
428
428
|
})
|
|
429
429
|
// NOTE: ID will be undefined if sectids are turned off
|
|
430
|
-
if (block.getId()) rewriteStyleAttribute(block, lines, idx,
|
|
430
|
+
if (block.getId()) rewriteStyleAttribute(block, lines, idx, idScopeLeader, blockStyle)
|
|
431
431
|
} else {
|
|
432
432
|
if (context === 'image') {
|
|
433
433
|
let line = lines[idx] || ''
|
|
@@ -456,7 +456,7 @@ function mergeAsciiDoc (
|
|
|
456
456
|
// nested document
|
|
457
457
|
idx = (block.getHeader().getLineNumber() || idx + 1) - 1
|
|
458
458
|
}
|
|
459
|
-
if (block.getId()) rewriteStyleAttribute(block, lines, idx,
|
|
459
|
+
if (block.getId()) rewriteStyleAttribute(block, lines, idx, idScopeLeader)
|
|
460
460
|
}
|
|
461
461
|
})
|
|
462
462
|
safePush(
|
|
@@ -491,20 +491,7 @@ function mergeAsciiDoc (
|
|
|
491
491
|
} else {
|
|
492
492
|
buffer.inBody = true
|
|
493
493
|
buffer.push('')
|
|
494
|
-
|
|
495
|
-
// Q: should we unset docname, page-module, etc?
|
|
496
|
-
let toggleSectids, syntheticId
|
|
497
|
-
if (!('sectids' in asciidocConfig.attributes)) {
|
|
498
|
-
buffer.push(':!sectids:')
|
|
499
|
-
toggleSectids = true
|
|
500
|
-
} else if (typeof asciidocConfig.attributes.sectids === 'string') {
|
|
501
|
-
if ('sectids' in mutableAttributes) {
|
|
502
|
-
buffer.push(':!sectids:')
|
|
503
|
-
toggleSectids = true
|
|
504
|
-
} else {
|
|
505
|
-
syntheticId = `__object-id-${global.Opal.hash(outlineEntry).$object_id()}`
|
|
506
|
-
}
|
|
507
|
-
}
|
|
494
|
+
const syntheticId = pagesInOutline.generateIdFromTitle(navtitleAsciiDoc, idCoordinateSeparator)
|
|
508
495
|
let sectionTitle = navtitleAsciiDoc
|
|
509
496
|
if (urlType === 'external') {
|
|
510
497
|
sectionTitle = `${url}[${navtitleAsciiDoc.replace(/\]/g, '\\]')}]`
|
|
@@ -512,14 +499,15 @@ function mergeAsciiDoc (
|
|
|
512
499
|
const resource = files.find((it) => it.pub.url === url)
|
|
513
500
|
if (resource) {
|
|
514
501
|
if (resource.src.family === 'page' && pagesInOutline.has(resource.pub.url)) {
|
|
515
|
-
const refid =
|
|
502
|
+
const { id: refid } = generateScopedId(
|
|
516
503
|
resource.src,
|
|
517
504
|
componentVersion,
|
|
518
505
|
idCoordinateSeparator,
|
|
519
506
|
idScopeSeparator,
|
|
520
507
|
idPrefix,
|
|
508
|
+
filetype,
|
|
521
509
|
true
|
|
522
|
-
)
|
|
510
|
+
)
|
|
523
511
|
sectionTitle = `xref:${refid}[${navtitleAsciiDoc.replace(/\]/g, '\\]')}]`
|
|
524
512
|
} else if (siteRoot) {
|
|
525
513
|
sectionTitle = `${resolveLinkTarget(resource, siteRoot, pubRoot, linkReferenceStyle, true)}[${navtitleAsciiDoc.replace(/\]/g, '\\]')}]`
|
|
@@ -529,12 +517,11 @@ function mergeAsciiDoc (
|
|
|
529
517
|
let hlevel = level + 1
|
|
530
518
|
if (hlevel > 6) {
|
|
531
519
|
hlevel = 6
|
|
532
|
-
buffer.push(
|
|
533
|
-
} else
|
|
520
|
+
buffer.push(`[discrete#${syntheticId}]`)
|
|
521
|
+
} else {
|
|
534
522
|
buffer.push(`[#${syntheticId}]`)
|
|
535
523
|
}
|
|
536
524
|
buffer.push(`${'='.repeat(hlevel)} ${sectionTitle}`)
|
|
537
|
-
if (toggleSectids) buffer.push(':sectids:')
|
|
538
525
|
}
|
|
539
526
|
}
|
|
540
527
|
|
|
@@ -610,6 +597,7 @@ function processDocumentHeader (doc, lines, buffer, ignoreLines) {
|
|
|
610
597
|
.slice(1, -1)
|
|
611
598
|
.trim()
|
|
612
599
|
.replace(/(?:^\w[\w-]*(?!=|[\w-]))?([#.%]\w[\w-]*)*/, '')
|
|
600
|
+
.replace(NamedIdAttrRx, '')
|
|
613
601
|
if (attrlist) buffer.push('[' + attrlist + ']')
|
|
614
602
|
}
|
|
615
603
|
} else if (belowDoctitle) {
|
|
@@ -645,10 +633,6 @@ function fixSectionLevels (sections, expectedLevel) {
|
|
|
645
633
|
})
|
|
646
634
|
}
|
|
647
635
|
|
|
648
|
-
function getObjectId (obj) {
|
|
649
|
-
return global.Opal.id(obj)
|
|
650
|
-
}
|
|
651
|
-
|
|
652
636
|
// NOTE: blank lines at top and bottom of document create mismatch when using line numbers to navigate source lines
|
|
653
637
|
// IMPORTANT: this must not leave behind lines the parser will drop!
|
|
654
638
|
// IDEA: another option is to capture initial lineno of reader and use as offset (but preseves those blank lines)
|
|
@@ -671,4 +655,11 @@ function safePush (onto, entries) {
|
|
|
671
655
|
}
|
|
672
656
|
}
|
|
673
657
|
|
|
658
|
+
function generateIdFromTitle (titleAsciiDoc, sep) {
|
|
659
|
+
const Section = this.$class().$const_get('::Asciidoctor::Section')
|
|
660
|
+
const baseId = Section.$generate_id(titleAsciiDoc, this)
|
|
661
|
+
this.getCatalog().refs['$[]='](baseId, true)
|
|
662
|
+
return `_${sep}${baseId}`
|
|
663
|
+
}
|
|
664
|
+
|
|
674
665
|
module.exports = produceAssemblyFile
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const ReservedIdNames = 'content header footnotes footer footer-text premable toc toctitle'.split(' ')
|
|
4
4
|
|
|
5
|
-
function
|
|
5
|
+
function generateScopedId (componentSrc, componentVersion, coordinateSep, scopeSep, prefix, filetype, asXrefTarget) {
|
|
6
6
|
let { component, module: mod, relative } = componentSrc
|
|
7
7
|
let id = relative.replace(/\.adoc$/, '').replace(/[/.]/g, '-')
|
|
8
8
|
if (component !== componentVersion.name) {
|
|
@@ -13,13 +13,13 @@ function generateId (componentSrc, componentVersion, coordinateSep, scopeSep, pr
|
|
|
13
13
|
mod = mod.replace(/(?:pass|stem)$/, '\\$&')
|
|
14
14
|
}
|
|
15
15
|
id = mod + coordinateSep + id
|
|
16
|
-
} else if (ReservedIdNames.includes(id)) {
|
|
17
|
-
id
|
|
18
|
-
|
|
16
|
+
} else if (filetype === 'html' && ReservedIdNames.includes(id)) {
|
|
17
|
+
id = prefix + id
|
|
18
|
+
prefix = ''
|
|
19
19
|
}
|
|
20
20
|
if (prefix && !/^[\p{Alpha}_:]/u.test(id)) id = prefix + id
|
|
21
21
|
const idLeader = id + scopeSep
|
|
22
|
-
return { idLeader, id
|
|
22
|
+
return { idLeader, id }
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
module.exports =
|
|
25
|
+
module.exports = generateScopedId
|
package/lib/util/rewriter.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const createResourceKey = require('./create-resource-key')
|
|
4
|
-
const
|
|
5
|
-
const { resolveEmbedTarget, resolveLinkTarget } = require('./resolver')
|
|
4
|
+
const generateScopedId = require('./generate-scoped-id')
|
|
6
5
|
const parseResourceRef = require('./parse-resource-ref')
|
|
6
|
+
const { resolveEmbedTarget, resolveLinkTarget } = require('./resolver')
|
|
7
|
+
const { NamedIdAttrRx } = require('./rx')
|
|
7
8
|
|
|
8
9
|
function rewriteXrefs (
|
|
9
10
|
line,
|
|
@@ -96,16 +97,16 @@ function rewriteXref (
|
|
|
96
97
|
text = ''
|
|
97
98
|
}
|
|
98
99
|
const componentVersionCtx = { name: ctx.component, version: ctx.version }
|
|
99
|
-
const refid =
|
|
100
|
+
const { idLeader: refidLeader, id: refid } = generateScopedId(
|
|
100
101
|
resource.src,
|
|
101
102
|
componentVersionCtx,
|
|
102
103
|
idCoordinateSep,
|
|
103
104
|
idScopeSep,
|
|
104
105
|
idPrefix,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
)
|
|
108
|
-
return `xref:${refid}[${text}]`
|
|
106
|
+
assemblyModel.filetype,
|
|
107
|
+
text.length > 0
|
|
108
|
+
)
|
|
109
|
+
return `xref:${fragment ? refidLeader + fragment : refid}[${text}]`
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
function rewriteImageAttr (val, contentCatalog, assemblyModel, ctx, assets) {
|
|
@@ -160,6 +161,8 @@ function rewriteStyleAttribute (block, lines, idx, idLeader, replacementStyle =
|
|
|
160
161
|
if (cellSpec) {
|
|
161
162
|
prevLine = cellSpec[2]
|
|
162
163
|
cellSpec = cellSpec[1]
|
|
164
|
+
} else if (~prevLine.indexOf('id=')) {
|
|
165
|
+
prevLine = `[${prevLine.slice(1, -1).replace(NamedIdAttrRx, '')}]`
|
|
163
166
|
}
|
|
164
167
|
let rawStyle
|
|
165
168
|
const commaIdx = prevLine.indexOf(',')
|
package/lib/util/rx.js
ADDED
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.18",
|
|
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)",
|