@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
|
@@ -11,20 +11,22 @@ const {
|
|
|
11
11
|
rewriteStyleAttribute,
|
|
12
12
|
} = require('./util/rewriter')
|
|
13
13
|
const sanitize = require('./util/sanitize')
|
|
14
|
+
const toHash = require('./util/to-hash')
|
|
14
15
|
const unconvertInlineAsciiDoc = require('./util/unconvert-inline-asciidoc')
|
|
15
16
|
|
|
16
17
|
const ATTR_ENTRY_RX = /^:(!?[\p{Alpha}0-9_][^:]*):(?: |$)/u
|
|
17
18
|
const BUILT_IN_NAMED_ENTITIES = { amp: '&', apos: "'", gt: '>', lt: '<', nbsp: ' ', quot: '"' }
|
|
18
19
|
const CHAR_REF_RX = /&(?:([a-z][a-z]+\d{0,2})|#(?:(\d{2,6})|x([a-z\d]{2,5})));/g
|
|
19
20
|
const DISCARD_ATTRIBUTE_NAMES = [
|
|
20
|
-
'doctype',
|
|
21
|
-
'leveloffset',
|
|
22
|
-
'preface-title',
|
|
23
21
|
'assembly-doctype',
|
|
24
22
|
'assembly-header-attributes',
|
|
25
23
|
'assembly-navtitle',
|
|
26
24
|
'assembly-slug',
|
|
27
25
|
'assembly-style',
|
|
26
|
+
'doctype',
|
|
27
|
+
'leveloffset',
|
|
28
|
+
'page-aliases',
|
|
29
|
+
'preface-title',
|
|
28
30
|
'underscore',
|
|
29
31
|
]
|
|
30
32
|
const { NAMED_ID_ATTR_RX } = require('./util/rx')
|
|
@@ -43,18 +45,17 @@ function produceAssemblyFile (
|
|
|
43
45
|
const pagesInOutline = selectPagesInOutline(outline, pagesByUrl)
|
|
44
46
|
if (outline.urlType === 'internal' && !pagesByUrl.has(outline.pathname) && !outline.items?.length) return
|
|
45
47
|
const { rootLevel, xmlIds } = assemblyModel
|
|
48
|
+
const scratchDoc = loadAsciiDoc(
|
|
49
|
+
{ contents: Buffer.alloc(0), src: { family: 'page', relative: '_scratch.adoc' } },
|
|
50
|
+
undefined,
|
|
51
|
+
asciidocConfig
|
|
52
|
+
)
|
|
46
53
|
const idSeparators = {
|
|
47
54
|
prefix:
|
|
48
55
|
'assembler-idprefix' in asciidocConfig.attributes ? (asciidocConfig.attributes['assembler-idprefix'] ?? '') : '_',
|
|
49
56
|
scope: xmlIds ? '---' : ':::',
|
|
50
57
|
coordinate: xmlIds ? '----' : ':',
|
|
51
|
-
generateIdFromTitle: generateIdFromTitle.bind(
|
|
52
|
-
loadAsciiDoc(
|
|
53
|
-
{ contents: Buffer.alloc(0), src: { family: 'page', relative: 'generate-id-from-title.adoc' } },
|
|
54
|
-
undefined,
|
|
55
|
-
asciidocConfig
|
|
56
|
-
)
|
|
57
|
-
),
|
|
58
|
+
generateIdFromTitle: generateIdFromTitle.bind(scratchDoc),
|
|
58
59
|
}
|
|
59
60
|
const { name: component, version } = componentVersion
|
|
60
61
|
asciidocConfig = prepareAsciiDocConfig(
|
|
@@ -63,12 +64,14 @@ function produceAssemblyFile (
|
|
|
63
64
|
pagesInOutline,
|
|
64
65
|
asciidocConfig,
|
|
65
66
|
assemblyModel,
|
|
66
|
-
idSeparators
|
|
67
|
+
idSeparators,
|
|
68
|
+
scratchDoc
|
|
67
69
|
)
|
|
68
|
-
const
|
|
70
|
+
const builder = buildAsciiDocHeader(componentVersion, outline.content, assemblyModel)
|
|
71
|
+
mergeAsciiDoc(
|
|
69
72
|
loadAsciiDoc,
|
|
70
73
|
contentCatalog,
|
|
71
|
-
|
|
74
|
+
builder,
|
|
72
75
|
componentVersion,
|
|
73
76
|
outline,
|
|
74
77
|
files,
|
|
@@ -78,15 +81,14 @@ function produceAssemblyFile (
|
|
|
78
81
|
mutableAttributes,
|
|
79
82
|
assemblyModel
|
|
80
83
|
)
|
|
81
|
-
if (buffer[buffer.doctypeIdx] === ':doctype: article') buffer.splice(buffer.doctypeIdx, 1)
|
|
82
84
|
const stem =
|
|
83
|
-
(
|
|
85
|
+
(builder.slug ? sanitizeSlug(builder.slug) : generateSlug(rootLevel === 0 ? 'index' : builder.navtitle)) ||
|
|
84
86
|
'export-' + (assemblyModel.stemSeq = (assemblyModel.exportSeq ?? 0) + 1)
|
|
85
87
|
const downloadStem = [component, version, stem === 'index' ? '' : stem].filter((it) => it).join('-')
|
|
86
88
|
const file = contentCatalog.createFile({
|
|
87
89
|
asciidoc: asciidocConfig,
|
|
88
90
|
assembler: { assembled: pagesInOutline.assembled, downloadStem, rootLevel },
|
|
89
|
-
contents:
|
|
91
|
+
contents: builder.serialize(),
|
|
90
92
|
src: { component, version, componentVersion, module: 'ROOT', family: 'export', relative: stem + '.adoc' },
|
|
91
93
|
pub: false,
|
|
92
94
|
})
|
|
@@ -95,7 +97,7 @@ function produceAssemblyFile (
|
|
|
95
97
|
return file
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
function prepareAsciiDocConfig (contentCatalog, ctx, pagesInOutline, asciidocConfig, assemblyModel, idSeparators) {
|
|
100
|
+
function prepareAsciiDocConfig (contentCatalog, ctx, pagesInOutline, asciidocConfig, assemblyModel, idSeparators, doc) {
|
|
99
101
|
let attributesModified
|
|
100
102
|
const configShared = asciidocConfig.$shared
|
|
101
103
|
const sharedAttributes = asciidocConfig.attributes
|
|
@@ -116,7 +118,17 @@ function prepareAsciiDocConfig (contentCatalog, ctx, pagesInOutline, asciidocCon
|
|
|
116
118
|
for (const [name, val] of Object.entries(sharedAttributes)) {
|
|
117
119
|
if (!(val?.constructor === String && ~val.indexOf(':'))) continue
|
|
118
120
|
if (~val.indexOf('xref:')) {
|
|
119
|
-
const newVal = rewriteXrefs(
|
|
121
|
+
const newVal = rewriteXrefs(
|
|
122
|
+
val,
|
|
123
|
+
contentCatalog,
|
|
124
|
+
assemblyModel,
|
|
125
|
+
ctx,
|
|
126
|
+
false,
|
|
127
|
+
pagesInOutline,
|
|
128
|
+
idSeparators,
|
|
129
|
+
null,
|
|
130
|
+
doc
|
|
131
|
+
)
|
|
120
132
|
if (newVal !== val) (attributesModified ??= {})[name] = newVal
|
|
121
133
|
}
|
|
122
134
|
}
|
|
@@ -126,25 +138,44 @@ function prepareAsciiDocConfig (contentCatalog, ctx, pagesInOutline, asciidocCon
|
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
function buildAsciiDocHeader (componentVersion, navtitle, assemblyModel) {
|
|
141
|
+
const { name: componentName, version, displayVersion, title } = componentVersion
|
|
129
142
|
const navtitlePlain = sanitize(navtitle)
|
|
130
143
|
const navtitleAsciiDoc = unconvertInlineAsciiDoc(navtitle)
|
|
131
|
-
const doctitle = (
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
const doctitle = (title === navtitlePlain ? '' : title + ': ') + navtitleAsciiDoc
|
|
145
|
+
const versioned = !!(version && version !== 'master')
|
|
146
|
+
return {
|
|
147
|
+
header: [
|
|
148
|
+
`= ${doctitle}`,
|
|
149
|
+
...(versioned ? [`:revnumber: ${displayVersion}`] : []),
|
|
150
|
+
`:doctype: ${(assemblyModel.doctype ??= 'book')}`,
|
|
151
|
+
':underscore: _',
|
|
152
|
+
`:page-component-name: ${componentName}`,
|
|
153
|
+
`:page-component-version:${versioned ? ' ' + version : ''}`,
|
|
154
|
+
':page-version: {page-component-version}',
|
|
155
|
+
`:page-component-display-version: ${displayVersion}`,
|
|
156
|
+
`:page-component-title: ${title}`,
|
|
157
|
+
],
|
|
158
|
+
currentComponentVersion: componentVersion,
|
|
159
|
+
navtitle,
|
|
160
|
+
setAuthor (author) {
|
|
161
|
+
this.header.splice(1, 0, author)
|
|
162
|
+
},
|
|
163
|
+
setDoctitle (doctitle_) {
|
|
164
|
+
this.header[0] = `= ${doctitle_}`
|
|
165
|
+
},
|
|
166
|
+
setDoctype (doctype) {
|
|
167
|
+
this.header[this.header.findIndex((line) => line.startsWith(':doctype: '))] = `:doctype: ${doctype}`
|
|
168
|
+
},
|
|
169
|
+
setDocid (docid) {
|
|
170
|
+
this.header.unshift(`[#${docid}]`)
|
|
171
|
+
},
|
|
172
|
+
serialize () {
|
|
173
|
+
const normalizedHeader = this.header.filter((it) => it !== ':doctype: article')
|
|
174
|
+
return this.body
|
|
175
|
+
? Buffer.from(normalizedHeader.join('\n') + '\n\n' + this.body.join('\n') + '\n')
|
|
176
|
+
: Buffer.from(normalizedHeader.join('\n') + '\n')
|
|
177
|
+
},
|
|
178
|
+
}
|
|
148
179
|
}
|
|
149
180
|
|
|
150
181
|
function selectPagesInOutline (outlineEntry, pagesByUrl, accum) {
|
|
@@ -165,7 +196,7 @@ function selectPagesInOutline (outlineEntry, pagesByUrl, accum) {
|
|
|
165
196
|
function mergeAsciiDoc (
|
|
166
197
|
loadAsciiDoc,
|
|
167
198
|
contentCatalog,
|
|
168
|
-
|
|
199
|
+
builder,
|
|
169
200
|
componentVersion,
|
|
170
201
|
outlineEntry,
|
|
171
202
|
files,
|
|
@@ -174,15 +205,14 @@ function mergeAsciiDoc (
|
|
|
174
205
|
asciidocConfig,
|
|
175
206
|
mutableAttributes,
|
|
176
207
|
assemblyModel,
|
|
177
|
-
lastComponentVersion = componentVersion,
|
|
178
208
|
level = 0,
|
|
179
209
|
supportsParts = false
|
|
180
210
|
) {
|
|
181
211
|
const { items = [], roles = [], unresolved, urlType, url, pathname, hash } = outlineEntry
|
|
182
212
|
// TODO: we could try to be smart about it and make sure the page with fragment is included at least once
|
|
183
|
-
if (roles.includes('site-only')) {
|
|
184
|
-
|
|
185
|
-
return
|
|
213
|
+
if (roles.includes('site-only') || (urlType === 'external' && !URL.canParse(url))) {
|
|
214
|
+
builder.body ??= []
|
|
215
|
+
return builder
|
|
186
216
|
}
|
|
187
217
|
const assembled = pagesInOutline.assembled
|
|
188
218
|
// FIXME: ideally, resource ID would be stored in navigation so we can look up the page more efficiently
|
|
@@ -191,15 +221,15 @@ function mergeAsciiDoc (
|
|
|
191
221
|
let navtitlePlain = sanitize(navtitle)
|
|
192
222
|
let navtitleAsciiDoc = unconvertInlineAsciiDoc(navtitle)
|
|
193
223
|
const { filetype, linkReferenceStyle, pubRoot, sectionMergeStrategy, siteRoot, logger, rootLevel } = assemblyModel
|
|
194
|
-
const doctype = assemblyModel.doctype
|
|
195
|
-
const atDocumentRoot = !
|
|
224
|
+
const doctype = assemblyModel.doctype
|
|
225
|
+
const atDocumentRoot = !builder.body?.length
|
|
196
226
|
let atBookRoot = atDocumentRoot && !level && doctype === 'book' && (supportsParts = true)
|
|
197
227
|
const hasItems = items.length > 0
|
|
198
228
|
if (page && !assembled.pages.has(page)) {
|
|
199
229
|
const contents = page.src.contents
|
|
200
230
|
if (contents == null) {
|
|
201
|
-
|
|
202
|
-
return
|
|
231
|
+
builder.body ??= []
|
|
232
|
+
return builder
|
|
203
233
|
}
|
|
204
234
|
const pageAsAsciiDoc = new page.constructor(
|
|
205
235
|
Object.assign({}, page, { contents: trimAsciiDoc(contents), mediaType: page.src.mediaType })
|
|
@@ -215,25 +245,25 @@ function mergeAsciiDoc (
|
|
|
215
245
|
},
|
|
216
246
|
})
|
|
217
247
|
: doc.getLogger()
|
|
218
|
-
doc.source_header_attributes ??=
|
|
248
|
+
doc.source_header_attributes ??= toHash()
|
|
219
249
|
const isRootPage = atDocumentRoot && !level
|
|
220
250
|
const { component, version, module: module_, relative, origin } = page.src
|
|
221
251
|
const doctypeOverride = doc.getAttribute('assembly-doctype')
|
|
222
252
|
if (doctypeOverride) {
|
|
223
|
-
if (doctypeOverride !== doctype)
|
|
253
|
+
if (doctypeOverride !== doctype) builder.setDoctype(doctypeOverride)
|
|
224
254
|
if (doctypeOverride !== 'book') atBookRoot = supportsParts = false
|
|
225
255
|
}
|
|
226
|
-
if (isRootPage && doc.hasAttribute('assembly-slug'))
|
|
256
|
+
if (isRootPage && doc.hasAttribute('assembly-slug')) builder.slug = doc.getAttribute('assembly-slug')
|
|
227
257
|
let hasAssemblyNavtitleAttr
|
|
228
258
|
if ((hasAssemblyNavtitleAttr = !!doc.getAttribute('assembly-navtitle'))) {
|
|
229
259
|
navtitleAsciiDoc = doc.getAttribute('assembly-navtitle')
|
|
230
260
|
navtitlePlain = sanitize((navtitle = doc.$apply_reftext_subs(navtitleAsciiDoc)))
|
|
231
|
-
if (
|
|
232
|
-
|
|
261
|
+
if (builder.body == null) {
|
|
262
|
+
builder.navtitle = navtitle
|
|
233
263
|
if (rootLevel) {
|
|
234
|
-
|
|
264
|
+
builder.setDoctitle(
|
|
235
265
|
(componentVersion.title === navtitlePlain ? '' : componentVersion.title + ': ') + navtitleAsciiDoc
|
|
236
|
-
|
|
266
|
+
)
|
|
237
267
|
}
|
|
238
268
|
}
|
|
239
269
|
}
|
|
@@ -259,13 +289,10 @@ function mergeAsciiDoc (
|
|
|
259
289
|
let nextSectionLevel = 1
|
|
260
290
|
const lines = doc.getSourceLines()
|
|
261
291
|
const ignoreLines = []
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
buffer.endHeaderIdx = buffer.length - 1
|
|
265
|
-
}
|
|
266
|
-
buffer.push('')
|
|
292
|
+
const buffer = (builder.body ??= [])
|
|
293
|
+
if (buffer.length) buffer.push('')
|
|
267
294
|
buffer.push(`:docname: ${docname}`)
|
|
268
|
-
if (component !==
|
|
295
|
+
if (component !== builder.currentComponentVersion.name) {
|
|
269
296
|
const thisComponentVersion =
|
|
270
297
|
component === componentVersion.name && version === componentVersion.version
|
|
271
298
|
? componentVersion
|
|
@@ -276,7 +303,7 @@ function mergeAsciiDoc (
|
|
|
276
303
|
buffer.push(':page-version: {page-component-version}')
|
|
277
304
|
buffer.push(`:page-component-display-version: ${thisComponentVersion.displayVersion}`)
|
|
278
305
|
buffer.push(`:page-component-title: ${thisComponentVersion.title}`)
|
|
279
|
-
|
|
306
|
+
builder.currentComponentVersion = thisComponentVersion
|
|
280
307
|
}
|
|
281
308
|
}
|
|
282
309
|
buffer.push(`:page-module: ${module_}`)
|
|
@@ -286,13 +313,10 @@ function mergeAsciiDoc (
|
|
|
286
313
|
buffer.push(`:page-origin-refname: ${origin.branch || origin.tag}`)
|
|
287
314
|
buffer.push(`:page-origin-reftype: ${origin.branch ? 'branch' : 'tag'}`)
|
|
288
315
|
buffer.push(`:page-origin-refhash: ${origin.worktree ? '(worktree)' : origin.refhash}`)
|
|
289
|
-
let headerHasBlockAttrs
|
|
290
316
|
if (doc.hasHeader()) {
|
|
291
317
|
for (const entry of processDocumentHeader(doc, lines, ignoreLines, isRootPage)) {
|
|
292
318
|
if (entry.type === 'author_line') {
|
|
293
|
-
|
|
294
|
-
buffer.doctypeIdx += 1
|
|
295
|
-
buffer.endHeaderIdx += 1
|
|
319
|
+
builder.setAuthor(entry.lines[0])
|
|
296
320
|
} else if (entry.type === 'attribute_entry') {
|
|
297
321
|
const name = entry.name
|
|
298
322
|
if (!entry.negated && !doc.isAttributeLocked(name)) {
|
|
@@ -333,14 +357,9 @@ function mergeAsciiDoc (
|
|
|
333
357
|
if (newVal !== val) entry.lines = `:${entry.name}: ${newVal}`.split('\n')
|
|
334
358
|
}
|
|
335
359
|
}
|
|
336
|
-
|
|
337
|
-
buffer.splice(buffer.endHeaderIdx + 1, 0, ...entry.lines)
|
|
338
|
-
buffer.endHeaderIdx += entry.lines.length
|
|
339
|
-
} else {
|
|
340
|
-
buffer.push(...entry.lines)
|
|
341
|
-
}
|
|
360
|
+
;(entry.promote ? builder.header : buffer).push(...entry.lines)
|
|
342
361
|
} else {
|
|
343
|
-
if (entry.type === 'attrlist') headerHasBlockAttrs = true
|
|
362
|
+
if (entry.type === 'attrlist') builder.headerHasBlockAttrs = true
|
|
344
363
|
buffer.push(...entry.lines)
|
|
345
364
|
}
|
|
346
365
|
}
|
|
@@ -364,15 +383,15 @@ function mergeAsciiDoc (
|
|
|
364
383
|
if (htitleOverride != null) {
|
|
365
384
|
const keepSections = hasSections && sectionMergeStrategy !== 'discrete'
|
|
366
385
|
if (htitleOverride === '') {
|
|
367
|
-
if (headerHasBlockAttrs || keepSections) {
|
|
386
|
+
if (builder.headerHasBlockAttrs || keepSections) {
|
|
368
387
|
htitleAsciiDoc = '{empty}'
|
|
369
388
|
notitle = true
|
|
370
389
|
} else {
|
|
371
|
-
if (hasPrefaceTitleAttr)
|
|
390
|
+
if (hasPrefaceTitleAttr) builder.header.push(':preface-title:')
|
|
372
391
|
htitleAsciiDoc = undefined
|
|
373
392
|
}
|
|
374
|
-
} else if (hasPrefaceTitleAttr && !headerHasBlockAttrs && !keepSections) {
|
|
375
|
-
|
|
393
|
+
} else if (hasPrefaceTitleAttr && !builder.headerHasBlockAttrs && !keepSections) {
|
|
394
|
+
builder.header.push(`:preface-title: ${unconvertInlineAsciiDoc(htitleOverride)}`)
|
|
376
395
|
htitleAsciiDoc = undefined
|
|
377
396
|
} else {
|
|
378
397
|
htitleAsciiDoc = unconvertInlineAsciiDoc(htitleOverride)
|
|
@@ -383,8 +402,7 @@ function mergeAsciiDoc (
|
|
|
383
402
|
if (atDocumentRoot) {
|
|
384
403
|
// Q: should we use htitleAsciiDoc to generate ID if not {empty} instead of pageStyle
|
|
385
404
|
pageFragment = `#_${idSeparators.coordinate}${pageIdLeader}${pageStyle}`
|
|
386
|
-
|
|
387
|
-
buffer.doctypeIdx += 1
|
|
405
|
+
builder.setDocid(pageId)
|
|
388
406
|
} else {
|
|
389
407
|
pageFragment = `#${pageId}`
|
|
390
408
|
}
|
|
@@ -414,8 +432,7 @@ function mergeAsciiDoc (
|
|
|
414
432
|
buffer.push(`[${heading.style ?? pageStyle}${pageFragment}${rolesAttr}${notitleAttrs}]`)
|
|
415
433
|
buffer.push(`${'='.repeat(heading.level)} ${heading.title}`)
|
|
416
434
|
} else if (atDocumentRoot) {
|
|
417
|
-
|
|
418
|
-
buffer.doctypeIdx += 1
|
|
435
|
+
builder.setDocid(pageId)
|
|
419
436
|
}
|
|
420
437
|
if (sectionMergeStrategy === 'enclose' && hasItems && hasSections && !(atDocumentRoot && heading)) {
|
|
421
438
|
// TODO: make overview section title configurable
|
|
@@ -423,7 +440,7 @@ function mergeAsciiDoc (
|
|
|
423
440
|
//if (overviewTitle === navtitle) overviewTitle = doc.getAttribute('overview-title', 'Overview')
|
|
424
441
|
const overviewTitle = doc.getAttribute('overview-title', 'Overview')
|
|
425
442
|
const syntheticId = idSeparators.generateIdFromTitle(overviewTitle, idSeparators, pageIdLeader)
|
|
426
|
-
if (heading) buffer.push('')
|
|
443
|
+
if (heading && buffer.length) buffer.push('')
|
|
427
444
|
let hlevel = level + (nextSectionLevel = 2)
|
|
428
445
|
if (hlevel > 6) {
|
|
429
446
|
const blockStyle = `discrete.h${hlevel}`
|
|
@@ -444,7 +461,7 @@ function mergeAsciiDoc (
|
|
|
444
461
|
if (doc.getDoctype() === 'manpage') {
|
|
445
462
|
const firstSectionIdx = hasSections ? doc.getSections()[0].getLineNumber() - 1 : lines.length
|
|
446
463
|
for (let idx = 0; idx < firstSectionIdx; idx++) {
|
|
447
|
-
if (
|
|
464
|
+
if (ignoreLines.includes(idx)) continue
|
|
448
465
|
const line = lines[idx]
|
|
449
466
|
if (line.startsWith('== ') && line.length > 3) {
|
|
450
467
|
allBlocks.unshift({
|
|
@@ -488,7 +505,7 @@ function mergeAsciiDoc (
|
|
|
488
505
|
})
|
|
489
506
|
let skipping
|
|
490
507
|
for (let idx = 0, lastIdx = lines.length - 1; idx <= lastIdx; idx++) {
|
|
491
|
-
if (
|
|
508
|
+
if (ignoreLines.includes(idx)) continue
|
|
492
509
|
let line = lines[idx]
|
|
493
510
|
if (line.startsWith('//')) {
|
|
494
511
|
if (line.charAt(2) !== '/') continue
|
|
@@ -604,10 +621,13 @@ function mergeAsciiDoc (
|
|
|
604
621
|
buffer,
|
|
605
622
|
lines.filter((it) => it !== undefined)
|
|
606
623
|
)
|
|
607
|
-
const attributeEntries =
|
|
624
|
+
const attributeEntries = doc.source_header_attributes.$entries()
|
|
608
625
|
if (attributeEntries.length) {
|
|
609
626
|
const resolvedAttributeEntries = attributeEntries.reduce(
|
|
610
627
|
(accum, [name, val]) => {
|
|
628
|
+
if (val) {
|
|
629
|
+
if (val['$nil?']()) val = null
|
|
630
|
+
}
|
|
611
631
|
// Q: couldn't we just check if attribute is locked?
|
|
612
632
|
if (name in mutableAttributes) {
|
|
613
633
|
const initialVal = mutableAttributes[name]
|
|
@@ -626,12 +646,11 @@ function mergeAsciiDoc (
|
|
|
626
646
|
if (resolvedAttributeEntries.length > 1) safePush(buffer, resolvedAttributeEntries)
|
|
627
647
|
}
|
|
628
648
|
} else if (level && !hash) {
|
|
649
|
+
const buffer = (builder.body ??= [])
|
|
629
650
|
if (atDocumentRoot && rootLevel === 0 && navtitlePlain === componentVersion.title) {
|
|
630
|
-
buffer.inBody ??= false
|
|
631
651
|
level--
|
|
632
652
|
} else {
|
|
633
|
-
buffer.
|
|
634
|
-
buffer.push('')
|
|
653
|
+
if (buffer.length) buffer.push('')
|
|
635
654
|
const syntheticId = idSeparators.generateIdFromTitle(navtitleAsciiDoc, idSeparators)
|
|
636
655
|
let sectionTitle = navtitleAsciiDoc
|
|
637
656
|
if (urlType === 'external') {
|
|
@@ -647,38 +666,39 @@ function mergeAsciiDoc (
|
|
|
647
666
|
}
|
|
648
667
|
}
|
|
649
668
|
}
|
|
669
|
+
if (supportsParts && level === 1 && roles.includes('part')) {
|
|
670
|
+
roles.splice(roles.indexOf('part', 1))
|
|
671
|
+
level--
|
|
672
|
+
}
|
|
650
673
|
const hlevel = level > 5 ? 6 : level + 1
|
|
651
674
|
const hroles = urlType === 'internal' ? roles.slice(1) : roles
|
|
652
675
|
buffer.push(`[${hlevel > 6 ? 'discrete' : ''}#${syntheticId}${hroles.reduce((str, it) => str + '.' + it, '')}]`)
|
|
653
676
|
buffer.push(`${'='.repeat(hlevel)} ${sectionTitle}`)
|
|
654
677
|
}
|
|
655
678
|
}
|
|
656
|
-
if (hasItems)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
})
|
|
680
|
-
}
|
|
681
|
-
return buffer
|
|
679
|
+
if (!hasItems) return
|
|
680
|
+
const nextLevel = level + 1
|
|
681
|
+
// NOTE: drop first child if same as parent; should we keep if content is different?
|
|
682
|
+
;(urlType === 'internal' && items[0].urlType === 'internal' && pathname === items[0].url && !items[0].items?.length
|
|
683
|
+
? items.slice(1)
|
|
684
|
+
: items
|
|
685
|
+
).forEach((item) => {
|
|
686
|
+
mergeAsciiDoc(
|
|
687
|
+
loadAsciiDoc,
|
|
688
|
+
contentCatalog,
|
|
689
|
+
builder,
|
|
690
|
+
componentVersion,
|
|
691
|
+
item,
|
|
692
|
+
files,
|
|
693
|
+
pagesInOutline,
|
|
694
|
+
idSeparators,
|
|
695
|
+
asciidocConfig,
|
|
696
|
+
mutableAttributes,
|
|
697
|
+
assemblyModel,
|
|
698
|
+
nextLevel,
|
|
699
|
+
atBookRoot
|
|
700
|
+
)
|
|
701
|
+
})
|
|
682
702
|
}
|
|
683
703
|
|
|
684
704
|
function processDocumentHeader (doc, lines, ignoreLines, isRootPage) {
|
|
@@ -717,7 +737,7 @@ function processDocumentHeader (doc, lines, ignoreLines, isRootPage) {
|
|
|
717
737
|
}
|
|
718
738
|
const line = lines[idx]
|
|
719
739
|
if (open === ':' || open === '-:') {
|
|
720
|
-
if (open === ':') current.
|
|
740
|
+
if (open === ':') current.appendLine(line)
|
|
721
741
|
if (!line?.endsWith(' \\')) current = open = undefined
|
|
722
742
|
} else if (line) {
|
|
723
743
|
let attributeEntryMatch
|
|
@@ -725,13 +745,14 @@ function processDocumentHeader (doc, lines, ignoreLines, isRootPage) {
|
|
|
725
745
|
if (chr0 === '/' && line.charAt(1) === '/') {
|
|
726
746
|
if (line.startsWith('////') && line === '/'.repeat(line.length)) {
|
|
727
747
|
if (open) {
|
|
728
|
-
current.
|
|
748
|
+
current.appendLine(line)
|
|
729
749
|
if (open === line) current = open = undefined
|
|
730
750
|
} else {
|
|
731
751
|
entries.push((current = { type: 'block_comment', lines: [(open = line)] }))
|
|
752
|
+
current.appendLine = Array.prototype.push.bind(current.lines)
|
|
732
753
|
}
|
|
733
754
|
} else if (open) {
|
|
734
|
-
current.
|
|
755
|
+
current.appendLine(line)
|
|
735
756
|
} else if (belowDoctitle && line.charAt(2) === '/') {
|
|
736
757
|
break
|
|
737
758
|
} else {
|
|
@@ -739,7 +760,7 @@ function processDocumentHeader (doc, lines, ignoreLines, isRootPage) {
|
|
|
739
760
|
current = undefined
|
|
740
761
|
}
|
|
741
762
|
} else if (open) {
|
|
742
|
-
current.
|
|
763
|
+
current.appendLine(line)
|
|
743
764
|
} else if (chr0 === ':' && ~line.indexOf(':', 2) && (attributeEntryMatch = line.match(ATTR_ENTRY_RX))) {
|
|
744
765
|
let name = attributeEntryMatch[1]
|
|
745
766
|
const negated = name.charAt() === '!' || name.charAt(name.length - 1) === '!'
|
|
@@ -748,7 +769,9 @@ function processDocumentHeader (doc, lines, ignoreLines, isRootPage) {
|
|
|
748
769
|
if (line.endsWith(' \\')) open = '-:' // disallow value continuation
|
|
749
770
|
} else {
|
|
750
771
|
if (line.endsWith(' \\')) open = ':'
|
|
751
|
-
entries.push((current = { type: 'attribute_entry', name, negated, lines: [
|
|
772
|
+
entries.push((current = { type: 'attribute_entry', name, negated, lines: [], lineno: idx + 1 }))
|
|
773
|
+
current.lines.push(negated ? `:!${name}:` : line)
|
|
774
|
+
current.appendLine = Array.prototype.push.bind(negated ? [] : current.lines)
|
|
752
775
|
if (assemblyHeaderAttributes.has(name)) current.promote = true
|
|
753
776
|
}
|
|
754
777
|
} else if (belowDoctitle) {
|
|
@@ -822,13 +845,13 @@ function safePush (onto, entries) {
|
|
|
822
845
|
}
|
|
823
846
|
|
|
824
847
|
function generateIdFromTitle (titleAsciiDoc, idSeparators, idLeader) {
|
|
825
|
-
const Section = this.$class()
|
|
848
|
+
const Section = this.$class().$$base_module.Section
|
|
826
849
|
const baseId = Section.$generate_id(titleAsciiDoc, this) // refs in catalog will always be empty
|
|
827
850
|
let id = `_${idSeparators.coordinate}${idLeader ?? ''}${baseId}`
|
|
828
851
|
const syntheticIds = (this.catalog.syntheticIds ??= {})
|
|
829
852
|
if (id in syntheticIds) {
|
|
830
853
|
const sep = (this.getAttribute('idseparator') ?? '_').charAt()
|
|
831
|
-
let cnt = this.$class()
|
|
854
|
+
let cnt = this.$class().$$base_module.Compliance.unique_id_start_index
|
|
832
855
|
let candidate
|
|
833
856
|
while ((candidate = `${id}${sep}${cnt}`) in syntheticIds) cnt++
|
|
834
857
|
id = candidate
|