@antora/asciidoc-loader
Advanced tools
Comparing version 1.0.0-alpha.6 to 1.0.0-alpha.7
@@ -21,2 +21,3 @@ 'use strict' | ||
const registry = asciidoctor.Extensions.create() | ||
// FIXME includeProcessor API does not accept an instance; use low-level API for now | ||
registry.$include_processor(IncludeProcessor.$new(callbacks.onInclude)) | ||
@@ -23,0 +24,0 @@ return registry |
@@ -5,3 +5,3 @@ 'use strict' | ||
const CIRCUMFIX_COMMENT_SUFFIX_RX = new RegExp(' (?:\\*[/)]|--%?>)$') | ||
const CIRCUMFIX_COMMENT_SUFFIX_RX = / (?:\*[/)]|--%?>)$/ | ||
const NEWLINE_RX = /\r\n?|\n/ | ||
@@ -13,3 +13,3 @@ const TAG_DELIMITER_RX = /[,;]/ | ||
const $callback = Symbol('callback') | ||
const superclass = Opal.module(null, 'Asciidoctor').$$const.Extensions.$$const.IncludeProcessor | ||
const superclass = Opal.module(null, 'Asciidoctor').Extensions.IncludeProcessor | ||
const scope = Opal.klass(Opal.module(null, 'Antora'), superclass, 'IncludeProcessor', function () {}) | ||
@@ -16,0 +16,0 @@ |
'use strict' | ||
// IMPORTANT eagerly load Opal to change the String encoding from UTF-16LE to UTF-8 | ||
// IMPORTANT eagerly load Opal to force the String encoding from UTF-16LE to UTF-8 | ||
const Opal = require('opal-runtime').Opal | ||
@@ -13,5 +13,7 @@ if ('encoding' in String.prototype && String(String.prototype.encoding) !== 'UTF-8') { | ||
const createExtensionRegistry = require('./create-extension-registry') | ||
const { posix: path } = require('path') | ||
const ospath = require('path') | ||
const { posix: path } = ospath | ||
const resolveIncludeFile = require('./include/resolve-include-file') | ||
const DOT_RELATIVE_RX = new RegExp(`^\\.{1,2}[${[...new Set(['/', ospath.sep])].join('').replace('\\', '\\\\')}]`) | ||
const { EXAMPLES_DIR_PROXY, PARTIALS_DIR_PROXY } = require('./constants') | ||
@@ -22,23 +24,21 @@ | ||
* | ||
* Uses the Asciidoctor.js load API to parse the source of the specified file | ||
* into an Asciidoctor Document object. Sets options and attributes that | ||
* provide integration with the Antora environment. The options include a | ||
* custom converter and extension registery to handle page references and | ||
* include directives, respectively. It also assigns attributes that provide | ||
* context either for the author (e.g., env=site) or the pipeline (e.g., | ||
* docfile). | ||
* Uses the Asciidoctor.js load API to parse the source of the file into an Asciidoctor Document object. Sets options | ||
* and attributes that provide integration with the Antora environment. Options include a custom converter and extension | ||
* registry to handle page references and include directives, respectively. It also assigns attributes that provide | ||
* context either for the author (e.g., env=site) or pipeline (e.g., docfile). | ||
* | ||
* @memberof asciidoc-loader | ||
* | ||
* @param {File} file - The virtual file the contains AsciiDoc source contents. | ||
* @param {Object} [customAttrs={}] - Custom attributes to assign on the AsciiDoc document. | ||
* @param {ContentCatalog} [contentCatalog=undefined] - The content catalog | ||
* that provides access to the virtual files in the site. | ||
* @param {Object} [opts={}] - Additional processing options. | ||
* @param {Boolean} [opts.relativizePageRefs=true] - Configures processor to generate | ||
* page references relative to the current page instead of the site root. | ||
* @param {File} file - The virtual file whose contents is an AsciiDoc source document. | ||
* @param {ContentCatalog} [contentCatalog=undefined] - The catalog of all virtual content files in the site. | ||
* @param {Object} [config={}] - AsciiDoc processor configuration options. | ||
* @param {Object} [config.attributes={}] - Shared AsciiDoc attributes to assign to the document. | ||
* @param {Array<Function>} [config.extensions=[]] - Self-registering AsciiDoc processor extension functions. | ||
* @param {Boolean} [config.relativizePageRefs=true] - Configures the AsciiDoc processor to generate relative page | ||
* references (relative to the current page) instead of root relative (relative to the site root). | ||
* | ||
* @returns {Document} An Asciidoctor Document object created from the specified source. | ||
* @returns {Document} An Asciidoctor Document object created from the source of the specified file. | ||
*/ | ||
function loadAsciiDoc (file, customAttrs = {}, contentCatalog = undefined, opts = {}) { | ||
function loadAsciiDoc (file, contentCatalog = undefined, config = {}) { | ||
if (!config) config = {} | ||
const envAttrs = { | ||
@@ -57,7 +57,6 @@ env: 'site', | ||
} | ||
const builtinAttrs = { | ||
const intrinsicAttrs = { | ||
docname: file.src.stem, | ||
docfile: file.path, | ||
// NOTE docdir implicitly sets base_dir on document | ||
// NOTE Opal only expands to absolute path if value begins with ./ | ||
// NOTE docdir implicitly sets base_dir on document; Opal only expands value to absolute path if it starts with ./ | ||
docdir: file.dirname, | ||
@@ -70,4 +69,4 @@ docfilesuffix: file.src.extname, | ||
} | ||
const attributes = Object.assign(envAttrs, defaultAttrs, customAttrs || {}, builtinAttrs) | ||
const relativizePageRefs = opts.relativizePageRefs !== false | ||
const attributes = Object.assign({}, envAttrs, defaultAttrs, config.attributes, intrinsicAttrs) | ||
const relativizePageRefs = config.relativizePageRefs !== false | ||
const converter = createConverter(asciidoctor, { | ||
@@ -79,3 +78,7 @@ onPageRef: (refSpec, content) => convertPageRef(refSpec, content, file, contentCatalog, relativizePageRefs), | ||
}) | ||
const options = { | ||
if (config.extensions && config.extensions.length) { | ||
const context = { file, contentCatalog, config } | ||
config.extensions.forEach((extension) => extension.register(extensionRegistry, context)) | ||
} | ||
return asciidoctor.load(file.contents.toString(), { | ||
attributes, | ||
@@ -85,6 +88,65 @@ converter, | ||
safe: 'safe', | ||
}) | ||
} | ||
/** | ||
* Resolves a global AsciiDoc configuration object from data in the playbook. | ||
* | ||
* Reads data from the asciidoc category of the playbook and resolves it into a global AsciiDoc configuration object | ||
* that can be used by the loadAsciiDoc function. This configuration object is a shallow clone of the data in the | ||
* playbook. The main purpose of this function is to resolve extension references in the playbook to extension | ||
* functions. If the extension is scoped, the function is stored in this object. If the extension is global, it is | ||
* registered with the global extension registry, then discarded. | ||
* | ||
* @memberof asciidoc-loader | ||
* | ||
* @param {Object} playbook - The configuration object for Antora. | ||
* @param {Object} playbook.asciidoc - The AsciiDoc configuration data in the playbook. | ||
* | ||
* @returns {Object} A resolved configuration object to be used by the loadAsciiDoc function. | ||
*/ | ||
function resolveConfig (playbook) { | ||
if (!playbook.asciidoc) return {} | ||
const config = Object.assign({}, playbook.asciidoc) | ||
// TODO process !name attributes | ||
if (config.extensions && config.extensions.length) { | ||
const extensions = config.extensions.reduce((accum, extensionPath) => { | ||
if (extensionPath.charAt() === '.' && DOT_RELATIVE_RX.test(extensionPath)) { | ||
// NOTE require resolves a dot-relative path relative to current file; resolve relative to playbook dir instead | ||
extensionPath = ospath.resolve(playbook.dir, extensionPath) | ||
} else if (!ospath.isAbsolute(extensionPath)) { | ||
// NOTE appending node_modules prevents require from looking elsewhere before looking in these paths | ||
const paths = [playbook.dir, ospath.dirname(__dirname)].map((start) => ospath.join(start, 'node_modules')) | ||
extensionPath = require.resolve(extensionPath, { paths }) | ||
} | ||
const extension = require(extensionPath) | ||
if ('register' in extension) { | ||
accum.push(extension) | ||
} else if (!isExtensionRegistered(extension, asciidoctor.Extensions)) { | ||
// QUESTION should we assign an antora-specific group name? | ||
asciidoctor.Extensions.register(extension) | ||
} | ||
return accum | ||
}, []) | ||
if (extensions.length) { | ||
config.extensions = extensions | ||
} else { | ||
delete config.extensions | ||
} | ||
} else { | ||
delete config.extensions | ||
} | ||
return asciidoctor.load(file.contents.toString(), options) | ||
return config | ||
} | ||
function isExtensionRegistered (ext, registry) { | ||
return ( | ||
registry.groups && | ||
global.Opal.hash(registry.groups) | ||
.$values() | ||
.includes(ext) | ||
) | ||
} | ||
module.exports = loadAsciiDoc | ||
module.exports.resolveConfig = resolveConfig |
{ | ||
"name": "@antora/asciidoc-loader", | ||
"version": "1.0.0-alpha.6", | ||
"version": "1.0.0-alpha.7", | ||
"description": "Loads AsciiDoc content into an Asciidoctor Document object (AST) for use in an Antora documentation pipeline.", | ||
@@ -18,3 +18,3 @@ "license": "MPL-2.0", | ||
"dependencies": { | ||
"asciidoctor.js": "^1.5.6-preview.4" | ||
"asciidoctor.js": "^1.5.6-preview.5" | ||
}, | ||
@@ -21,0 +21,0 @@ "engines": { |
@@ -12,3 +12,3 @@ # Antora AsciiDoc Loader | ||
* Automatic resolution of paths to images and attachments. | ||
* Inherent document attributes that reflect the Antora environment. | ||
* Implicit document attributes that pass information from the Antora environment. | ||
@@ -15,0 +15,0 @@ [Antora](https://antora.org) is a modular static site generator designed for creating documentation sites from AsciiDoc documents. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25542
575
3