@antora/assembler
Version:
An extension library for Antora that assembles content from multiple pages into a single AsciiDoc file to converted and publish.
75 lines (69 loc) • 3.02 kB
JavaScript
const expandPath = require('@antora/expand-path-helper')
const fsp = require('node:fs/promises')
const os = require('node:os')
const yaml = require('js-yaml')
function loadConfig (playbook, configSource = './antora-assembler.yml') {
return (
configSource.constructor === Object
? Promise.resolve(configSource)
: fsp
.access((configSource = expandPath(configSource, { dot: playbook.dir })))
.then(
() => true,
() => false
)
.then((exists) =>
exists ? fsp.readFile(configSource).then((data) => camelCaseKeys(yaml.load(data), ['asciidoc'])) : {}
)
).then((config) => {
if (config.enabled === false) return undefined
let asciidocAttrs
if (!config.asciidoc) {
config.asciidoc = { attributes: (asciidocAttrs = {}) }
} else if (!(asciidocAttrs = config.asciidoc.attributes)) {
config.asciidoc.attributes = asciidocAttrs = {}
}
if (!('doctype' in asciidocAttrs)) asciidocAttrs.doctype = 'book'
if (!('revdate' in asciidocAttrs)) asciidocAttrs.revdate = getLocalDate()
asciidocAttrs['page-partial'] = null
asciidocAttrs['loader-assembler'] = ''
if (config.componentVersions == null) {
config.componentVersions = ['*']
} else if (typeof config.componentVersions === 'string') {
config.componentVersions = config.componentVersions.split(', ')
}
if (!('rootLevel' in config)) config.rootLevel = 0
if (!('insertStartPage' in config)) config.insertStartPage = true
if (['discrete', 'fuse', 'enclose'].indexOf(config.sectionMergeStrategy) < 0) {
config.sectionMergeStrategy = 'discrete'
}
const build = config.build || (config.build = {})
if (build.dir === '$' + '{playbook.output.dir}') {
throw new Error('Not implemented')
}
build.dir = expandPath(build.dir || './build/assembler', { dot: playbook.dir })
build.cwd = playbook.dir // use playbook.dir for the purpose of finding and loading require scripts
if (!('clean' in build) && 'output' in playbook) build.clean = playbook.output.clean
if (!('publish' in build)) build.publish = true
if (!build.processLimit) {
build.processLimit = 'processLimit' in build ? Infinity : Math.round(os.cpus().length * 0.5)
}
return config
})
}
function camelCaseKeys (o, stopPaths = [], p = undefined) {
if (Array.isArray(o)) return o.map((it) => camelCaseKeys(it, stopPaths, p))
if (o == null || o.constructor !== Object) return o
const pathPrefix = p ? p + '.' : ''
const accum = {}
for (const [k, v] of Object.entries(o)) {
const camelKey = k.charAt() + k.slice(1).replace(/_([a-z])/g, (_, l) => l.toUpperCase())
accum[camelKey] = ~stopPaths.indexOf(pathPrefix + camelKey) ? v : camelCaseKeys(v, stopPaths, pathPrefix + camelKey)
}
return accum
}
function getLocalDate (now = new Date()) {
return new Date(now - now.getTimezoneOffset() * 60000).toISOString().split('T')[0]
}
module.exports = loadConfig