@antora/assembler 1.0.0-beta.9 → 1.0.0-rc.10
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/adapters/asciidoctor/jsonl-logger.rb +25 -0
- package/lib/assemble-content.js +141 -135
- package/lib/compile-conversion-attributes.js +76 -0
- package/lib/configure.js +44 -16
- package/lib/constants.js +24 -0
- package/lib/filter-component-versions.js +25 -62
- package/lib/index.js +1 -1
- package/lib/load-config.js +84 -43
- package/lib/log-command.js +18 -0
- package/lib/produce-assembly-file.js +539 -509
- package/lib/produce-assembly-files.js +128 -157
- package/lib/util/collate-asciidoc-attributes.js +32 -0
- package/lib/util/create-resource-key.js +7 -0
- package/lib/util/deep-clone.js +18 -0
- package/lib/util/generate-scoped-id.js +26 -0
- package/lib/util/identify-mutable-attributes.js +25 -0
- package/lib/util/lazy-readable.js +12 -3
- package/lib/util/matcher.js +150 -0
- package/lib/util/parse-resource-ref.js +36 -0
- package/lib/util/resolver.js +36 -0
- package/lib/util/rewriter.js +231 -0
- package/lib/util/rx.js +5 -0
- package/lib/util/to-hash.js +7 -0
- package/lib/util/unconvert-inline-asciidoc.js +22 -14
- package/package.json +15 -15
- package/lib/select-mutable-attributes.js +0 -26
- package/lib/util/compute-out.js +0 -57
- package/lib/util/create-asciidoc-file.js +0 -17
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
function parseResourceRef (ref, ctx = {}, family = undefined, contentCatalog = undefined) {
|
|
4
|
+
const atIdx = ref.indexOf('@')
|
|
5
|
+
let firstColonIdx = ref.indexOf(':')
|
|
6
|
+
let component, version, module_
|
|
7
|
+
if (~atIdx && (~firstColonIdx ? atIdx < firstColonIdx : true)) {
|
|
8
|
+
if ((version = ref.substring(0, atIdx)) === '_') version = ''
|
|
9
|
+
ref = ref.substring(atIdx + 1)
|
|
10
|
+
if (~firstColonIdx) firstColonIdx -= atIdx + 1
|
|
11
|
+
}
|
|
12
|
+
const addColons = ~firstColonIdx ? (~ref.indexOf(':', firstColonIdx + 1) ? '' : ':') : '::'
|
|
13
|
+
const segments = (addColons + ref).split(':')
|
|
14
|
+
if ((component = segments[0])) {
|
|
15
|
+
module_ = segments[1] || 'ROOT'
|
|
16
|
+
version ??= contentCatalog?.getComponent(component)?.latest.version
|
|
17
|
+
} else {
|
|
18
|
+
component = ctx.component
|
|
19
|
+
version ??= ctx.version
|
|
20
|
+
module_ = segments[1] || ctx.module || 'ROOT'
|
|
21
|
+
}
|
|
22
|
+
let relative = segments.length > 3 ? segments.slice(2).join(':') : segments[2]
|
|
23
|
+
const dollarIdx = relative.indexOf('$')
|
|
24
|
+
if (~dollarIdx) {
|
|
25
|
+
family = relative.substring(0, dollarIdx) || family
|
|
26
|
+
relative = relative.substring(dollarIdx + 1)
|
|
27
|
+
}
|
|
28
|
+
if (relative.charAt() === '.' && relative.charAt(1) === '/') {
|
|
29
|
+
const ctxRelative = ctx.relative
|
|
30
|
+
const topic = ctxRelative ? ctxRelative.substring(0, (ctxRelative.lastIndexOf('/') + 1 || 1) - 1) : undefined
|
|
31
|
+
relative = (topic ? topic + '/' : '') + relative.substring(2)
|
|
32
|
+
}
|
|
33
|
+
return { component, version, module: module_, family, relative }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = parseResourceRef
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('node:path/posix')
|
|
4
|
+
|
|
5
|
+
function resolveEmbedTarget (resource, outDirname, referenceStyle, escapeForInline) {
|
|
6
|
+
const target =
|
|
7
|
+
referenceStyle === 'output-relative' ? resource.out.path : path.relative(outDirname + '/', resource.out.path)
|
|
8
|
+
return escapeForInline ? target.replace(/_/g, '{underscore}') : target
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function resolveLinkTarget (resource, siteRoot, pubRoot, referenceStyle, escapeForInline, ensurePrefix = true) {
|
|
12
|
+
let target
|
|
13
|
+
if (resource.site?.url) {
|
|
14
|
+
target = ['', resource.pub.url]
|
|
15
|
+
} else {
|
|
16
|
+
switch (referenceStyle) {
|
|
17
|
+
case 'absolute':
|
|
18
|
+
target = ['', siteRoot.url + resource.pub.url]
|
|
19
|
+
break
|
|
20
|
+
case 'root-relative':
|
|
21
|
+
target = [ensurePrefix ? 'link:' : '', siteRoot.path + resource.pub.url]
|
|
22
|
+
break
|
|
23
|
+
default:
|
|
24
|
+
target = [ensurePrefix ? 'link:' : '', computeRelativeUrl(pubRoot + '/', resource.pub.url)]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (escapeForInline) target[1] = target[1].replace(/_/g, '{underscore}')
|
|
28
|
+
return target.join('')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function computeRelativeUrl (from, to) {
|
|
32
|
+
const rel = path.relative(from, to)
|
|
33
|
+
return to.charAt(to.length - 1) === '/' ? rel + '/' : rel
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { resolveEmbedTarget, resolveLinkTarget }
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const createResourceKey = require('./create-resource-key')
|
|
4
|
+
const generateScopedId = require('./generate-scoped-id')
|
|
5
|
+
const parseResourceRef = require('./parse-resource-ref')
|
|
6
|
+
const { resolveEmbedTarget, resolveLinkTarget } = require('./resolver')
|
|
7
|
+
const toHash = require('./to-hash')
|
|
8
|
+
|
|
9
|
+
const { NAMED_ID_ATTR_RX } = require('./rx')
|
|
10
|
+
|
|
11
|
+
function rewriteXrefs (
|
|
12
|
+
line,
|
|
13
|
+
contentCatalog,
|
|
14
|
+
assemblyModel,
|
|
15
|
+
ctx,
|
|
16
|
+
escapeForInline,
|
|
17
|
+
pagesInOutline,
|
|
18
|
+
idSeparators,
|
|
19
|
+
idLeader,
|
|
20
|
+
doc,
|
|
21
|
+
sourceLocation
|
|
22
|
+
) {
|
|
23
|
+
return line.replace(/(?<![\\+])xref:((?:\.\/|:)?[\p{Alpha}0-9_/.{#].*?)\[(|[\s\S]*?[^\\])\]/gu, (_, target, text) =>
|
|
24
|
+
rewriteXref(
|
|
25
|
+
target,
|
|
26
|
+
text,
|
|
27
|
+
contentCatalog,
|
|
28
|
+
assemblyModel,
|
|
29
|
+
ctx,
|
|
30
|
+
escapeForInline,
|
|
31
|
+
pagesInOutline,
|
|
32
|
+
idSeparators,
|
|
33
|
+
idLeader,
|
|
34
|
+
doc,
|
|
35
|
+
sourceLocation
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function rewriteXref (
|
|
41
|
+
target,
|
|
42
|
+
text,
|
|
43
|
+
contentCatalog,
|
|
44
|
+
assemblyModel,
|
|
45
|
+
ctx,
|
|
46
|
+
escapeForInline,
|
|
47
|
+
pagesInOutline,
|
|
48
|
+
idSeparators,
|
|
49
|
+
idLeader,
|
|
50
|
+
doc,
|
|
51
|
+
sourceLocation
|
|
52
|
+
) {
|
|
53
|
+
const rawTarget = target
|
|
54
|
+
if (sourceLocation && ~target.indexOf('{')) {
|
|
55
|
+
target = doc.$sub_attributes(target, toHash({ attribute_missing: 'skip' }))
|
|
56
|
+
}
|
|
57
|
+
let fragment, resourceRef
|
|
58
|
+
const hashIdx = target.indexOf('#')
|
|
59
|
+
if (~hashIdx) {
|
|
60
|
+
resourceRef = target.substring(0, hashIdx)
|
|
61
|
+
fragment = target.substring(hashIdx + 1)
|
|
62
|
+
} else if (target.endsWith('.adoc') || ~target.indexOf('$')) {
|
|
63
|
+
resourceRef = target
|
|
64
|
+
fragment = ''
|
|
65
|
+
} else {
|
|
66
|
+
fragment = target
|
|
67
|
+
}
|
|
68
|
+
if (!resourceRef) return `xref:${idLeader == null ? rawTarget : idLeader + fragment}[${text}]`
|
|
69
|
+
let resourceId = parseResourceRef(resourceRef, ctx, 'page', contentCatalog)
|
|
70
|
+
const family = resourceId.family
|
|
71
|
+
let resource
|
|
72
|
+
if (family === 'page' && !contentCatalog.getById(resourceId)) {
|
|
73
|
+
if ((resource = contentCatalog.getById(Object.assign({}, resourceId, { family: 'alias' })))) {
|
|
74
|
+
resourceId = resource.rel.src
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (family !== 'page' || !(resource = pagesInOutline?.get(createResourceKey(resourceId)))) {
|
|
78
|
+
let defaultText
|
|
79
|
+
if ((resource = contentCatalog.getById(resourceId))?.pub) {
|
|
80
|
+
const { linkReferenceStyle, pubRoot, siteRoot } = assemblyModel
|
|
81
|
+
defaultText = resource.asciidoc?.xreftext || rawTarget
|
|
82
|
+
if (siteRoot || linkReferenceStyle === 'relative') {
|
|
83
|
+
const hash = fragment && !(family === 'page' && fragment === resource.asciidoc.id) ? '#' + fragment : ''
|
|
84
|
+
const linkTarget = resolveLinkTarget(resource, siteRoot, pubRoot, linkReferenceStyle, escapeForInline)
|
|
85
|
+
return `${linkTarget}${hash}[${updateAttrlist(doc, text, defaultText)}]`
|
|
86
|
+
}
|
|
87
|
+
if (sourceLocation) {
|
|
88
|
+
const msg = `Cannot create external ${family} reference in assembly because site URL is unknown: ${rawTarget}`
|
|
89
|
+
doc.getLogger().warn(doc.createLogMessage(msg, { source_location: sourceLocation }))
|
|
90
|
+
}
|
|
91
|
+
} else if (~target.indexOf(':')) {
|
|
92
|
+
defaultText = rawTarget // use explicit text so AsciiDoc processor displays it correctly
|
|
93
|
+
}
|
|
94
|
+
const linkAttrlist = updateAttrlist(doc, text, defaultText, 'unresolved')
|
|
95
|
+
return `link:${rawTarget.charAt() === ':' ? resourceId.module + rawTarget : rawTarget}[${linkAttrlist}]`
|
|
96
|
+
}
|
|
97
|
+
if (fragment === resource.asciidoc.id) fragment = ''
|
|
98
|
+
if (
|
|
99
|
+
text &&
|
|
100
|
+
(assemblyModel.dropExplicitXrefText === 'always' ||
|
|
101
|
+
(assemblyModel.dropExplicitXrefText === 'if-redundant' && text === resource.title))
|
|
102
|
+
) {
|
|
103
|
+
text = ''
|
|
104
|
+
}
|
|
105
|
+
const componentVersionCtx = { name: ctx.component, version: ctx.version }
|
|
106
|
+
const refid = generateScopedId(
|
|
107
|
+
resource.src,
|
|
108
|
+
componentVersionCtx,
|
|
109
|
+
idSeparators,
|
|
110
|
+
assemblyModel.filetype,
|
|
111
|
+
text.length > 0
|
|
112
|
+
)
|
|
113
|
+
return `xref:${fragment ? refid + idSeparators.scope + fragment : refid}[${text}]`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function rewriteImageAttr (val, contentCatalog, assemblyModel, ctx, assets) {
|
|
117
|
+
const match = val.startsWith('image:') && /^image::?(.+?)\[(.*?)\](@|)$/.exec(val)
|
|
118
|
+
if (!match) return
|
|
119
|
+
const newTarget = rewriteImageRef(match[1], contentCatalog, assemblyModel, ctx, assets)
|
|
120
|
+
return newTarget ? `image:${newTarget}[${match[2]}]${match[3]}` : val
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function rewriteInlineImages (line, contentCatalog, assemblyModel, ctx, assets, escapeForInline, doc) {
|
|
124
|
+
return line.replace(/(?<![\\+])image:([^:\s[](?:[^[]*[^\s[])?)\[(|[\s\S]*?[^\\])\]/g, (m, target, attrlist) => {
|
|
125
|
+
const newTarget = rewriteImageRef(target, contentCatalog, assemblyModel, ctx, assets, escapeForInline, doc)
|
|
126
|
+
return newTarget ? `image:${newTarget}[${attrlist}]` : m
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function rewriteImageRef (target, contentCatalog, assemblyModel, ctx, assets, escapeForInline, doc) {
|
|
131
|
+
if (doc && ~target.indexOf('{')) target = doc.$sub_attributes(target, toHash({ attribute_missing: 'skip' }))
|
|
132
|
+
const image = isResourceRef(target) && contentCatalog.resolveResource(target, ctx, 'image', ['image'])
|
|
133
|
+
if (!image?.out) return
|
|
134
|
+
let newTarget
|
|
135
|
+
const { filetype, embedReferenceStyle, linkReferenceStyle, outDirname, pubRoot, siteRoot } = assemblyModel
|
|
136
|
+
if (filetype !== 'html') {
|
|
137
|
+
newTarget = resolveEmbedTarget(image, outDirname, embedReferenceStyle, escapeForInline ?? false)
|
|
138
|
+
assets.add(image)
|
|
139
|
+
} else if (siteRoot || linkReferenceStyle === 'relative') {
|
|
140
|
+
newTarget = resolveLinkTarget(image, siteRoot, pubRoot, linkReferenceStyle, escapeForInline ?? false, false)
|
|
141
|
+
if (linkReferenceStyle === 'relative') assets.add(image)
|
|
142
|
+
}
|
|
143
|
+
return newTarget
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function rewriteStyleAttribute (block, lines, idx, idLeader, replacementStyle = '') {
|
|
147
|
+
let prevLine = lines[idx - 1]
|
|
148
|
+
const char0 = prevLine?.charAt()
|
|
149
|
+
if (char0) {
|
|
150
|
+
if (
|
|
151
|
+
(char0 === '.' && /^\.\.?[^ \t.]/.test(prevLine)) ||
|
|
152
|
+
(char0 === '[' &&
|
|
153
|
+
prevLine.charAt(1) === '[' &&
|
|
154
|
+
/^\[\[(?:|[\p{Alpha}_:][\p{Alpha}0-9_\-:.]*(?:, *.+)?)\]\]$/u.test(prevLine))
|
|
155
|
+
) {
|
|
156
|
+
return rewriteStyleAttribute(block, lines, idx - 1, idLeader, replacementStyle)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
let cellSpec
|
|
160
|
+
const blockId = block.getId()
|
|
161
|
+
if (
|
|
162
|
+
char0 &&
|
|
163
|
+
(char0 === '[' || (block.getDocument().isNested() && (cellSpec = prevLine.match(/^([^[|]*)\| *(\[.+)/)))) &&
|
|
164
|
+
prevLine.charAt(prevLine.length - 1) === ']'
|
|
165
|
+
) {
|
|
166
|
+
if (cellSpec) {
|
|
167
|
+
prevLine = cellSpec[2]
|
|
168
|
+
cellSpec = cellSpec[1]
|
|
169
|
+
} else if (~prevLine.indexOf('id=')) {
|
|
170
|
+
prevLine = `[${prevLine.substring(1, prevLine.length - 1).replace(NAMED_ID_ATTR_RX, '')}]`
|
|
171
|
+
}
|
|
172
|
+
let rawStyle
|
|
173
|
+
const commaIdx = prevLine.indexOf(',')
|
|
174
|
+
if (~commaIdx) {
|
|
175
|
+
rawStyle = prevLine.substring(1, commaIdx)
|
|
176
|
+
if (~rawStyle.indexOf('=')) rawStyle = undefined
|
|
177
|
+
} else if (!~prevLine.indexOf('=')) {
|
|
178
|
+
rawStyle = prevLine.substring(1, prevLine.length - 1)
|
|
179
|
+
}
|
|
180
|
+
if (rawStyle) {
|
|
181
|
+
if (~rawStyle.indexOf('#')) {
|
|
182
|
+
prevLine = prevLine.replace(/#[^.%,\]]+/, `#${idLeader}${blockId}`)
|
|
183
|
+
if (replacementStyle) prevLine = prevLine.replace(/^[^#.%,\]]+/, `[${replacementStyle}`)
|
|
184
|
+
} else {
|
|
185
|
+
prevLine = `[${
|
|
186
|
+
replacementStyle ? rawStyle.replace(/^[^.%]*/, replacementStyle) : rawStyle
|
|
187
|
+
}#${idLeader}${blockId}${prevLine.substring(rawStyle.length + 1)}`
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
prevLine = `[${replacementStyle}#${idLeader}${blockId}${rawStyle == null ? ',' : ''}${prevLine.substring(1)}`
|
|
191
|
+
}
|
|
192
|
+
if (cellSpec) prevLine = `${cellSpec}|${prevLine}`
|
|
193
|
+
lines[idx - 1] = prevLine
|
|
194
|
+
} else {
|
|
195
|
+
lines.splice(idx, 0, `[${replacementStyle}#${idLeader}${blockId}]`)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function isResourceRef (str) {
|
|
200
|
+
return !(~str.indexOf(':') && (~str.indexOf('://') || (str.startsWith('data:') && ~str.indexOf(','))))
|
|
201
|
+
}
|
|
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
|
+
|
|
224
|
+
module.exports = {
|
|
225
|
+
rewriteXref,
|
|
226
|
+
rewriteXrefs,
|
|
227
|
+
rewriteImageAttr,
|
|
228
|
+
rewriteImageRef,
|
|
229
|
+
rewriteInlineImages,
|
|
230
|
+
rewriteStyleAttribute,
|
|
231
|
+
}
|
package/lib/util/rx.js
ADDED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
const ATTRIBUTE_REFERENCE_RX = /\{[a-z0-9_][a-z0-9_-]*\}/g
|
|
4
4
|
const STRICT_WORD_CHAR_RX = /[\p{L}\d_]/u
|
|
5
5
|
const WORD_CHAR_RX = /[\p{L}\d_;}:<>]/u
|
|
6
|
+
const XML_SPECIAL_CHARS = { '<': '<', '>': '>', '&': '&' }
|
|
7
|
+
const XML_SPECIAL_CHARS_RX = /&(?:[lg]t|amp);/g
|
|
6
8
|
|
|
7
9
|
const MARK_FOR_TAG = { code: '`', em: '_', mark: '#', span: '#', strong: '*' }
|
|
8
10
|
const SKIP_SPAN = { icon: '<i ', image: '<img ' }
|
|
@@ -10,17 +12,17 @@ const SKIP_SPAN = { icon: '<i ', image: '<img ' }
|
|
|
10
12
|
module.exports = (str) => {
|
|
11
13
|
if (!str) return str
|
|
12
14
|
let matchIndex = str.indexOf('<')
|
|
13
|
-
if (!~matchIndex) return
|
|
15
|
+
if (!~matchIndex) return unconvertNonTag(str)
|
|
14
16
|
let current = { contents: '' }
|
|
15
17
|
const stack = [current]
|
|
16
18
|
let lastIndex = 0
|
|
17
19
|
do {
|
|
18
20
|
if (matchIndex > lastIndex) {
|
|
19
|
-
const matched = str.
|
|
20
|
-
current.contents +=
|
|
21
|
+
const matched = str.substring(lastIndex, matchIndex)
|
|
22
|
+
current.contents += unconvertNonTag(matched)
|
|
21
23
|
}
|
|
22
24
|
const isCloseTag = str[++matchIndex] === '/' ? ++matchIndex : false
|
|
23
|
-
let tagName = str.
|
|
25
|
+
let tagName = str.substring(matchIndex, (lastIndex = str.indexOf('>', matchIndex) + 1) - 1)
|
|
24
26
|
if (isCloseTag) {
|
|
25
27
|
const parent = current // TODO expect tagName to equal current.tagName
|
|
26
28
|
stack.pop()
|
|
@@ -43,13 +45,13 @@ module.exports = (str) => {
|
|
|
43
45
|
} else {
|
|
44
46
|
let attrs, attrlistIndex, role
|
|
45
47
|
if (~(attrlistIndex = tagName.indexOf(' '))) {
|
|
46
|
-
role = (attrs = parseAttrlist(tagName.
|
|
47
|
-
tagName = tagName.
|
|
48
|
+
role = (attrs = parseAttrlist(tagName.substring(attrlistIndex))).class
|
|
49
|
+
tagName = tagName.substring(0, attrlistIndex)
|
|
48
50
|
}
|
|
49
51
|
if (tagName === 'img') {
|
|
50
52
|
current.contents += 'image:' + attrs.src + '[' + attrs.alt + ']'
|
|
51
53
|
} else if (tagName === 'i' && current.tagName === 'span' && current.role === 'icon') {
|
|
52
|
-
current.contents += 'icon:' + role.
|
|
54
|
+
current.contents += 'icon:' + role.substring(6) + '[]'
|
|
53
55
|
lastIndex += 4
|
|
54
56
|
} else {
|
|
55
57
|
let check, mark
|
|
@@ -61,8 +63,8 @@ module.exports = (str) => {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
} while (~(matchIndex = str.indexOf('<', lastIndex)))
|
|
64
|
-
const rest = str.
|
|
65
|
-
if (rest) current.contents +=
|
|
66
|
+
const rest = str.substring(lastIndex)
|
|
67
|
+
if (rest) current.contents += unconvertNonTag(rest)
|
|
66
68
|
return current.contents
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -73,16 +75,16 @@ function parseAttrlist (str) {
|
|
|
73
75
|
const spaceIndex = str.indexOf(' ', lastIndex)
|
|
74
76
|
const equalsIndex = str.indexOf('=', lastIndex)
|
|
75
77
|
if (~spaceIndex && spaceIndex < equalsIndex) {
|
|
76
|
-
attrs[str.
|
|
78
|
+
attrs[str.substring(lastIndex, (lastIndex = spaceIndex))] = true
|
|
77
79
|
} else if (~equalsIndex) {
|
|
78
|
-
const name = str.
|
|
80
|
+
const name = str.substring(lastIndex, equalsIndex)
|
|
79
81
|
const valueIndex = equalsIndex + 1
|
|
80
82
|
attrs[name] =
|
|
81
83
|
str.charAt(valueIndex) === '"'
|
|
82
|
-
? str.
|
|
83
|
-
: str.
|
|
84
|
+
? str.substring(valueIndex + 1, (lastIndex = str.indexOf('"', valueIndex + 1) + 1) - 1)
|
|
85
|
+
: str.substring(valueIndex, (lastIndex = ~spaceIndex ? spaceIndex : str.length))
|
|
84
86
|
} else {
|
|
85
|
-
attrs[str.
|
|
87
|
+
attrs[str.substring(lastIndex)] = true
|
|
86
88
|
break
|
|
87
89
|
}
|
|
88
90
|
}
|
|
@@ -93,3 +95,9 @@ function isWordChar (str, strict) {
|
|
|
93
95
|
if (!str) return false
|
|
94
96
|
return (strict ? STRICT_WORD_CHAR_RX : WORD_CHAR_RX).test(str)
|
|
95
97
|
}
|
|
98
|
+
|
|
99
|
+
function unconvertNonTag (str) {
|
|
100
|
+
if (~str.indexOf('{')) str = str.replace(ATTRIBUTE_REFERENCE_RX, '\\$&')
|
|
101
|
+
if (~str.indexOf('&')) str = str.replace(XML_SPECIAL_CHARS_RX, (m) => XML_SPECIAL_CHARS[m])
|
|
102
|
+
return str
|
|
103
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/assembler",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.10",
|
|
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)",
|
|
@@ -19,38 +19,38 @@
|
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"test": "node --test test/*-test.js",
|
|
22
|
-
"prepublishOnly": "npx -y downdoc --prepublish",
|
|
23
|
-
"postpublish": "npx -y downdoc --postpublish"
|
|
22
|
+
"prepublishOnly": "npx -y downdoc@latest --prepublish",
|
|
23
|
+
"postpublish": "npx -y downdoc@latest --postpublish"
|
|
24
24
|
},
|
|
25
25
|
"main": "lib/index.js",
|
|
26
26
|
"exports": {
|
|
27
27
|
".": "./lib/index.js",
|
|
28
28
|
"./filter-component-versions": "./lib/filter-component-versions.js",
|
|
29
29
|
"./load-config": "./lib/load-config.js",
|
|
30
|
-
"./
|
|
31
|
-
"./produce-assembly-files": "./lib/produce-assembly-files.js",
|
|
32
|
-
"./select-mutable-attributes": "./lib/select-mutable-attributes.js"
|
|
30
|
+
"./package.json": "./package.json"
|
|
33
31
|
},
|
|
34
32
|
"imports": {
|
|
35
|
-
"#
|
|
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",
|
|
36
36
|
"#unconvert-inline-asciidoc": "./lib/util/unconvert-inline-asciidoc.js"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@asciidoctor/reducer": "~1.1",
|
|
40
39
|
"@antora/expand-path-helper": "~3.0",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"js-yaml": "~
|
|
40
|
+
"@antora/run-command-helper": "~1.1",
|
|
41
|
+
"@asciidoctor/reducer": "~1.1",
|
|
42
|
+
"js-yaml": "~5.3"
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
|
-
"@antora/asciidoc-loader": "
|
|
47
|
-
"@antora/navigation-builder": "
|
|
48
|
-
"@antora/site-publisher": "
|
|
45
|
+
"@antora/asciidoc-loader": "3.2.0-rc.3",
|
|
46
|
+
"@antora/navigation-builder": "3.2.0-rc.3",
|
|
47
|
+
"@antora/site-publisher": "3.2.0-rc.3"
|
|
49
48
|
},
|
|
50
49
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
50
|
+
"node": ">=20.0.0"
|
|
52
51
|
},
|
|
53
52
|
"files": [
|
|
53
|
+
"adapters/",
|
|
54
54
|
"lib/"
|
|
55
55
|
],
|
|
56
56
|
"keywords": [
|
|
@@ -1,26 +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
|
-
return Object.entries(doc.getAttributes()).reduce((accum, [name, val]) => {
|
|
21
|
-
if (!immutableAttributeNames.includes(name)) accum[name] = val
|
|
22
|
-
return accum
|
|
23
|
-
}, {})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
module.exports = selectMutableAttributes
|
package/lib/util/compute-out.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { posix: path } = require('node:path')
|
|
4
|
-
|
|
5
|
-
function computeOut (src) {
|
|
6
|
-
const { component, version, module: module_ = 'ROOT', family, relative } = src
|
|
7
|
-
const outRelative = family === 'page' ? relative.replace(/\.adoc$/, '.html') : relative
|
|
8
|
-
const { dir: dirname, base: basename } = path.parse(outRelative)
|
|
9
|
-
const componentVersion = this.getComponentVersion(component, version)
|
|
10
|
-
const versionSegment =
|
|
11
|
-
'activeVersionSegment' in componentVersion
|
|
12
|
-
? componentVersion.activeVersionSegment
|
|
13
|
-
: resolveActiveVersionSegment.call(this, component, version)
|
|
14
|
-
const outDirSegments = []
|
|
15
|
-
const moduleRootPathSegments = []
|
|
16
|
-
if (component !== 'ROOT') outDirSegments.push(component)
|
|
17
|
-
if (versionSegment) outDirSegments.push(versionSegment)
|
|
18
|
-
if (module_ !== 'ROOT') outDirSegments.push(module_)
|
|
19
|
-
const outModuleDirSegments = outDirSegments.slice()
|
|
20
|
-
if (family !== 'page') {
|
|
21
|
-
outDirSegments.push(`_${family}s`)
|
|
22
|
-
moduleRootPathSegments.push('..')
|
|
23
|
-
}
|
|
24
|
-
if (dirname) {
|
|
25
|
-
outDirSegments.push(dirname)
|
|
26
|
-
for (const _ of dirname.split('/')) moduleRootPathSegments.push('..')
|
|
27
|
-
}
|
|
28
|
-
const rootPathSegments = moduleRootPathSegments.slice()
|
|
29
|
-
for (const _ of outModuleDirSegments) rootPathSegments.push('..')
|
|
30
|
-
const outDirname = outDirSegments.join('/')
|
|
31
|
-
const result = {
|
|
32
|
-
dirname: outDirname,
|
|
33
|
-
basename,
|
|
34
|
-
path: outDirname + '/' + basename,
|
|
35
|
-
moduleRootPath: moduleRootPathSegments.length ? moduleRootPathSegments.join('/') : '.',
|
|
36
|
-
rootPath: rootPathSegments.length ? rootPathSegments.join('/') : '.',
|
|
37
|
-
}
|
|
38
|
-
return result
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function resolveActiveVersionSegment (component, version) {
|
|
42
|
-
let startPage = this.resolvePage('index.adoc', { component, version })
|
|
43
|
-
let startPageSrc
|
|
44
|
-
if (startPage) {
|
|
45
|
-
startPageSrc = startPage.src
|
|
46
|
-
} else {
|
|
47
|
-
startPageSrc = { component, version, module: 'ROOT', family: 'page', relative: 'index.adoc' }
|
|
48
|
-
this.removeFile((startPage = this.addFile({ src: startPageSrc })))
|
|
49
|
-
}
|
|
50
|
-
const outPathSegments = startPage.out.path.split('/')
|
|
51
|
-
for (const _ of startPage.out.moduleRootPath.split('/')) outPathSegments.pop()
|
|
52
|
-
if (startPageSrc.module !== 'ROOT') outPathSegments.pop()
|
|
53
|
-
if (startPageSrc.component !== 'ROOT') outPathSegments.shift()
|
|
54
|
-
return outPathSegments.length ? outPathSegments[0] : ''
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
module.exports = computeOut
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const computeOut = require('./compute-out')
|
|
4
|
-
|
|
5
|
-
function createAsciiDocFile (contentCatalog, file) {
|
|
6
|
-
file.mediaType = 'text/asciidoc'
|
|
7
|
-
const src = file.src
|
|
8
|
-
const out = computeOut.call(contentCatalog, src)
|
|
9
|
-
if (src.family === 'export') {
|
|
10
|
-
contentCatalog.removeFile((file = contentCatalog.addFile(Object.assign(file, { path: out.path, out: null }))))
|
|
11
|
-
return file
|
|
12
|
-
}
|
|
13
|
-
const pub = { url: '/' + out.path, moduleRootPath: out.moduleRootPath, rootPath: out.rootPath }
|
|
14
|
-
return { contents: src.contents ?? Buffer.alloc(0), src, out, pub }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = createAsciiDocFile
|