Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #12, replace cli by yargs #32

Merged
merged 2 commits into from
Apr 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bin/asciidoctorjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
'use strict'

process.title = 'asciidoctorjs'
require('../lib/cli.js')()
const cli = require('../lib/cli.js')
const argv = cli.argsParser().argv
cli.run(argv)
245 changes: 168 additions & 77 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,55 @@
/* global Opal */
'use strict'

const cli = require('cli').enable('status')
const yargs = require('yargs')
const asciidoctor = require('asciidoctor.js')()

function convertOptions (cliOptions) {
const backend = cliOptions['backend']
const doctype = cliOptions['doctype']
const safeMode = cliOptions['safe-mode']
const noHeaderFooter = cliOptions['no-header-footer']
const sectionNumbers = cliOptions['section-numbers']
const baseDir = cliOptions['base-dir']
const destinationDir = cliOptions['destination-dir']
const outFile = cliOptions['out-file']
const quiet = cliOptions['quiet']
const verbose = cliOptions['verbose']
const timings = cliOptions['timings']
const trace = cliOptions['trace']
const requireLib = cliOptions['require']
cli.debug('require ' + requireLib)
cli.debug('backend ' + backend)
cli.debug('doctype ' + doctype)
cli.debug('header_footer ' + !noHeaderFooter)
cli.debug('section-numbers ' + sectionNumbers)
cli.debug('quiet ' + quiet)
cli.debug('verbose ' + verbose)
cli.debug('timings ' + timings)
cli.debug('trace ' + trace)
cli.debug('baseDir ' + baseDir)
cli.debug('destinationDir ' + destinationDir)
function convertOptions (argv) {
const backend = argv['backend']
const doctype = argv['doctype']
const safeMode = argv['safe-mode']
const noHeaderFooter = argv['no-header-footer']
const sectionNumbers = argv['section-numbers']
const baseDir = argv['base-dir']
const destinationDir = argv['destination-dir']
const outFile = argv['out-file']
const quiet = argv['quiet']
const verbose = argv['verbose']
const timings = argv['timings']
const trace = argv['trace']
const requireLib = argv['require']
if (verbose) {
console.log('require ' + requireLib)
console.log('backend ' + backend)
console.log('doctype ' + doctype)
console.log('header-footer ' + !noHeaderFooter)
console.log('section-numbers ' + sectionNumbers)
console.log('quiet ' + quiet)
console.log('verbose ' + verbose)
console.log('timings ' + timings)
console.log('trace ' + trace)
console.log('base-dir ' + baseDir)
console.log('destination-dir ' + destinationDir)
}
if (requireLib) {
require(requireLib)
}
const verboseMode = quiet ? 0 : verbose ? 2 : 1
let attributes = ''
const attributes = []
if (noHeaderFooter) {
attributes = 'showtitle '
attributes.push('showtitle')
}
if (sectionNumbers) {
attributes = attributes.concat('sectnums ')
attributes.push('sectnums')
}
const cliAttributes = cliOptions['attribute']
const cliAttributes = argv['attribute']
if (cliAttributes) {
attributes = attributes.concat(cliAttributes)
attributes.push(...cliAttributes)
}
if (verbose) {
console.log('verbose-mode ' + verboseMode)
console.log('attributes ' + attributes)
}
cli.debug('verboseMode ' + verboseMode)
cli.debug('attributes ' + attributes)
const options = {
backend: backend,
doctype: doctype,
Expand All @@ -67,56 +71,143 @@ function convertOptions (cliOptions) {
options.mkdirs = true
}
options.attributes = attributes
cli.debug('options ' + JSON.stringify(options))
if (verbose) {
console.log('options ' + JSON.stringify(options))
}
if (options.to_file === '-') {
options.to_file = Opal.gvars.stdout
}
return options
}

function run () {
cli.parse({
'backend': ['b', 'set output format backend (default: html5)', 'string', 'html5'],
'doctype': ['d', 'document type to use when converting document: [article, book, manpage, inline] (default: article)', 'string', 'article'],
'out-file': ['o', 'output file (default: based on path of input file) use \'\' to output to STDOUT', 'file'],
'safe-mode': ['S', 'set safe mode level explicitly: [unsafe, safe, server, secure] (default: unsafe)), disables potentially dangerous macros in source files, such as include::[]', 'string', 'unsafe'],
'no-header-footer': ['s', 'suppress output of header and footer (default: false)', 'boolean', false],
'section-numbers': ['n', 'auto-number section titles in the HTML backend disabled by default', 'boolean', false],
'base-dir': ['B', 'base directory containing the document and resources (default: directory of source file)', 'path'],
'destination-dir': ['D', 'destination output directory (default: directory of source file)', 'path'],
'quiet': ['q', 'suppress warnings (default: false)', 'boolean', 'false'],
'trace': [false, 'include backtrace information on errors (default: false)', 'boolean', false],
'verbose': ['v', 'enable verbose mode (default: false)', 'boolean', false],
'timings': ['t', 'enable timings mode (default: false)', 'boolean', false],
'attribute': ['a', 'a document attribute to set in the form of key, key! or key=value pair', 'string', ''],
'require': ['r', 'require the specified library before executing the processor, using the standard Node require', 'string', ''],
'version': ['V', 'display the version and runtime environment (or -v if no other flags or arguments)', 'boolean', false]
})
function argsParser () {
return yargs
.detectLocale(false)
.wrap(Math.min(120, yargs.terminalWidth()))
.command('$0 [files...]', '', function (yargs) {
return yargs
.option('backend', {
alias: 'b',
default: 'html5',
describe: 'set output format backend',
type: 'string'
})
.option('doctype', {
alias: 'd',
default: 'article',
describe: 'document type to use when converting document',
choices: ['article', 'book', 'manpage', 'inline']
})
.option('out-file', {
alias: 'o',
describe: 'output file (default: based on path of input file) use \'\' to output to STDOUT',
type: 'string'
})
.option('safe-mode', {
alias: 'S',
default: 'unsafe',
describe: 'set safe mode level explicitly, disables potentially dangerous macros in source files, such as include::[]',
choices: ['unsafe', 'safe', 'server', 'secure']
})
.option('no-header-footer', {
alias: 's',
default: false,
describe: 'suppress output of header and footer',
type: 'boolean'
})
.option('section-numbers', {
alias: 'n',
default: false,
describe: 'auto-number section titles in the HTML backend disabled by default',
type: 'boolean'
})
.option('base-dir', {
// QUESTION: should we check that the directory exists ? coerce to a directory ?
alias: 'B',
describe: 'base directory containing the document and resources (default: directory of source file)',
type: 'string'
})
.option('destination-dir', {
// QUESTION: should we check that the directory exists ? coerce to a directory ?
alias: 'D',
describe: 'destination output directory (default: directory of source file)',
type: 'string'
})
.option('quiet', {
alias: 'q',
default: false,
describe: 'suppress warnings',
type: 'boolean'
})
.option('trace', {
default: false,
describe: 'include backtrace information on errors',
type: 'boolean'
})
.option('verbose', {
alias: 'v',
default: false,
describe: 'enable verbose mode',
type: 'boolean'
})
.option('timings', {
alias: 't',
default: false,
describe: 'enable timings mode',
type: 'boolean'
})
.option('attribute', {
alias: 'a',
array: true,
describe: 'a document attribute to set in the form of key, key! or key=value pair',
type: 'string'
})
.option('require', {
alias: 'r',
array: true,
describe: 'require the specified library before executing the processor, using the standard Node require',
type: 'string'
})
.option('version', {
alias: 'V',
default: false,
describe: 'display the version and runtime environment (or -v if no other flags or arguments)',
type: 'boolean'
})
})
.help()
}

cli.main(function (cliArgs, cliOptions) {
const options = convertOptions(cliOptions)
const verbose = cliOptions['verbose']
const version = cliOptions['version']
if (version || (verbose && cliArgs.length === 0)) {
cli.info(`Asciidoctor ${asciidoctor.getCoreVersion()} [http://asciidoctor.org]`)
const releaseName = process.release ? process.release.name : 'node'
cli.info(`Runtime Environment (${releaseName} ${process.version} on ${process.platform})`)
} else if (cliArgs.length) {
cliArgs.forEach(function (file) {
cli.debug('converting file ' + file)
if (options.timings) {
const timings = asciidoctor.Timings.$new()
const instanceOptions = Object.assign({}, options, {timings: timings})
asciidoctor.convertFile(file, instanceOptions)
timings.$print_report(Opal.gvars.stderr, file)
} else {
asciidoctor.convertFile(file, options)
}
})
} else {
cli.getUsage()
}
})
function run (argv) {
const verbose = argv['verbose']
const version = argv['version']
const files = argv['files']
const options = convertOptions(argv)
if (version || (verbose && files && files.length === 0)) {
console.log(`Asciidoctor ${asciidoctor.getCoreVersion()} [http://asciidoctor.org]`)
const releaseName = process.release ? process.release.name : 'node'
console.log(`Runtime Environment (${releaseName} ${process.version} on ${process.platform})`)
} else if (files && files.length > 0) {
files.forEach(function (file) {
if (verbose) {
console.log(`converting file ${file}`)
}
if (argv['timings']) {
const timings = asciidoctor.Timings.$new()
const instanceOptions = Object.assign({}, options, {timings: timings})
asciidoctor.convertFile(file, instanceOptions)
timings.$print_report(Opal.gvars.stderr, file)
} else {
asciidoctor.convertFile(file, options)
}
})
} else {
yargs.showHelp()
}
}

module.exports = run
module.exports = {
run: run,
argsParser: argsParser,
convertOptions: convertOptions
}
Loading