1
0
Files
world/book/node_modules/@asciidoctor/cli/lib/invoker.js
2025-05-12 05:38:44 +09:00

152 lines
5.1 KiB
JavaScript

const fs = require('fs')
const ospath = require('path')
const asciidoctor = require('@asciidoctor/core')()
const pkg = require('../package.json')
const stdin = require('./stdin')
const DOT_RELATIVE_RX = new RegExp(`^\\.{1,2}[/${ospath.sep.replace('/', '').replace('\\', '\\\\')}]`)
class Invoker {
constructor (options) {
this.options = options
}
async invoke () {
const processArgs = this.options.argv.slice(2)
const { args } = this.options
const { verbose, version, files } = args
if (version || (verbose && processArgs.length === 1)) {
this.showVersion()
process.exit(0)
}
Invoker.prepareProcessor(args, asciidoctor)
const options = this.options.options
const failureLevel = options.failure_level
if (this.options.stdin) {
await Invoker.convertFromStdin(options, args)
Invoker.exit(failureLevel)
} else if (files && files.length > 0) {
Invoker.processFiles(files, verbose, args.timings, options)
Invoker.exit(failureLevel)
} else {
this.showHelp()
process.exit(0)
}
}
showHelp () {
if (this.options.args.help === 'syntax') {
console.log(fs.readFileSync(ospath.join(__dirname, '..', 'data', 'reference', 'syntax.adoc'), 'utf8'))
} else {
this.options.yargs.showHelp()
}
}
showVersion () {
console.log(this.version())
}
version () {
const releaseName = process.release ? process.release.name : 'node'
return `Asciidoctor.js ${asciidoctor.getVersion()} (Asciidoctor ${asciidoctor.getCoreVersion()}) [https://asciidoctor.org]
Runtime Environment (${releaseName} ${process.version} on ${process.platform})
CLI version ${pkg.version}`
}
/**
* @deprecated Use {#showVersion}. Will be removed in version 4.0.
*/
static printVersion () {
console.log(new Invoker().version())
}
static async readFromStdin () {
return stdin.read()
}
static async convertFromStdin (options, args) {
const data = await Invoker.readFromStdin()
if (args.timings) {
const timings = asciidoctor.Timings.create()
const instanceOptions = Object.assign({}, options, { timings })
Invoker.convert(asciidoctor.convert, data, instanceOptions)
timings.printReport(process.stderr, '-')
} else {
Invoker.convert(asciidoctor.convert, data, options)
}
}
static convert (processorFn, input, options) {
try {
processorFn.apply(asciidoctor, [input, options])
} catch (e) {
if (e && e.name === 'NotImplementedError' && e.message === `asciidoctor: FAILED: missing converter for backend '${options.backend}'. Processing aborted.`) {
console.error(`> Error: missing converter for backend '${options.backend}'. Processing aborted.`)
console.error('> You might want to require a Node.js package with --require option to support this backend.')
process.exit(1)
}
throw e
}
}
static convertFile (file, options) {
Invoker.convert(asciidoctor.convertFile, file, options)
}
static processFiles (files, verbose, timings, options) {
files.forEach((file) => {
if (verbose) {
console.log(`converting file ${file}`)
}
if (timings) {
const timings = asciidoctor.Timings.create()
const instanceOptions = Object.assign({}, options, { timings })
Invoker.convertFile(file, instanceOptions)
timings.printReport(process.stderr, file)
} else {
Invoker.convertFile(file, options)
}
})
}
static requireLibrary (requirePath, cwd = process.cwd()) {
if (requirePath.charAt(0) === '.' && DOT_RELATIVE_RX.test(requirePath)) {
// NOTE require resolves a dot-relative path relative to current file; resolve relative to cwd instead
requirePath = ospath.resolve(requirePath)
} else if (!ospath.isAbsolute(requirePath)) {
// NOTE appending node_modules prevents require from looking elsewhere before looking in these paths
const paths = [cwd, ospath.dirname(__dirname)].map((start) => ospath.join(start, 'node_modules'))
requirePath = require.resolve(requirePath, { paths })
}
return require(requirePath)
}
static prepareProcessor (argv, asciidoctor) {
const requirePaths = argv.require
if (requirePaths) {
requirePaths.forEach((requirePath) => {
const lib = Invoker.requireLibrary(requirePath)
if (lib && typeof lib.register === 'function') {
// REMIND: it could be an extension or a converter.
// the register function on a converter does not take any argument
// but the register function on an extension expects one argument (the extension registry)
// Until we revisit the API for extension and converter, we pass the registry as the first argument
lib.register(asciidoctor.Extensions)
}
})
}
}
static exit (failureLevel) {
let code = 0
const logger = asciidoctor.LoggerManager.getLogger()
if (logger && typeof logger.getMaxSeverity === 'function' && logger.getMaxSeverity() && logger.getMaxSeverity() >= failureLevel) {
code = 1
}
process.exit(code)
}
}
module.exports = Invoker
module.exports.asciidoctor = asciidoctor