@antora/assembler 1.0.0-alpha.5 → 1.0.0-alpha.6

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.
@@ -121,6 +121,7 @@ const IncludeDirectiveTracker = (() => {
121
121
  this.$$reducer.includePushed = true
122
122
  const directiveLineno = this.lineno - 1 // we're below the include line, which is 1-based
123
123
  const prevIncDepth = this.include_stack.length
124
+ let offset = lineno > 1 ? lineno - 1 : 0
124
125
  const result = Opal.send(this, Opal.find_super_dispatcher(this, 'push_include', pushInclude), [
125
126
  data,
126
127
  file,
@@ -128,12 +129,12 @@ const IncludeDirectiveTracker = (() => {
128
129
  lineno,
129
130
  attrs,
130
131
  ])
131
- pushIncludeReplacement.call(
132
- this,
133
- directiveLineno,
134
- this.include_stack.length > prevIncDepth ? this.$lines() : [],
135
- lineno > 1 ? lineno - 1 : 0
136
- )
132
+ let incLines = []
133
+ if (this.include_stack.length > prevIncDepth) {
134
+ incLines = this.$lines()
135
+ if (attrs['$key?']('leveloffset') && incLines[0].startsWith(':leveloffset: ') && incLines[1] === '') offset -= 2
136
+ }
137
+ pushIncludeReplacement.call(this, directiveLineno, incLines, offset)
137
138
  return result
138
139
  })
139
140
 
@@ -174,8 +175,12 @@ function treeProcessor () {
174
175
  let targetLines, idx
175
176
  if (into != null) {
176
177
  targetLines = incReplacements[into].lines
177
- // adds assurance that we're replacing the correct line
178
- if (targetLines[(idx = lineno - 1)] !== line) return
178
+ // adds extra assurance that the program is replacing the correct line
179
+ if (targetLines[(idx = lineno - 1)] !== line) {
180
+ const msg = `include directive to reduce not found; expected: "${line}"; got: "${targetLines[idx]}"`
181
+ doc.getLogger().error(msg)
182
+ return
183
+ }
179
184
  }
180
185
  if ((drop || []).length) {
181
186
  drop
@@ -1,13 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const camelCaseKeys = require('camelcase-keys')
4
3
  const expandPath = require('@antora/expand-path-helper')
5
4
  const { promises: fsp } = require('fs')
6
5
  const os = require('os')
7
6
  const yaml = require('js-yaml')
8
7
 
9
- const CAMEL_CASE_KEYS_OPTS = { deep: true, stopPaths: ['asciidoc'] }
10
-
11
8
  function loadConfig (playbook, configSource = './antora-assembler.yml') {
12
9
  return (
13
10
  configSource.constructor === Object
@@ -19,9 +16,7 @@ function loadConfig (playbook, configSource = './antora-assembler.yml') {
19
16
  () => false
20
17
  )
21
18
  .then((exists) =>
22
- exists
23
- ? fsp.readFile(configSource).then((data) => camelCaseKeys(yaml.load(data), CAMEL_CASE_KEYS_OPTS))
24
- : {}
19
+ exists ? fsp.readFile(configSource).then((data) => camelCaseKeys(yaml.load(data), ['asciidoc'])) : {}
25
20
  )
26
21
  ).then((config) => {
27
22
  if (config.enabled === false) return undefined
@@ -61,4 +56,16 @@ function loadConfig (playbook, configSource = './antora-assembler.yml') {
61
56
  })
62
57
  }
63
58
 
59
+ function camelCaseKeys (o, stopPaths = [], p) {
60
+ if (Array.isArray(o)) return o.map((it) => camelCaseKeys(it, stopPaths, p))
61
+ if (o == null || o.constructor !== Object) return o
62
+ const pathPrefix = p ? p + '.' : ''
63
+ const accum = {}
64
+ for (const [k, v] of Object.entries(o)) {
65
+ const camelKey = k.charAt() + k.substr(1).replace(/_([a-z])/g, (_, l) => l.toUpperCase())
66
+ accum[camelKey] = ~stopPaths.indexOf(pathPrefix + camelKey) ? v : camelCaseKeys(v, stopPaths, pathPrefix + camelKey)
67
+ }
68
+ return accum
69
+ }
70
+
64
71
  module.exports = loadConfig
@@ -8,6 +8,7 @@ function produceAggregateDocument (
8
8
  contentCatalog,
9
9
  componentVersion,
10
10
  outline,
11
+ doctype,
11
12
  pages,
12
13
  asciidocConfig,
13
14
  mutableAttributes,
@@ -16,7 +17,7 @@ function produceAggregateDocument (
16
17
  const pagesInOutline = selectPagesInOutline(outline, pages)
17
18
  const navtitle = outline.content
18
19
  const stem = generateStem(componentVersion, navtitle)
19
- const header = buildAsciiDocHeader(componentVersion, navtitle)
20
+ const header = buildAsciiDocHeader(componentVersion, navtitle, doctype)
20
21
  const body = aggregateAsciiDoc(
21
22
  loadAsciiDoc,
22
23
  contentCatalog,
@@ -44,13 +45,13 @@ function produceAggregateDocument (
44
45
  })
45
46
  }
46
47
 
47
- function buildAsciiDocHeader (componentVersion, navtitle) {
48
+ function buildAsciiDocHeader (componentVersion, navtitle, doctype = 'book') {
48
49
  const doctitle = navtitle === componentVersion.title ? navtitle : `${componentVersion.title}: ${navtitle}`
49
- const version = componentVersion.version && componentVersion.version !== 'master' ? componentVersion.version : ''
50
+ const version = componentVersion.version === 'master' ? '' : componentVersion.version
50
51
  return [
51
52
  `= ${doctitle}`,
52
53
  ...(version ? [`v${version}`] : []),
53
- ':doctype: book', // for debugging only; set via CLI
54
+ ...(doctype === 'article' ? [] : [`:doctype: ${doctype}`]),
54
55
  // Q: should we pass these via the CLI so they cannot be modified?
55
56
  `:page-component-name: ${componentVersion.name}`,
56
57
  `:page-component-version:${version ? ' ' + version : ''}`,
@@ -208,6 +209,11 @@ function aggregateAsciiDoc (
208
209
  for (let idx = 0, len = lines.length; idx < len; idx++) {
209
210
  if (~ignoreLines.indexOf(idx)) continue
210
211
  let line = lines[idx]
212
+ if (line.charAt() === ':' && /^:(?:leveloffset: .*|!leveloffset:|leveloffset!:)$/.test(line)) {
213
+ if (lines[idx - 1] === '') lines[idx - 1] = undefined
214
+ lines[idx] = undefined
215
+ continue
216
+ }
211
217
  if (~line.indexOf('<<')) {
212
218
  line = line.replace(/(?<![\\+])<<#?([\p{Alpha}0-9_/.:{][^>,]*?)(?:|, *([^>]+?))?>>/gu, (m, refid, text) => {
213
219
  // support natural xref
@@ -223,7 +229,7 @@ function aggregateAsciiDoc (
223
229
  }
224
230
  if (~line.indexOf('xref:')) {
225
231
  // Q: should we allow : as first character of target?
226
- line = line.replace(/xref:([\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (m, target, text) => {
232
+ line = line.replace(/(?<![\\+])xref:([\p{Alpha}0-9_/.{#].*?)\[(|.*?[^\\])\]/gu, (m, target, text) => {
227
233
  let pagePart, fragment, targetPage
228
234
  const hashIdx = target.indexOf('#')
229
235
  if (~hashIdx) {
@@ -305,19 +311,17 @@ function aggregateAsciiDoc (
305
311
  let idx = lineno - 1
306
312
  if (context === 'section' && !block.getDocument().isNested()) {
307
313
  if (block.getSectionName() === 'header') {
308
- lines.splice(idx, 1)
314
+ lines[idx] = undefined
309
315
  return
310
316
  }
311
317
  let blockStyle = sectionMergeStrategy === 'discrete' ? 'discrete' : undefined
312
- // FIXME: quick fix; needs more thorough review
313
- const leveloffset = Number(doc.getAttribute('leveloffset') || 0)
314
- lines[idx] = lines[idx].replace(/^=+( .+)/, (_, rest) => {
315
- let targetMarkerLength = block.level + (1 - leveloffset) + level + (enclosed ? 1 : 0)
318
+ lines[idx] = lines[idx].replace(/^=+ (.+)/, (_, rest) => {
319
+ let targetMarkerLength = block.level + 1 + level + (enclosed ? 1 : 0)
316
320
  if (targetMarkerLength > 6) {
317
321
  targetMarkerLength = 6
318
322
  blockStyle = 'discrete'
319
323
  }
320
- return '='.repeat(targetMarkerLength) + rest
324
+ return '='.repeat(targetMarkerLength) + ' ' + rest
321
325
  })
322
326
  // NOTE: ID will be undefined if sectids are turned off
323
327
  if (block.getId()) rewriteStyleAttribute(block, lines, idx, idprefix, blockStyle)
@@ -327,7 +331,7 @@ function aggregateAsciiDoc (
327
331
  let prefix = ''
328
332
  // Q: can we use startsWith('image::') in certain cases?
329
333
  let imageMacroOffset = (
330
- lastImageMacroAt && lastImageMacroAt[0] === idx ? line.substr(0, lastImageMacroAt[1]) : line
334
+ lastImageMacroAt?.[0] === idx ? line.substr(0, lastImageMacroAt[1]) : line
331
335
  ).lastIndexOf('image::')
332
336
  if (imageMacroOffset > 0) {
333
337
  if (
@@ -358,7 +362,7 @@ function aggregateAsciiDoc (
358
362
  if (block.getId()) rewriteStyleAttribute(block, lines, idx, idprefix)
359
363
  }
360
364
  })
361
- buffer.push(...lines)
365
+ buffer.push(...lines.filter((it) => it !== undefined))
362
366
  const attributeEntries = Object.entries(doc.attributes_defined_in_header || {})
363
367
  if (attributeEntries.length) {
364
368
  const resolvedAttributeEntries = attributeEntries.reduce(
@@ -371,7 +375,7 @@ function aggregateAsciiDoc (
371
375
  } else if (val !== initialVal) {
372
376
  accum.push(`:${name}:${initialVal ? ' ' + initialVal : ''}`)
373
377
  }
374
- } else if (val != null && !(doc.isAttributeLocked(name) || name === 'doctype')) {
378
+ } else if (val != null && !(doc.isAttributeLocked(name) || name === 'doctype' || name === 'leveloffset')) {
375
379
  accum.push(`:!${name}:`)
376
380
  }
377
381
  return accum
@@ -438,7 +442,8 @@ function aggregateAsciiDoc (
438
442
 
439
443
  function generateStem (componentVersion, title) {
440
444
  const { name, version } = componentVersion
441
- const segments = [name]
445
+ const segments = []
446
+ if (name !== 'ROOT') segments.push(name)
442
447
  if (version && version !== 'master') segments.push(version)
443
448
  segments.push(
444
449
  title
@@ -40,6 +40,7 @@ function produceAggregateDocuments (loadAsciiDoc, contentCatalog, assemblerConfi
40
40
  contentCatalog,
41
41
  componentVersion,
42
42
  outline,
43
+ doctype,
43
44
  contentCatalog.getPages((page) => page.out),
44
45
  mergedAsciiDocConfig,
45
46
  mutableAttributes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/assembler",
3
- "version": "1.0.0-alpha.5",
3
+ "version": "1.0.0-alpha.6",
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)",
@@ -31,7 +31,6 @@
31
31
  "dependencies": {
32
32
  "@antora/expand-path-helper": "~2.0",
33
33
  "braces": "~3.0",
34
- "camelcase-keys": "~7.0",
35
34
  "picomatch": "~2.3",
36
35
  "vinyl": "~2.2",
37
36
  "js-yaml": "~4.1"