123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- 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
|