@antora/assembler 1.0.0-rc.4 → 1.0.0-rc.5

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.
@@ -23,7 +23,8 @@ async function assembleContent (playbook, contentCatalog, converter, { configSou
23
23
  backend: targetBackend = targetExtname.substring(1),
24
24
  embedReferenceStyle = 'relative',
25
25
  mediaType: targetMediaType,
26
- loggerName = PACKAGE_NAME,
26
+ loggerName = `${PACKAGE_NAME} [${targetBackend}-exporter]`,
27
+ xmlCompliant,
27
28
  } = converter ?? {}
28
29
  const assemblerConfig = await loadConfig.call(this, configSource, playbook, '-' + targetBackend)
29
30
  if (assemblerConfig.enabled === false || !contentCatalog.publishableFamilies?.has('export')) return []
@@ -38,8 +39,9 @@ async function assembleContent (playbook, contentCatalog, converter, { configSou
38
39
  const { loadAsciiDoc = require('@antora/asciidoc-loader') } = generatorFunctions
39
40
  const { assembly: assemblyConfig, build: buildConfig } = assemblerConfig
40
41
  assemblyConfig.embedReferenceStyle = embedReferenceStyle
42
+ if (xmlCompliant) assemblyConfig.xmlIds ??= true
41
43
  const profile = (assemblyConfig.profile ??= targetBackend)
42
- const intrinsicAttributes = { 'loader-assembler': '' }
44
+ const intrinsicAttributes = { 'loader-assembler': '', 'assembler-root-level': assemblyConfig.rootLevel }
43
45
  const cwd = (buildConfig.cwd ??= process.cwd())
44
46
  if (profile) {
45
47
  buildConfig.dir ??= ospath.join(playbook.dir ?? process.cwd(), `build/assembler/${profile}`)
@@ -150,16 +152,21 @@ function generateSelectAssemblyProfile (context, contentCatalog, baseModel, intr
150
152
  const attributes = Object.assign({}, baseModel.attributes)
151
153
  const model = Object.assign({}, baseModel, overrides, { attributes, logger })
152
154
  if (!overrides) return Object.assign(model, { navigation: navigation || componentVersion.navigation })
155
+ if ('rootLevel' in overrides) attributes['assembler-root-level'] = overrides.rootLevel
153
156
  delete model.navFiles
154
157
  delete model.messages
155
- if (overrides.attributes) Object.entries(overrides.attributes).forEach(([name, val]) => (attributes[name] = val))
158
+ if (overrides.attributes) {
159
+ for (const [name, val] of Object.entries(overrides.attributes)) {
160
+ if (!(name in intrinsicAttributes)) attributes[name] = val
161
+ }
162
+ }
156
163
  if (navigation) return Object.assign(model, { navigation })
157
164
  overrides.messages?.forEach(boundSendToLog)
158
165
  const navFiles = overrides.navFiles
159
166
  if (!navFiles) return Object.assign(model, { navigation: componentVersion.navigation })
160
167
  if (!navFiles.length) return Object.assign(model, { navigation: [] })
161
168
  model.navigation = buildAlternateNavigation(contentCatalog, componentVersion, navFiles, {
162
- attributes: intrinsicAttributes,
169
+ attributes: model.attributes,
163
170
  })
164
171
  return model
165
172
  }
@@ -182,7 +189,7 @@ function prepareConvertAttributes (doc, targetExtname, relativeToOutput, assembl
182
189
  docdir,
183
190
  docfile,
184
191
  docfilesuffix,
185
- 'docname@': docname,
192
+ docname: `${docname}@`,
186
193
  imagesdir: '',
187
194
  outdir,
188
195
  outfile,
@@ -206,6 +213,17 @@ function prepareConvertAttributes (doc, targetExtname, relativeToOutput, assembl
206
213
  return args
207
214
  },
208
215
  })
216
+ Object.defineProperty(attributes, 'outfilesuffix', {
217
+ get () {
218
+ return ospath.extname(this.outfile)
219
+ },
220
+ set (value) {
221
+ const outfile = this.outfile
222
+ const extname = ospath.extname(outfile)
223
+ if (extname && outfile.endsWith(extname)) this.outfile = outfile.substring(0, outfile.length - extname.length)
224
+ this.outfile += value
225
+ },
226
+ })
209
227
  return Object.defineProperty(attributes, 'toArgs', { enumerable: false })
210
228
  }
211
229
 
@@ -265,12 +283,14 @@ async function resolveFileOrContents (convertResult, convertAttributes, buildCon
265
283
  fileOrContents = convertResult.stdout
266
284
  }
267
285
  let logger, match
268
- if (buildConfig.stderrSink === 'log' && convertResult.stderr.length && (logger = this.getLogger(loggerName))) {
286
+ if (buildConfig.stderrSink === 'log' && convertResult.stderr?.length && (logger = this.getLogger(loggerName))) {
269
287
  const docfile = convertAttributes.docfile
270
288
  const command = buildConfig.command
289
+ const file = { path: docfile }
271
290
  const stderr = convertResult.stderr.toString().trimEnd()
291
+ const additionalLines = ['Additional stderr lines from command:']
272
292
  stderr.split(NEWLINE_RX).forEach((line) => {
273
- const ctx = { command, file: { path: docfile } }
293
+ const ctx = { command, file }
274
294
  if (line.charAt() === '{' && line.charAt(line.length - 1) === '}') {
275
295
  const entry = JSON.parse(line)
276
296
  if (entry.name) ctx.program = entry.name
@@ -286,9 +306,10 @@ async function resolveFileOrContents (convertResult, convertAttributes, buildCon
286
306
  if (lineno) ctx.line = parseInt(lineno, 10)
287
307
  logger[level === 'WARNING' ? 'warn' : level.toLowerCase()](ctx, msg)
288
308
  } else {
289
- logger.info(ctx, line)
309
+ additionalLines.push(line)
290
310
  }
291
311
  })
312
+ if (additionalLines.length > 1) logger.info({ command, file }, additionalLines.join('\n'))
292
313
  }
293
314
  } else if (convertResult !== undefined) {
294
315
  return convertResult
package/lib/configure.js CHANGED
@@ -17,7 +17,8 @@ function internalConfigure (converter, config = {}, providers = {}) {
17
17
 
18
18
  this.once('navigationBuilt', async ({ playbook, contentCatalog }) => {
19
19
  const { assembleContent = require('./assemble-content'), ...assembleContentConfig } = providers
20
- if (assembleContentConfig.configSource?.constructor === Object) {
20
+ if (config.configSource?.constructor === Object) {
21
+ assembleContentConfig.configSource = config.configSource
21
22
  await assembleContent.call(this, playbook, contentCatalog, converter, assembleContentConfig)
22
23
  } else {
23
24
  const singleConfig = !('configFiles' in config)
@@ -9,6 +9,7 @@ const yaml = require('js-yaml')
9
9
  const { LEGACY_ASSEMBLY_KEYS } = require('./constants')
10
10
  const CAMEL_CASE_STOP_PATHS = ['asciidoc.attributes', 'assembly.attributes']
11
11
  const PACKAGE_NAME = require('../package.json').name
12
+ const YAML_SCHEMA = yaml.CORE_SCHEMA.withTags(yaml.mergeTag)
12
13
 
13
14
  function loadConfig (configSource, playbook, preferredQualifier = '') {
14
15
  let resolvedConfigSource
@@ -36,11 +37,11 @@ function loadConfig (configSource, playbook, preferredQualifier = '') {
36
37
  }
37
38
  return {}
38
39
  }
39
- return fsp
40
- .readFile(resolvedConfigSource)
41
- .then((data) =>
42
- Object.assign(camelCaseKeys(yaml.load(data), CAMEL_CASE_STOP_PATHS), { file: resolvedConfigSource })
43
- )
40
+ return fsp.readFile(resolvedConfigSource).then((data) =>
41
+ Object.assign(camelCaseKeys(yaml.load(data, { schema: YAML_SCHEMA }), CAMEL_CASE_STOP_PATHS), {
42
+ file: resolvedConfigSource,
43
+ })
44
+ )
44
45
  })
45
46
  ).then((config) => {
46
47
  if (config.enabled === false) return config
@@ -198,6 +198,7 @@ function mergeAsciiDoc (
198
198
  Object.assign({}, page, { contents: trimAsciiDoc(contents), mediaType: page.src.mediaType })
199
199
  )
200
200
  const doc = loadAsciiDoc(pageAsAsciiDoc, contentCatalog, asciidocConfig)
201
+ doc.catalog.syntheticIds = {}
201
202
  doc.logger = logger
202
203
  ? Object.assign(doc.getLogger().$dup(), {
203
204
  delegate: {
@@ -475,7 +476,7 @@ function mergeAsciiDoc (
475
476
  if (~ignoreLines.indexOf(idx)) continue
476
477
  let line = lines[idx]
477
478
  if (line.startsWith('//')) {
478
- if (line[2] !== '/') continue
479
+ if (line.charAt(2) !== '/') continue
479
480
  if (line.length > 3 && line === '/'.repeat(line.length)) {
480
481
  if (skipping) {
481
482
  if (line === skipping) skipping = undefined
@@ -807,10 +808,18 @@ function safePush (onto, entries) {
807
808
 
808
809
  function generateIdFromTitle (titleAsciiDoc, idSeparators, idLeader) {
809
810
  const Section = this.$class().$const_get('::Asciidoctor::Section')
810
- const baseId = Section.$generate_id(titleAsciiDoc, this)
811
- if (idLeader) return `_${idSeparators.coordinate}${idLeader}${baseId}`
812
- this.getCatalog().refs['$[]='](baseId, true)
813
- return `_${idSeparators.coordinate}${baseId}`
811
+ const baseId = Section.$generate_id(titleAsciiDoc, this) // refs in catalog will always be empty
812
+ let id = `_${idSeparators.coordinate}${idLeader ?? ''}${baseId}`
813
+ const syntheticIds = (this.catalog.syntheticIds ??= {})
814
+ if (id in syntheticIds) {
815
+ const sep = (this.getAttribute('idseparator') ?? '_').charAt()
816
+ let cnt = this.$class().$const_get('::Asciidoctor::Compliance').unique_id_start_index
817
+ let candidate
818
+ while ((candidate = `${id}${sep}${cnt}`) in syntheticIds) cnt++
819
+ id = candidate
820
+ }
821
+ syntheticIds[id] = true
822
+ return id
814
823
  }
815
824
 
816
825
  module.exports = produceAssemblyFile
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/assembler",
3
- "version": "1.0.0-rc.4",
3
+ "version": "1.0.0-rc.5",
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)",
@@ -41,7 +41,7 @@
41
41
  "@asciidoctor/reducer": "~1.1",
42
42
  "@antora/expand-path-helper": "~3.0",
43
43
  "@antora/run-command-helper": "~1.1",
44
- "js-yaml": "~4.3"
44
+ "js-yaml": "~5.2"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@antora/asciidoc-loader": "3.2.0-rc.2",