@antora/assembler 1.0.0-rc.6 → 1.0.0-rc.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 +26 -87
- package/lib/compile-conversion-attributes.js +73 -0
- package/lib/configure.js +6 -4
- package/lib/constants.js +1 -0
- package/lib/index.js +1 -1
- package/lib/load-config.js +5 -5
- package/lib/log-command.js +3 -3
- package/lib/produce-assembly-file.js +140 -117
- package/lib/produce-assembly-files.js +55 -77
- package/lib/util/collate-asciidoc-attributes.js +32 -0
- package/lib/util/deep-clone.js +18 -0
- package/lib/util/identify-mutable-attributes.js +25 -0
- package/lib/util/lazy-readable.js +12 -9
- package/lib/util/rewriter.js +34 -9
- package/lib/util/to-hash.js +7 -0
- package/package.json +3 -5
- package/lib/select-mutable-attributes.js +0 -27
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const collateAsciiDocAttributes = require('./util/collate-asciidoc-attributes')
|
|
3
4
|
const filterComponentVersions = require('./filter-component-versions')
|
|
4
5
|
const produceAssemblyFile = require('./produce-assembly-file')
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const ATTR_REF_RX = /\\?\{(\w[\w-]*)\}/g
|
|
6
|
+
const identifyMutableAttributes = require('./util/identify-mutable-attributes')
|
|
8
7
|
|
|
9
8
|
function produceAssemblyFiles (
|
|
10
9
|
loadAsciiDoc,
|
|
11
10
|
contentCatalog,
|
|
12
11
|
assemblerConfig,
|
|
13
|
-
|
|
12
|
+
selectAssemblerProfile,
|
|
14
13
|
selectComponentVersions
|
|
15
14
|
) {
|
|
16
15
|
const { assembly: assemblyConfig } = assemblerConfig
|
|
17
|
-
|
|
16
|
+
selectAssemblerProfile ??= (componentVersion) => ({
|
|
18
17
|
attributes: assemblyConfig.attributes,
|
|
19
18
|
doctype: assemblyConfig.doctype,
|
|
20
19
|
insertStartPage: assemblyConfig.insertStartPage,
|
|
@@ -30,27 +29,28 @@ function produceAssemblyFiles (
|
|
|
30
29
|
})
|
|
31
30
|
const baseAssemblyAttributes = assemblyConfig.attributes
|
|
32
31
|
const publishableFiles = contentCatalog.getFiles().filter((file) => file.out && file.pub)
|
|
32
|
+
const reducerExtension = require('@asciidoctor/reducer') // require lazily to wait for Opal to be defined
|
|
33
33
|
let siteRoot
|
|
34
34
|
const configMdc = assemblerConfig.file ? { file: { path: assemblerConfig.file } } : {}
|
|
35
35
|
selectComponentVersions ??= filterComponentVersions.bind(null, assemblerConfig.componentVersionFilter)
|
|
36
36
|
return selectComponentVersions(contentCatalog.getComponents()).reduce((accum, componentVersion) => {
|
|
37
|
-
const assemblyModel =
|
|
37
|
+
const assemblyModel = selectAssemblerProfile(componentVersion)
|
|
38
38
|
const { attributes: assemblyAttributes, logger, navigation, rootLevel } = assemblyModel
|
|
39
39
|
if (!navigation) return accum
|
|
40
40
|
const contextualLogger = logger ? { warn: logger.warn.bind(logger, configMdc) } : undefined
|
|
41
41
|
const { name: componentName, version, title } = componentVersion
|
|
42
|
-
const
|
|
42
|
+
const asciidocConfig = getAsciiDocConfigWithAsciidoctorReducerExtension(componentVersion, reducerExtension)
|
|
43
43
|
let sourceHighlighter
|
|
44
44
|
if ('source-highlighter' in assemblyAttributes) {
|
|
45
45
|
sourceHighlighter = assemblyAttributes['source-highlighter']
|
|
46
46
|
delete assemblyAttributes['source-highlighter']
|
|
47
47
|
}
|
|
48
48
|
const mergedAsciiDocAttributes = collateAsciiDocAttributes(
|
|
49
|
-
Object.assign({},
|
|
49
|
+
Object.assign({}, asciidocConfig.attributes),
|
|
50
50
|
assemblyAttributes,
|
|
51
51
|
contextualLogger
|
|
52
52
|
)
|
|
53
|
-
const mergedAsciiDocConfig = Object.assign({},
|
|
53
|
+
const mergedAsciiDocConfig = Object.assign({}, asciidocConfig, {
|
|
54
54
|
attributes: mergedAsciiDocAttributes,
|
|
55
55
|
})
|
|
56
56
|
assemblyModel.filetype = baseAssemblyAttributes['assembler-filetype']
|
|
@@ -82,33 +82,10 @@ function produceAssemblyFiles (
|
|
|
82
82
|
} else if (!(assemblyModel.filetype === 'pdf' && assemblyModel.linkReferenceStyle === 'relative')) {
|
|
83
83
|
assemblyModel.linkReferenceStyle = 'absolute'
|
|
84
84
|
}
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
: contentCatalog.resolvePage('index.adoc', { component: componentName, version })
|
|
90
|
-
if (startPage && startPage.src.component === componentName && startPage.src.version === version) {
|
|
91
|
-
if (assemblyModel.insertStartPage) {
|
|
92
|
-
const navtitle = startPage.asciidoc?.navtitle || rootEntry.content
|
|
93
|
-
Object.assign(rootEntry, { navtitle, url: startPage.pub.url, urlType: 'internal', roles: ['page'] })
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
// Q: should we always use a reference page as startPage for computing mutableAttributes?
|
|
97
|
-
startPage = contentCatalog.createFile({
|
|
98
|
-
src: {
|
|
99
|
-
component: componentVersion.name,
|
|
100
|
-
version: componentVersion.version,
|
|
101
|
-
componentVersion,
|
|
102
|
-
module: 'ROOT',
|
|
103
|
-
family: 'page',
|
|
104
|
-
relative: 'index.adoc',
|
|
105
|
-
origin: (componentVersion.origins || [])[0],
|
|
106
|
-
},
|
|
107
|
-
})
|
|
108
|
-
startPage.path = ['modules', startPage.src.module, startPage.src.family + 's', startPage.src.relative].join('/')
|
|
109
|
-
}
|
|
110
|
-
const mutableAttributes = selectMutableAttributes(loadAsciiDoc, contentCatalog, startPage, mergedAsciiDocConfig)
|
|
111
|
-
prepareOutlines(navigation, rootEntry, rootLevel).reduce((any, outline) => {
|
|
85
|
+
const outlineRoot = { content: title }
|
|
86
|
+
const startPage = resolveStartPage(contentCatalog, componentVersion, assemblyModel.insertStartPage, outlineRoot)
|
|
87
|
+
const mutableAttributes = identifyMutableAttributes(loadAsciiDoc, contentCatalog, startPage, mergedAsciiDocConfig)
|
|
88
|
+
prepareOutlines(navigation, outlineRoot, rootLevel).reduce((any, outline) => {
|
|
112
89
|
const assemblyFile = produceAssemblyFile(
|
|
113
90
|
loadAsciiDoc,
|
|
114
91
|
contentCatalog,
|
|
@@ -132,25 +109,54 @@ function produceAssemblyFiles (
|
|
|
132
109
|
}, [])
|
|
133
110
|
}
|
|
134
111
|
|
|
135
|
-
function getAsciiDocConfigWithAsciidoctorReducerExtension (componentVersion) {
|
|
136
|
-
const asciidoctorReducerExtension = require('@asciidoctor/reducer') // NOTE: must be required lazily
|
|
112
|
+
function getAsciiDocConfigWithAsciidoctorReducerExtension (componentVersion, reducerExtension) {
|
|
137
113
|
const asciidocConfig = componentVersion.asciidoc
|
|
138
|
-
const extensions = [
|
|
114
|
+
const extensions = [reducerExtension]
|
|
139
115
|
const configuredExtensions = asciidocConfig.extensions || []
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
116
|
+
return configuredExtensions.length
|
|
117
|
+
? Object.assign({}, asciidocConfig, {
|
|
118
|
+
extensions: configuredExtensions.reduce((accum, candidate) => {
|
|
119
|
+
if (candidate !== reducerExtension) accum.push(candidate)
|
|
120
|
+
return accum
|
|
121
|
+
}, extensions),
|
|
122
|
+
sourcemap: true,
|
|
123
|
+
})
|
|
124
|
+
: Object.assign({}, asciidocConfig, { extensions, sourcemap: true })
|
|
148
125
|
}
|
|
149
126
|
|
|
150
127
|
function includedInNav (items, url) {
|
|
151
128
|
return items.find((it) => it.url === url || includedInNav(it.items || [], url))
|
|
152
129
|
}
|
|
153
130
|
|
|
131
|
+
function resolveStartPage (contentCatalog, componentVersion, insertStartPage, outlineRoot) {
|
|
132
|
+
const { name: componentName, version } = componentVersion
|
|
133
|
+
let startPage =
|
|
134
|
+
'startPage' in componentVersion
|
|
135
|
+
? componentVersion.startPage
|
|
136
|
+
: contentCatalog.resolvePage('index.adoc', { component: componentName, version })
|
|
137
|
+
if (startPage && startPage.src.component === componentName && startPage.src.version === version) {
|
|
138
|
+
if (insertStartPage) {
|
|
139
|
+
const navtitle = startPage.asciidoc?.navtitle || outlineRoot.content
|
|
140
|
+
Object.assign(outlineRoot, { navtitle, url: startPage.pub.url, urlType: 'internal', roles: ['page'] })
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
startPage = contentCatalog.createFile({
|
|
144
|
+
src: {
|
|
145
|
+
component: componentName,
|
|
146
|
+
version,
|
|
147
|
+
componentVersion,
|
|
148
|
+
module: 'ROOT',
|
|
149
|
+
family: 'page',
|
|
150
|
+
relative: 'index.adoc',
|
|
151
|
+
origin: componentVersion.origins?.values().next().value,
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
// FIXME remove once upgrading to Antora 3.2.0
|
|
155
|
+
startPage.path = ['modules', startPage.src.module, startPage.src.family + 's', startPage.src.relative].join('/')
|
|
156
|
+
}
|
|
157
|
+
return startPage
|
|
158
|
+
}
|
|
159
|
+
|
|
154
160
|
function prepareOutlines (navigation, rootEntry, rootLevel) {
|
|
155
161
|
const singleEntry = navigation.length === 1
|
|
156
162
|
const items = navigation.reduce((accum, it) => {
|
|
@@ -174,37 +180,9 @@ function prepareOutlines (navigation, rootEntry, rootLevel) {
|
|
|
174
180
|
return items
|
|
175
181
|
}
|
|
176
182
|
|
|
177
|
-
function collateAsciiDocAttributes (collated, additional, logger) {
|
|
178
|
-
Object.entries(additional).forEach(([name, val]) => {
|
|
179
|
-
if (val && val.constructor === String) {
|
|
180
|
-
let alias
|
|
181
|
-
val = val.replace(ATTR_REF_RX, (ref, refname) => {
|
|
182
|
-
if (ref.charAt() === '\\') return ref.substring(1)
|
|
183
|
-
const refval = collated[refname]
|
|
184
|
-
if (refval == null || refval === false) {
|
|
185
|
-
if (refname in collated && ref === val) {
|
|
186
|
-
alias = refval
|
|
187
|
-
} else if (collated['attribute-missing'] === 'warn') {
|
|
188
|
-
logger?.warn("Skipping reference to missing attribute '%s' in value of '%s' attribute", refname, name)
|
|
189
|
-
}
|
|
190
|
-
return ref
|
|
191
|
-
}
|
|
192
|
-
if (refval.constructor === String) return refval
|
|
193
|
-
if (ref !== val) return refval.toString()
|
|
194
|
-
alias = refval
|
|
195
|
-
return ref
|
|
196
|
-
})
|
|
197
|
-
if (alias !== undefined) val = alias
|
|
198
|
-
}
|
|
199
|
-
collated[name] = val
|
|
200
|
-
})
|
|
201
|
-
return collated
|
|
202
|
-
}
|
|
203
|
-
|
|
204
183
|
function extractUrlPath (url) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return urlPath === '/' ? '' : urlPath
|
|
184
|
+
const parsedUrl = url ? URL.parse(url) : null
|
|
185
|
+
return parsedUrl == null || parsedUrl.pathname === '/' ? '' : parsedUrl.pathname
|
|
208
186
|
}
|
|
209
187
|
|
|
210
188
|
module.exports = produceAssemblyFiles
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ATTR_REF_RX = /\\?\{(\w[\w-]*)\}/g
|
|
4
|
+
|
|
5
|
+
function collateAsciiDocAttributes (collated, additional = {}, logger = undefined) {
|
|
6
|
+
Object.entries(additional).forEach(([name, val]) => {
|
|
7
|
+
if (val && val.constructor === String) {
|
|
8
|
+
let alias
|
|
9
|
+
val = val.replace(ATTR_REF_RX, (ref, refname) => {
|
|
10
|
+
if (ref.charAt() === '\\') return ref.substring(1)
|
|
11
|
+
const refval = collated[refname]
|
|
12
|
+
if (refval == null || refval === false) {
|
|
13
|
+
if (refname in collated && ref === val) {
|
|
14
|
+
alias = refval
|
|
15
|
+
} else if (collated['attribute-missing'] === 'warn') {
|
|
16
|
+
logger?.warn("Skipping reference to missing attribute '%s' in value of '%s' attribute", refname, name)
|
|
17
|
+
}
|
|
18
|
+
return ref
|
|
19
|
+
}
|
|
20
|
+
if (refval.constructor === String) return refval
|
|
21
|
+
if (ref !== val) return refval.toString()
|
|
22
|
+
alias = refval
|
|
23
|
+
return ref
|
|
24
|
+
})
|
|
25
|
+
if (alias !== undefined) val = alias
|
|
26
|
+
}
|
|
27
|
+
collated[name] = val
|
|
28
|
+
})
|
|
29
|
+
return collated
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = collateAsciiDocAttributes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
function deepClone (o) {
|
|
4
|
+
switch (o.constructor) {
|
|
5
|
+
case Object:
|
|
6
|
+
return Object.keys(o).reduce((accum, k) => {
|
|
7
|
+
const v = o[k]
|
|
8
|
+
accum[k] = !v || typeof v !== 'object' ? v : deepClone(v)
|
|
9
|
+
return accum
|
|
10
|
+
}, {})
|
|
11
|
+
case Array:
|
|
12
|
+
return o.map((it) => (!it || typeof it !== 'object' ? it : deepClone(it)))
|
|
13
|
+
default:
|
|
14
|
+
return o
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = deepClone
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Identifies AsciiDoc attributes that can be modified in the body of the page.
|
|
5
|
+
*
|
|
6
|
+
* This determination is made by loading a reference page with empty contents, retrieving the list of document attribute
|
|
7
|
+
* names, then removing any attributes that were passed via the API with some exceptions. The reason for this function
|
|
8
|
+
* is to be more prudent with which attributes to manage at the boundaries of an assembled page.
|
|
9
|
+
*/
|
|
10
|
+
function identifyMutableAttributes (loadAsciiDoc, contentCatalog, referencePage, asciidocConfig) {
|
|
11
|
+
const doc = loadAsciiDoc(
|
|
12
|
+
new referencePage.constructor(
|
|
13
|
+
Object.assign({}, referencePage, { contents: Buffer.alloc(0), mediaType: 'text/asciidoc' })
|
|
14
|
+
),
|
|
15
|
+
contentCatalog,
|
|
16
|
+
asciidocConfig
|
|
17
|
+
)
|
|
18
|
+
const immutableAttributeNames = doc.attribute_overrides.$keys()['$+'](['doctype'])
|
|
19
|
+
return Object.entries(doc.getAttributes()).reduce((accum, [name, val]) => {
|
|
20
|
+
if (!immutableAttributeNames.includes(name)) accum[name] = val
|
|
21
|
+
return accum
|
|
22
|
+
}, {})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = identifyMutableAttributes
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const fs = require('node:fs')
|
|
3
4
|
const { PassThrough } = require('node:stream')
|
|
4
5
|
|
|
5
6
|
// adapted from https://github.com/jpommerening/node-lazystream/blob/master/lib/lazystream.js | license: MIT
|
|
6
7
|
class LazyReadable extends PassThrough {
|
|
7
|
-
constructor (
|
|
8
|
-
super(
|
|
8
|
+
constructor (fnOrPath) {
|
|
9
|
+
super()
|
|
10
|
+
const fn = typeof fnOrPath === 'function' ? fnOrPath : fs.createReadStream.bind(null, fnOrPath)
|
|
9
11
|
this._read = function () {
|
|
10
12
|
delete this._read // restores original method
|
|
11
|
-
fn.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const readable = fn().on('error', (err) => {
|
|
14
|
+
let msg = 'Failed to create stream'
|
|
15
|
+
if (err.syscall === 'open') msg += ` for path '${err.path}'`
|
|
16
|
+
this.emit('error', new Error(msg, { cause: err }))
|
|
17
|
+
})
|
|
18
|
+
readable.pipe(this)
|
|
19
|
+
this.fd = readable.fd
|
|
20
|
+
this.path = readable.path
|
|
18
21
|
return this._read.apply(this, arguments)
|
|
19
22
|
}
|
|
20
23
|
this.emit('readable')
|
package/lib/util/rewriter.js
CHANGED
|
@@ -4,6 +4,7 @@ const createResourceKey = require('./create-resource-key')
|
|
|
4
4
|
const generateScopedId = require('./generate-scoped-id')
|
|
5
5
|
const parseResourceRef = require('./parse-resource-ref')
|
|
6
6
|
const { resolveEmbedTarget, resolveLinkTarget } = require('./resolver')
|
|
7
|
+
const toHash = require('./to-hash')
|
|
7
8
|
|
|
8
9
|
const { NAMED_ID_ATTR_RX } = require('./rx')
|
|
9
10
|
|
|
@@ -50,7 +51,9 @@ function rewriteXref (
|
|
|
50
51
|
sourceLocation
|
|
51
52
|
) {
|
|
52
53
|
const rawTarget = target
|
|
53
|
-
if (
|
|
54
|
+
if (sourceLocation && ~target.indexOf('{')) {
|
|
55
|
+
target = doc.$sub_attributes(target, toHash({ attribute_missing: 'skip' }))
|
|
56
|
+
}
|
|
54
57
|
let fragment, resourceRef
|
|
55
58
|
const hashIdx = target.indexOf('#')
|
|
56
59
|
if (~hashIdx) {
|
|
@@ -72,21 +75,23 @@ function rewriteXref (
|
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
if (family !== 'page' || !(resource = pagesInOutline?.get(createResourceKey(resourceId)))) {
|
|
78
|
+
let defaultText
|
|
75
79
|
if ((resource = contentCatalog.getById(resourceId))?.pub) {
|
|
76
80
|
const { linkReferenceStyle, pubRoot, siteRoot } = assemblyModel
|
|
77
|
-
|
|
81
|
+
defaultText = resource.asciidoc?.xreftext || rawTarget
|
|
78
82
|
if (siteRoot || linkReferenceStyle === 'relative') {
|
|
79
83
|
const hash = fragment && !(family === 'page' && fragment === resource.asciidoc.id) ? '#' + fragment : ''
|
|
80
|
-
|
|
84
|
+
const linkTarget = resolveLinkTarget(resource, siteRoot, pubRoot, linkReferenceStyle, escapeForInline)
|
|
85
|
+
return `${linkTarget}${hash}[${updateAttrlist(doc, text, defaultText)}]`
|
|
81
86
|
}
|
|
82
|
-
if (
|
|
87
|
+
if (sourceLocation) {
|
|
83
88
|
const msg = `Cannot create external ${family} reference in assembly because site URL is unknown: ${rawTarget}`
|
|
84
89
|
doc.logger.warn(doc.createLogMessage(msg, { source_location: sourceLocation }))
|
|
85
90
|
}
|
|
91
|
+
} else if (~target.indexOf(':')) {
|
|
92
|
+
defaultText = rawTarget // use explicit text so AsciiDoc processor displays it correctly
|
|
86
93
|
}
|
|
87
|
-
const linkAttrlist = text
|
|
88
|
-
? (~text.indexOf(',') ? `"${text}"` : text) + ',role=unresolved'
|
|
89
|
-
: (~target.indexOf(':') ? `${rawTarget},` : '') + 'role=unresolved'
|
|
94
|
+
const linkAttrlist = updateAttrlist(doc, text, defaultText, 'unresolved')
|
|
90
95
|
return `link:${rawTarget.charAt() === ':' ? resourceId.module + rawTarget : rawTarget}[${linkAttrlist}]`
|
|
91
96
|
}
|
|
92
97
|
if (fragment === resource.asciidoc.id) fragment = ''
|
|
@@ -123,7 +128,7 @@ function rewriteInlineImages (line, contentCatalog, assemblyModel, ctx, assets,
|
|
|
123
128
|
}
|
|
124
129
|
|
|
125
130
|
function rewriteImageRef (target, contentCatalog, assemblyModel, ctx, assets, escapeForInline, doc) {
|
|
126
|
-
if (doc && ~target.indexOf('{')) target = doc.$sub_attributes(target,
|
|
131
|
+
if (doc && ~target.indexOf('{')) target = doc.$sub_attributes(target, toHash({ attribute_missing: 'skip' }))
|
|
127
132
|
const image = isResourceRef(target) && contentCatalog.resolveResource(target, ctx, 'image', ['image'])
|
|
128
133
|
if (!image?.out) return
|
|
129
134
|
let newTarget
|
|
@@ -135,7 +140,6 @@ function rewriteImageRef (target, contentCatalog, assemblyModel, ctx, assets, es
|
|
|
135
140
|
newTarget = resolveLinkTarget(image, siteRoot, pubRoot, linkReferenceStyle, escapeForInline ?? false, false)
|
|
136
141
|
if (linkReferenceStyle === 'relative') assets.add(image)
|
|
137
142
|
}
|
|
138
|
-
if (!newTarget) return
|
|
139
143
|
return newTarget
|
|
140
144
|
}
|
|
141
145
|
|
|
@@ -196,6 +200,27 @@ function isResourceRef (str) {
|
|
|
196
200
|
return !(~str.indexOf(':') && (~str.indexOf('://') || (str.startsWith('data:') && ~str.indexOf(','))))
|
|
197
201
|
}
|
|
198
202
|
|
|
203
|
+
function updateAttrlist (doc, attrlist, defaultText, role) {
|
|
204
|
+
const attrs = { named: {}, pos: [] }
|
|
205
|
+
if (attrlist) {
|
|
206
|
+
const normalize = ~attrlist.indexOf('\n')
|
|
207
|
+
if (normalize) attrlist = attrlist.replace(/\n/g, '\x1e')
|
|
208
|
+
doc
|
|
209
|
+
.$parse_attributes(attrlist)
|
|
210
|
+
.$entries()
|
|
211
|
+
.forEach(([k, v]) => {
|
|
212
|
+
v = v['$nil?']() ? '' : normalize ? v.replace(/\x1e/g, '\n') : v
|
|
213
|
+
typeof k === 'number' ? attrs.pos.push(v) : (attrs.named[k] = v)
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
if (defaultText) attrs.pos[0] ||= defaultText
|
|
217
|
+
if (role) attrs.named.role = (attrs.named.role ? attrs.named.role + ' ' : '') + role
|
|
218
|
+
const entries = []
|
|
219
|
+
for (const v of attrs.pos) entries.push(~v.indexOf(',') || ~v.indexOf('=') ? `"${v}"` : v)
|
|
220
|
+
for (const [k, v] of Object.entries(attrs.named)) entries.push(`${k}=` + (~v.indexOf(',') ? `"${v}"` : v))
|
|
221
|
+
return entries.join(',')
|
|
222
|
+
}
|
|
223
|
+
|
|
199
224
|
module.exports = {
|
|
200
225
|
rewriteXref,
|
|
201
226
|
rewriteXrefs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/assembler",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.7",
|
|
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)",
|
|
@@ -27,14 +27,12 @@
|
|
|
27
27
|
".": "./lib/index.js",
|
|
28
28
|
"./filter-component-versions": "./lib/filter-component-versions.js",
|
|
29
29
|
"./load-config": "./lib/load-config.js",
|
|
30
|
-
"./log-command": "./lib/log-command.js",
|
|
31
|
-
"./produce-assembly-file": "./lib/produce-assembly-file.js",
|
|
32
|
-
"./produce-assembly-files": "./lib/produce-assembly-files.js",
|
|
33
|
-
"./select-mutable-attributes": "./lib/select-mutable-attributes.js",
|
|
34
30
|
"./package.json": "./package.json"
|
|
35
31
|
},
|
|
36
32
|
"imports": {
|
|
37
33
|
"#asciidoctor-log-adapter": "./adapters/asciidoctor/jsonl-logger.rb",
|
|
34
|
+
"#identify-mutable-attributes": "./lib/util/identify-mutable-attributes.js",
|
|
35
|
+
"#produce-assembly-files": "./lib/produce-assembly-files.js",
|
|
38
36
|
"#unconvert-inline-asciidoc": "./lib/util/unconvert-inline-asciidoc.js"
|
|
39
37
|
},
|
|
40
38
|
"dependencies": {
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
function selectMutableAttributes (loadAsciiDoc, contentCatalog, referencePage, asciidocConfig) {
|
|
4
|
-
const doc = loadAsciiDoc(
|
|
5
|
-
new referencePage.constructor(
|
|
6
|
-
Object.assign({}, referencePage, { contents: Buffer.alloc(0), mediaType: 'text/asciidoc' })
|
|
7
|
-
),
|
|
8
|
-
contentCatalog,
|
|
9
|
-
asciidocConfig
|
|
10
|
-
)
|
|
11
|
-
const additionalMutableNames = [
|
|
12
|
-
'page-component-name',
|
|
13
|
-
'page-component-version',
|
|
14
|
-
'page-version',
|
|
15
|
-
'page-component-display-version',
|
|
16
|
-
'page-component-title',
|
|
17
|
-
]
|
|
18
|
-
// we could consider using an Asciidoctor extension here to grab attributes passed via the API instead
|
|
19
|
-
const immutableAttributeNames = doc.attribute_overrides.$keys()['$-'](additionalMutableNames)
|
|
20
|
-
immutableAttributeNames.push('doctype')
|
|
21
|
-
return Object.entries(doc.getAttributes()).reduce((accum, [name, val]) => {
|
|
22
|
-
if (!immutableAttributeNames.includes(name)) accum[name] = val
|
|
23
|
-
return accum
|
|
24
|
-
}, {})
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
module.exports = selectMutableAttributes
|