@antora/assembler 1.0.0-alpha.1 → 1.0.0-alpha.4
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.
|
@@ -105,7 +105,7 @@ function aggregateAsciiDoc (
|
|
|
105
105
|
page = new page.constructor(Object.assign({}, page, { contents, mediaType: 'text/asciidoc' }))
|
|
106
106
|
const { module: module_, relative, origin } = page.src
|
|
107
107
|
const doc = loadAsciiDoc(page, contentCatalog, asciidocConfig)
|
|
108
|
-
const
|
|
108
|
+
const refs = doc.getCatalog().refs
|
|
109
109
|
// NOTE: in Antora, docname is relative src path from module without file extension
|
|
110
110
|
const docname = doc.getAttribute('docname')
|
|
111
111
|
//const idprefix = `${module_ === 'ROOT' ? '' : module_ + ':'}${docname}//`
|
|
@@ -171,22 +171,10 @@ function aggregateAsciiDoc (
|
|
|
171
171
|
const ignoreLines = []
|
|
172
172
|
// TODO: think more about when multipart is allowed; perhaps configurable
|
|
173
173
|
if (doc.hasSections()) fixSectionLevels(doc.getSections(), level === 0)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
accum.push(block)
|
|
179
|
-
if (block.getContext() === 'table') {
|
|
180
|
-
const rows = block.rows
|
|
181
|
-
;[...rows.body, ...rows.foot].forEach((row) => {
|
|
182
|
-
row.forEach((cell) => {
|
|
183
|
-
if (cell.style !== 'asciidoc') return
|
|
184
|
-
accum.push(...cell.inner_document.findBy((it) => it.getContext() !== 'document'))
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
}
|
|
188
|
-
return accum
|
|
189
|
-
}, [])
|
|
174
|
+
const allBlocks = doc.findBy(
|
|
175
|
+
{ traverse_documents: true },
|
|
176
|
+
(it) => it.getContext() !== 'document' && !(it.getContext() === 'table_cell' && it.getStyle() === 'asciidoc')
|
|
177
|
+
)
|
|
190
178
|
allBlocks.forEach((block) => {
|
|
191
179
|
const contentModel = block.content_model
|
|
192
180
|
if (
|
|
@@ -218,11 +206,9 @@ function aggregateAsciiDoc (
|
|
|
218
206
|
let line = lines[idx]
|
|
219
207
|
if (~line.indexOf('<<')) {
|
|
220
208
|
line = line.replace(/(?<![\\+])<<#?([\p{Alpha}0-9_/.:{][^>,]*?)(?:|, *([^>]+?))?>>/gu, (m, refid, text) => {
|
|
221
|
-
// support natural xref
|
|
222
|
-
if (!
|
|
223
|
-
if (
|
|
224
|
-
return m
|
|
225
|
-
}
|
|
209
|
+
// support natural xref
|
|
210
|
+
if (!refs['$key?'](refid) && (~refid.indexOf(' ') || refid.toLowerCase() !== refid)) {
|
|
211
|
+
if ((refid = doc.$resolve_id(refid))['$nil?']()) return m
|
|
226
212
|
}
|
|
227
213
|
return `<<${idprefix}${refid}${text ? ',' + text : ''}>>`
|
|
228
214
|
})
|
|
@@ -233,21 +219,26 @@ function aggregateAsciiDoc (
|
|
|
233
219
|
}
|
|
234
220
|
if (~line.indexOf('xref:')) {
|
|
235
221
|
// Q: should we allow : as first character of target?
|
|
236
|
-
line = line.replace(/xref:([\p{Alpha}
|
|
222
|
+
line = line.replace(/xref:([\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (m, target, text) => {
|
|
237
223
|
let pagePart, fragment, targetPage
|
|
238
224
|
const hashIdx = target.indexOf('#')
|
|
239
225
|
if (~hashIdx) {
|
|
240
226
|
pagePart = target.substr(0, hashIdx)
|
|
241
227
|
fragment = target.substr(hashIdx + 1)
|
|
242
228
|
// TODO: for now, assume .adoc; in the future, consider other file extensions
|
|
243
|
-
if (
|
|
229
|
+
if (pagePart && !pagePart.endsWith('.adoc')) pagePart += '.adoc'
|
|
244
230
|
} else if (target.endsWith('.adoc')) {
|
|
245
231
|
pagePart = target
|
|
246
232
|
fragment = ''
|
|
247
233
|
} else {
|
|
248
234
|
fragment = target
|
|
249
235
|
}
|
|
250
|
-
if (!pagePart)
|
|
236
|
+
if (!pagePart) {
|
|
237
|
+
// Q: should we validate the internal ID here?
|
|
238
|
+
return text && ~text.indexOf('=')
|
|
239
|
+
? `xref:${idprefix}${fragment}[${text}]`
|
|
240
|
+
: `<<${idprefix}${fragment}${text ? ',' + text.replace(/\\]/g, ']') : ''}>>`
|
|
241
|
+
}
|
|
251
242
|
if (~pagePart.indexOf('@') || /:.*:/.test(pagePart)) {
|
|
252
243
|
// TODO: handle unresolved page better
|
|
253
244
|
return siteUrl && (targetPage = contentCatalog.resolvePage(pagePart, page.src))
|
|
@@ -301,6 +292,7 @@ function aggregateAsciiDoc (
|
|
|
301
292
|
// NOTE: need to do this last since it modifies the line numbers
|
|
302
293
|
// we could remap the line numbers to make them resilient
|
|
303
294
|
// or we could mark which lines to remove and filter them after
|
|
295
|
+
let lastImageMacroAt
|
|
304
296
|
;[...allBlocks].reverse().forEach((block) => {
|
|
305
297
|
const lineno = block.getLineNumber()
|
|
306
298
|
// NOTE: lineno is not defined for preamble
|
|
@@ -327,33 +319,33 @@ function aggregateAsciiDoc (
|
|
|
327
319
|
if (block.getId()) rewriteStyleAttribute(block, lines, idx, idprefix, blockStyle)
|
|
328
320
|
} else {
|
|
329
321
|
if (context === 'image') {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
lines[idx] = `image::${image.pub.url.substr(1)}${line.substr(line.indexOf('['))}`
|
|
322
|
+
let line = lines[idx] || ''
|
|
323
|
+
let prefix = ''
|
|
324
|
+
// Q: can we use startsWith('image::') in certain cases?
|
|
325
|
+
let imageMacroOffset = (
|
|
326
|
+
lastImageMacroAt && lastImageMacroAt[0] === idx ? line.substr(0, lastImageMacroAt[1]) : line
|
|
327
|
+
).lastIndexOf('image::')
|
|
328
|
+
if (imageMacroOffset > 0) {
|
|
329
|
+
if (
|
|
330
|
+
block.getDocument().isNested() &&
|
|
331
|
+
(prefix = line.substr(0, imageMacroOffset)).trimRight().endsWith('|')
|
|
332
|
+
) {
|
|
333
|
+
line = line.substr(prefix.length)
|
|
334
|
+
} else {
|
|
335
|
+
imageMacroOffset = -1
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (imageMacroOffset >= 0) {
|
|
339
|
+
const target = block.getAttribute('target')
|
|
340
|
+
if (isResourceSpec(target)) {
|
|
341
|
+
const image = contentCatalog.resolveResource(target, page.src, 'image', ['image'])
|
|
342
|
+
// FIXME: handle (or report) case when image is not resolved
|
|
343
|
+
if (image) {
|
|
344
|
+
lines[idx] = `${prefix}image::${image.pub.url.substr(1)}${line.substr(line.indexOf('['))}`
|
|
345
|
+
image.out.assembled = true
|
|
346
|
+
}
|
|
356
347
|
}
|
|
348
|
+
lastImageMacroAt = [idx, imageMacroOffset]
|
|
357
349
|
}
|
|
358
350
|
}
|
|
359
351
|
if (block.getId()) rewriteStyleAttribute(block, lines, idx, idprefix)
|
|
@@ -6,13 +6,15 @@ const selectMutableAttributes = require('./select-mutable-attributes')
|
|
|
6
6
|
|
|
7
7
|
function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfig) {
|
|
8
8
|
const { insertStartPage, rootLevel, sectionMergeStrategy, asciidoc: assemblerAsciiDocConfig } = assemblerConfig
|
|
9
|
+
const assemblerAsciiDocAttributes = Object.assign({}, assemblerAsciiDocConfig.attributes)
|
|
10
|
+
delete assemblerAsciiDocAttributes['source-highlighter'] // only used at convert time
|
|
9
11
|
return filterComponentVersions(contentCatalog.getComponents(), assemblerConfig.componentVersions).reduce(
|
|
10
12
|
(accum, componentVersion) => {
|
|
11
13
|
const { name: componentName, version, title, navigation } = componentVersion
|
|
12
14
|
if (!navigation) return accum
|
|
13
15
|
const componentVersionAsciiDocConfig = getAsciiDocConfigWithAsciidoctorReducerExtension(componentVersion)
|
|
14
16
|
const mergedAsciiDocConfig = Object.assign({}, componentVersionAsciiDocConfig, {
|
|
15
|
-
attributes: Object.assign({}, componentVersionAsciiDocConfig.attributes,
|
|
17
|
+
attributes: Object.assign({}, componentVersionAsciiDocConfig.attributes, assemblerAsciiDocAttributes),
|
|
16
18
|
})
|
|
17
19
|
const rootEntry = { content: title }
|
|
18
20
|
const startPage = contentCatalog.getComponentVersionStartPage(componentName, version)
|
|
@@ -60,6 +62,7 @@ function getAsciiDocConfigWithAsciidoctorReducerExtension (componentVersion) {
|
|
|
60
62
|
},
|
|
61
63
|
[asciidoctorReducerExtension]
|
|
62
64
|
),
|
|
65
|
+
sourcemap: true,
|
|
63
66
|
})
|
|
64
67
|
}
|
|
65
68
|
return Object.assign({}, asciidocConfig, { extensions: [asciidoctorReducerExtension], sourcemap: true })
|
|
@@ -6,9 +6,8 @@ const { PassThrough } = require('stream')
|
|
|
6
6
|
class LazyReadable extends PassThrough {
|
|
7
7
|
constructor (fn, options) {
|
|
8
8
|
super(options)
|
|
9
|
-
const _read = this._read
|
|
10
9
|
this._read = function () {
|
|
11
|
-
this._read
|
|
10
|
+
delete this._read // restores original method
|
|
12
11
|
fn.call(this, options).on('error', this.emit.bind(this, 'error')).pipe(this)
|
|
13
12
|
return this._read.apply(this, arguments)
|
|
14
13
|
}
|
package/lib/util/run-command.js
CHANGED
|
@@ -43,11 +43,15 @@ async function runCommand (cmd, argv = [], opts = {}) {
|
|
|
43
43
|
ps.on('error', (err) => reject(err.code === 'ENOENT' ? new Error(`Command not found: ${cmdv.join(' ')}`) : err))
|
|
44
44
|
ps.stdout.on('data', (data) => (output ? process.stdout.write(data) : stdout.push(data)))
|
|
45
45
|
ps.stderr.on('data', (data) => stderr.push(data))
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
if (input instanceof Buffer) {
|
|
47
|
+
try {
|
|
48
|
+
ps.stdin.on('error', () => undefined)
|
|
49
|
+
ps.stdin.end(input)
|
|
50
|
+
} catch (err) {
|
|
51
|
+
if (!ps.stdin.writableEnded) ps.stdin.end()
|
|
52
|
+
reject(err)
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
51
55
|
ps.stdin.end()
|
|
52
56
|
}
|
|
53
57
|
})
|
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.4",
|
|
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)",
|