UNPKG

@antora/assembler

Version:

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.

115 lines (104 loc) 4.89 kB
'use strict' function configure (context, ...args) { internalConfigure.apply(context, args) } function internalConfigure (converter, config = {}, providers = {}) { this.once('componentsRegistered', ({ contentCatalog, assemblerProfiles }) => { if (assemblerProfiles) return this.updateVariables({ assemblerProfiles: getAssemblerProfiles(contentCatalog) }) }) this.once('beforeProcess', enableKeepSource) this.once('navigationBuilt', async ({ playbook, contentCatalog }) => { const { assembleContent = require('./assemble-content'), ...assembleContentConfig } = providers if (assembleContentConfig.configSource?.constructor === Object) { await assembleContent.call(this, playbook, contentCatalog, converter, assembleContentConfig) } else { const singleConfig = !('configFiles' in config) const configFiles = singleConfig ? config.configFile : config.configFiles for (const configSource of Array.isArray(configFiles) ? configFiles : [configFiles]) { const assembleContentConfigWithConfigSource = Object.assign({}, assembleContentConfig, { configSource }) await assembleContent.call(this, playbook, contentCatalog, converter, assembleContentConfigWithConfigSource) if (singleConfig) break } } }) } function enableKeepSource ({ siteAsciiDocConfig }) { if (siteAsciiDocConfig.keepSource instanceof Boolean) return siteAsciiDocConfig.keepSource = Object.assign(new Boolean(true), { oldValue: siteAsciiDocConfig.keepSource }) this.once('navigationBuilt', restoreKeepSource) } function restoreKeepSource ({ siteAsciiDocConfig, contentCatalog }) { if (!(siteAsciiDocConfig.keepSource instanceof Boolean)) return if ((siteAsciiDocConfig.keepSource = siteAsciiDocConfig.keepSource.oldValue)) return contentCatalog.getPages((page) => delete page.src.contents) } function getAssemblerProfiles (contentCatalog, assemblerProfiles = new Map()) { contentCatalog.getComponents().forEach((component) => { component.versions.forEach((componentVersion) => { const source = componentVersion.nav?.origin ?? [...(componentVersion.origins ?? [])].find((it) => it.descriptor?.ext?.assembler) const assemblerConfig = getAssemblerConfigFromDescriptor(source?.descriptor) if (!assemblerConfig) return const componentVersionRef = `${componentVersion.version}@${componentVersion.name}` const filesByPath = componentVersion.files.reduce((accum, it) => accum.set(it.path, it), new Map()) const componentVersionProfiles = assemblerConfig.reduce((accum, entry) => { const data = {} const profile = entry.profile ?? undefined if (accum.has(profile)) return accum const nav = entry.nav Object.entries(entry).forEach(([key, val]) => { if (key === 'profile' || key === 'nav') return const camelKey = key.toLowerCase().replace(/[_-]([a-z0-9])/g, (_, l, idx) => (idx ? l.toUpperCase() : l)) data[camelKey] = val }) if (nav) { data.navFiles = (nav.length ? [...new Set(nav)] : nav).reduce((navFiles, path_) => { const navFile = filesByPath.get(path_) if (navFile) { navFiles.push(initNavFile(navFile, component.name, componentVersion.version, navFiles.length)) } else { ;(data.messages ??= []).push([ 'warn', { source }, `Could not resolve nav file for ${profile || '<default>'} profile in ${componentVersionRef}: ${path_}`, ]) } return navFiles }, []) } else if (!Object.keys(data).length) { return accum } return accum.set(profile, data) }, new Map()) assemblerProfiles.set(componentVersionRef, componentVersionProfiles) }) }) return assemblerProfiles } function getAssemblerConfigFromDescriptor (descriptor = {}) { const assemblerConfig = descriptor.ext?.assembler if (!assemblerConfig) return if (!Array.isArray(assemblerConfig)) return [assemblerConfig] if (assemblerConfig.length) return assemblerConfig } function initNavFile (file, component, version, index) { const src = Object.assign({}, file.src, { component, version, module: 'ROOT', family: 'nav' }) const filePathSegments = file.path.split('/') let relativeStartIdx = 0 if (filePathSegments[0] === 'modules') { relativeStartIdx += 1 if (filePathSegments.length > 2) { relativeStartIdx += 1 src.module = filePathSegments[1] if (filePathSegments.length > 3 && filePathSegments[2] === 'partials') { relativeStartIdx += 1 src.family = 'partial' } } } src.relative = filePathSegments.slice(relativeStartIdx).join('/') return Object.assign(new file.constructor(file), { nav: { index }, src }) } module.exports = configure