Skip to content

Commit

Permalink
Resolves #35, automatically register converter and extension
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Apr 6, 2019
1 parent 362ad43 commit 11a10fc
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 7 deletions.
41 changes: 35 additions & 6 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

const yargs = require('yargs')
const fs = require('fs')
const path = require('path')
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('\\', '\\\\')}]`)

function convertOptions (args) {
const backend = args['backend']
const doctype = args['doctype']
Expand Down Expand Up @@ -46,9 +48,6 @@ function convertOptions (args) {
console.log('base-dir ' + baseDir)
console.log('destination-dir ' + destinationDir)
}
if (requireLib) {
require(requireLib)
}
const verboseMode = quiet ? 0 : verbose ? 2 : 1
const attributes = []
if (sectionNumbers) {
Expand Down Expand Up @@ -271,6 +270,34 @@ function processFiles (files, verbose, timings, options) {
process.exit(code)
}

function 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)
}

function prepareProcessor (argv, asciidoctor) {
const requirePaths = argv['require']
if (requirePaths) {
requirePaths.forEach(function (requirePath) {
const lib = 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)
}
})
}
}

function run (argv) {
const processArgs = argv.slice(2)
const args = argsParser().parse(processArgs)
Expand All @@ -282,6 +309,7 @@ function run (argv) {
args['out-file'] = args['out-file'] || '-'
}
const options = convertOptions(args)
prepareProcessor(args, asciidoctor)
if (stdin) {
convertFromStdin(options, args)
} else if (version || (verbose && files && files.length === 0)) {
Expand All @@ -293,7 +321,7 @@ function run (argv) {
processFiles(files, verbose, args['timings'], options)
} else {
if (args['help'] === 'syntax') {
console.log(fs.readFileSync(path.join(__dirname, '..', 'data', 'reference', 'syntax.adoc'), 'utf8'))
console.log(fs.readFileSync(ospath.join(__dirname, '..', 'data', 'reference', 'syntax.adoc'), 'utf8'))
} else {
yargs.showHelp()
}
Expand All @@ -305,5 +333,6 @@ module.exports = {
argsParser: argsParser,
convertOptions: convertOptions,
processFiles: processFiles,
processor: asciidoctor
processor: asciidoctor,
prepareProcessor: prepareProcessor
}
9 changes: 9 additions & 0 deletions test/fixtures/blog-converter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class BlogConverter {
convert () {
return '<blog></blog>';
}
}

module.exports.register = function register () {
Opal.Asciidoctor.ConverterFactory.register(new BlogConverter(), ['blog']);
}
20 changes: 20 additions & 0 deletions test/fixtures/shout-ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const shoutBlock = function () {
const self = this
self.named('shout')
self.onContext('paragraph')
self.process(function (parent, reader) {
const lines = reader.getLines().map(l => l.toUpperCase())
return self.createBlock(parent, 'paragraph', lines)
})
}

module.exports.register = function register (registry) {
if (typeof registry.register === 'function') {
registry.register(function () {
this.block(shoutBlock)
})
} else if (typeof registry.block === 'function') {
registry.block(shoutBlock)
}
return registry
}
28 changes: 27 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const dirtyChai = require('dirty-chai')
chai.use(dirtyChai)

const stdin = require('../lib/stdin')
const { run, processor, convertOptions, processFiles } = require('../lib/cli.js')
const { run, processor, convertOptions, processFiles, prepareProcessor } = require('../lib/cli.js')
const argsParser = require('../lib/cli.js').argsParser()

describe('Arguments parser', () => {
Expand Down Expand Up @@ -182,3 +182,29 @@ describe('Process files', () => {
}
})
})

describe('Require option', () => {
it('should require an extension library', () => {
const asciidoctor = require('@asciidoctor/core')()
try {
expect(Object.keys(asciidoctor.Extensions.getGroups()).length).to.equal(0)
prepareProcessor(argsParser.parse('one.adoc -r ./test/fixtures/shout-ext.js'), asciidoctor)
expect(Object.keys(asciidoctor.Extensions.getGroups()).length).to.equal(1)
} finally {
asciidoctor.Extensions.unregisterAll()
}
})

it('should require a converter library', () => {
const asciidoctor = require('@asciidoctor/core')()
try {
asciidoctor.convert('Hello', { backend: 'blog' })
expect.fail('blog backend should be missing')
} catch (e) {
expect(e.message).to.equal('asciidoctor: FAILED: missing converter for backend \'blog\'. Processing aborted.')
}
prepareProcessor(argsParser.parse('one.adoc -r ./test/fixtures/blog-converter.js'), asciidoctor)
const html = asciidoctor.convert('Hello', { backend: 'blog' })
expect(html).to.equal('<blog></blog>')
})
})

0 comments on commit 11a10fc

Please sign in to comment.