Comparing version 0.2.0 to 0.3.0
496
cli.js
@@ -8,152 +8,103 @@ #!/usr/bin/env node | ||
var mdast, | ||
fs, | ||
path, | ||
pack; | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
var commander = require('commander'); | ||
var debug = require('debug')('mdast'); | ||
var mdast = require('./'); | ||
var pack = require('./package.json'); | ||
mdast = require('./'); | ||
fs = require('fs'); | ||
path = require('path'); | ||
pack = require('./package.json'); | ||
/* | ||
* Cached methods. | ||
* Shortcuts. | ||
*/ | ||
var resolve, | ||
exists; | ||
var Command = commander.Command; | ||
var exists = fs.existsSync || path.existsSync; | ||
var resolve = path.resolve; | ||
var join = path.join; | ||
var read = fs.readFile; | ||
var write = fs.writeFile; | ||
var stdout = process.stdout; | ||
var stdin = process.stdin; | ||
var stderr = process.stderr; | ||
resolve = path.resolve; | ||
exists = fs.existsSync; | ||
/* | ||
* Current working directory. | ||
* Constants. | ||
*/ | ||
var cwd; | ||
var SPLITTER = / *[,;] */g; | ||
var DELIMITER = / *: */g; | ||
cwd = process.cwd(); | ||
var ENCODING = 'utf-8'; | ||
/* | ||
* Detect if a value is expected to be piped in. | ||
*/ | ||
var cwd = process.cwd(); | ||
var expextPipeIn = !stdin.isTTY; | ||
var seperator = path.sep; | ||
var expextPipeIn; | ||
var command = Object.keys(pack.bin)[0]; | ||
expextPipeIn = !process.stdin.isTTY; | ||
/** | ||
* Fail with `message` to stderr and exit with `1`. | ||
* | ||
* Throwing an error in node@0.10 might cause an exit | ||
* code of `8` for file operations. | ||
* | ||
* @param {Error|string} message | ||
*/ | ||
function fail(message) { | ||
stderr.write(message + '\n'); | ||
process.exit(1); | ||
} | ||
/* | ||
* Arguments. | ||
/** | ||
* Find root of node modules. | ||
* | ||
* @return {string} | ||
*/ | ||
function findRoot() { | ||
var parts = cwd.split(seperator); | ||
var location = cwd; | ||
var argv; | ||
while (!exists(join(location, 'package.json')) && parts.length > 1) { | ||
parts.pop(); | ||
location = parts.join(seperator); | ||
} | ||
argv = process.argv.slice(2); | ||
return parts.length ? location : cwd; | ||
} | ||
/* | ||
* Command. | ||
* Root. | ||
*/ | ||
var command; | ||
var root = findRoot(); | ||
command = Object.keys(pack.bin)[0]; | ||
/** | ||
* Help. | ||
* Find a plugin. | ||
* | ||
* @return {string} | ||
* @param {string} pathlike | ||
* @return {Object} | ||
*/ | ||
function help() { | ||
return [ | ||
'', | ||
'Usage: ' + command + ' [options] file', | ||
'', | ||
pack.description, | ||
'', | ||
'Options:', | ||
'', | ||
' -h, --help output usage information', | ||
' -v, --version output version number', | ||
' -a, --ast output AST information', | ||
' --options output available settings', | ||
' -o, --output <path> specify output location', | ||
' -O, --option <option> specify settings', | ||
' -u, --use <plugin> specify plugins', | ||
'', | ||
'Usage:', | ||
'', | ||
'# Note that bash does not allow reading and writing to the', | ||
'# same file through pipes', | ||
'', | ||
'# Pass `Readme.md` through mdast', | ||
'$ ' + command + ' Readme.md -o Readme.md', | ||
'', | ||
'# Pass stdin through mdast, with options, to stdout', | ||
'$ cat Readme.md | ' + command + ' --option ' + | ||
'"setext, bullet: *" > Readme-new.md', | ||
'', | ||
'# Use an npm module', | ||
'$ npm install some-plugin', | ||
'$ ' + command + ' --use some-plugin History.md > History-new.md' | ||
].join('\n ') + '\n'; | ||
} | ||
function find(pathlike) { | ||
var local = resolve(root, pathlike); | ||
var npm = resolve(root, 'node_modules', pathlike); | ||
var current = resolve(cwd, 'node_modules', pathlike); | ||
var plugin; | ||
/** | ||
* Fail w/ `exception`. | ||
* | ||
* @param {null|string|Error} exception | ||
*/ | ||
function fail(exception) { | ||
if (!exception) { | ||
exception = help(); | ||
if (exists(local) || exists(local + '.js')) { | ||
plugin = local; | ||
} else if (exists(npm)) { | ||
plugin = npm; | ||
} else if (exists(current)) { | ||
plugin = current; | ||
} | ||
process.stderr.write((exception.stack || exception) + '\n'); | ||
debug('Using plugin `%s` at `%s`', pathlike, plugin); | ||
process.exit(1); | ||
} | ||
try { | ||
plugin = require(plugin); | ||
} catch (exception) { | ||
fail(exception); | ||
} | ||
/** | ||
* Log available options. | ||
* | ||
* @return {string} | ||
*/ | ||
function getOptions() { | ||
return [ | ||
'', | ||
'# Options', | ||
'', | ||
'Both camel- and dash-cased options are allowed.', | ||
'', | ||
'## [Parse](https://github.com/wooorm/mdast#mdastparsevalue-options)', | ||
'', | ||
'- `gfm` (boolean, default: true)', | ||
'- `tables` (boolean, default: true)', | ||
'- `pedantic` (boolean, default: false)', | ||
'- `breaks` (boolean, default: false)', | ||
'- `footnotes` (boolean, default: false)', | ||
'', | ||
'## [Stringify](https://github.com/wooorm/mdast#' + | ||
'mdaststringifyast-options)', | ||
'', | ||
'- `setext` (boolean, default: false)', | ||
'- `closeAtx` (boolean, default: false)', | ||
'- `reference-links` (boolean, default: false)', | ||
'- `reference-footnotes` (boolean, default: true)', | ||
'- `fences` (boolean, default: false)', | ||
'- `bullet` ("-", "*", or "+", default: "-")', | ||
'- `rule` ("-", "*", or "_", default: "*")', | ||
'- `rule-repetition` (number, default: 3)', | ||
'- `rule-spaces` (boolean, default: false)', | ||
'- `strong` ("_", or "*", default: "*")', | ||
'- `emphasis` ("_", or "*", default: "_")', | ||
'', | ||
'Settings are specified as follows:', | ||
'', | ||
'```', | ||
'$ ' + command + ' --option "some-option:some-value"', | ||
'# Multiple options:', | ||
'$ ' + command + ' --option "emphasis:*,strong:_"', | ||
'```' | ||
].join('\n ') + '\n'; | ||
return plugin; | ||
} | ||
@@ -173,162 +124,187 @@ | ||
/* | ||
* Program. | ||
/** | ||
* Parse settings into an object. | ||
* | ||
* @param {string} flags | ||
* @param {Object} cache | ||
* @return {Object} | ||
*/ | ||
function settings(flags, cache) { | ||
flags.split(SPLITTER).forEach(function (flag) { | ||
var value; | ||
var index, | ||
expectOption, | ||
expectPlugin, | ||
expectOutput, | ||
expectAST, | ||
plugins, | ||
options, | ||
output, | ||
files; | ||
flag = flag.split(DELIMITER); | ||
plugins = []; | ||
value = flag[1]; | ||
if (value === 'true' || value === undefined) { | ||
value = true; | ||
} else if (value === 'false') { | ||
value = false; | ||
} else if (Number(value) === Number(value)) { | ||
value = Number(value); | ||
} | ||
cache[camelCase(flag[0])] = value; | ||
}); | ||
return cache; | ||
} | ||
/** | ||
* Run the program. | ||
* Parse plugins into a list. | ||
* | ||
* @param {string} value | ||
* @param {string} ware | ||
* @param {Array.<string>} cache | ||
* @return {Array.<string>} | ||
*/ | ||
function program(value) { | ||
var doc, | ||
parser, | ||
local, | ||
fn; | ||
function plugins(ware, cache) { | ||
return cache.concat(ware.split(SPLITTER)); | ||
} | ||
if (!value.length) { | ||
fail(); | ||
} else { | ||
parser = mdast; | ||
/** | ||
* Command. | ||
*/ | ||
plugins.forEach(function (plugin) { | ||
local = resolve(cwd, plugin); | ||
var program = new Command(pack.name) | ||
.version(pack.version) | ||
.description(pack.description) | ||
.usage('[options] file') | ||
.option('-o, --output <path>', 'specify output location', null) | ||
.option('-s, --setting <settings>', 'specify settings', settings, {}) | ||
.option('-u, --use <plugins>', 'use transform plugin(s)', plugins, []) | ||
.option('-a, --ast', 'output AST information', false) | ||
.option('--settings', 'output available settings', false); | ||
if (exists(local) || exists(local + '.js')) { | ||
fn = require(local); | ||
} else { | ||
try { | ||
fn = require(resolve(cwd, 'node_modules', plugin)); | ||
} catch (exception) { | ||
fail(exception); | ||
} | ||
} | ||
/** | ||
* Help. | ||
*/ | ||
parser = parser.use(fn); | ||
}); | ||
program.on('--help', function () { | ||
console.log(' # Note that bash does not allow reading and writing'); | ||
console.log(' # to the same file through pipes'); | ||
console.log(); | ||
console.log(' Usage:'); | ||
console.log(); | ||
console.log(' # Pass `Readme.md` through mdast'); | ||
console.log(' $ ' + command + ' Readme.md -o Readme.md'); | ||
console.log(); | ||
console.log(' # Pass stdin through mdast, with settings, to stdout'); | ||
console.log(' $ cat Readme.md | ' + command + ' --setting ' + | ||
'"setext, bullet: *" > Readme-new.md'); | ||
console.log(); | ||
console.log(' # use a plugin'); | ||
console.log(' $ npm install mdast-toc'); | ||
console.log(' $ ' + command + ' --use mdast-toc -o Readme.md'); | ||
console.log(); | ||
}); | ||
doc = parser.parse(value, options); | ||
program.on('--settings', function () { | ||
console.log(); | ||
console.log(' # Settings'); | ||
console.log(); | ||
console.log(' Both camel- and dash-cased settings are allowed.'); | ||
console.log(); | ||
console.log(' ## [Parse](https://github.com/wooorm/mdast#' + | ||
'mdastparsevalue-options)'); | ||
console.log(); | ||
console.log(' - `gfm` (boolean, default: true)'); | ||
console.log(' - `tables` (boolean, default: true)'); | ||
console.log(' - `yaml` (boolean, default: true)'); | ||
console.log(' - `pedantic` (boolean, default: false)'); | ||
console.log(' - `breaks` (boolean, default: false)'); | ||
console.log(' - `footnotes` (boolean, default: false)'); | ||
console.log(); | ||
console.log(' ## [Stringify](https://github.com/wooorm/mdast#' + | ||
'mdaststringifyast-options)'); | ||
console.log(); | ||
console.log(' - `setext` (boolean, default: false)'); | ||
console.log(' - `close-atx` (boolean, default: false)'); | ||
console.log(' - `loose-table` (boolean, default: false)'); | ||
console.log(' - `spaced-table` (boolean, default: true)'); | ||
console.log(' - `reference-links` (boolean, default: false)'); | ||
console.log(' - `reference-footnotes` (boolean, default: true)'); | ||
console.log(' - `fences` (boolean, default: false)'); | ||
console.log(' - `bullet` ("-", "*", or "+", default: "-")'); | ||
console.log(' - `rule` ("-", "*", or "_", default: "*")'); | ||
console.log(' - `rule-repetition` (number, default: 3)'); | ||
console.log(' - `rule-spaces` (boolean, default: false)'); | ||
console.log(' - `strong` ("_", or "*", default: "*")'); | ||
console.log(' - `emphasis` ("_", or "*", default: "_")'); | ||
console.log(); | ||
console.log(' Settings are specified as follows:'); | ||
console.log(); | ||
console.log(' $ ' + command + ' --setting "name:value"'); | ||
console.log(); | ||
console.log(' Multiple settings:'); | ||
console.log(); | ||
console.log(' $ ' + command + ' --setting "emphasis:*,strong:_"'); | ||
console.log(); | ||
}); | ||
if (expectAST) { | ||
doc = JSON.stringify(doc, null, 2); | ||
} else { | ||
doc = mdast.stringify(doc, options); | ||
} | ||
program.parse(process.argv); | ||
if (output) { | ||
fs.writeFile(output, doc, function (exception) { | ||
if (exception) { | ||
fail(exception); | ||
} | ||
}); | ||
} else { | ||
process.stdout.write(doc); | ||
} | ||
} | ||
} | ||
/* | ||
* Program. | ||
*/ | ||
if ( | ||
argv.indexOf('--help') !== -1 || | ||
argv.indexOf('-h') !== -1 | ||
) { | ||
console.log(help()); | ||
} else if ( | ||
argv.indexOf('--version') !== -1 || | ||
argv.indexOf('-v') !== -1 | ||
) { | ||
console.log(pack.version); | ||
} else if ( | ||
argv.indexOf('--options') !== -1 | ||
) { | ||
console.log(getOptions()); | ||
} else { | ||
index = argv.indexOf('--ast'); | ||
debug('Using root: `%s`', root); | ||
if (index === -1) { | ||
index = argv.indexOf('-a'); | ||
} | ||
var parser = mdast; | ||
if (index !== -1) { | ||
expectAST = true; | ||
argv.splice(index, 1); | ||
} | ||
program.use.forEach(function (pathlike) { | ||
parser = parser.use(find(pathlike)); | ||
}); | ||
files = []; | ||
options = {}; | ||
/** | ||
* Parse `value` with `parser`. When `ast` is set, | ||
* pretty prints JSON, otherwise stringifies with | ||
* `parser`. Either write to `output` or to stdout. | ||
* | ||
* @param {string} value | ||
*/ | ||
function run(value) { | ||
debug('Using options `%j`', program.setting); | ||
argv.forEach(function (argument) { | ||
if (argument === '--option' || argument === '-O') { | ||
expectOption = true; | ||
} else if (argument === '--use' || argument === '-u') { | ||
expectPlugin = true; | ||
} else if (argument === '--output' || argument === '-o') { | ||
expectOutput = true; | ||
} else if (expectPlugin) { | ||
argument.split(',').forEach(function (plugin) { | ||
plugins.push(plugin); | ||
}); | ||
try { | ||
var doc = parser.parse(value, program.setting); | ||
} catch (exception) { | ||
fail(exception); | ||
} | ||
expectPlugin = false; | ||
} else if (expectOutput) { | ||
output = argument; | ||
if (program.ast) { | ||
doc = JSON.stringify(doc, null, 2); | ||
} else { | ||
doc = parser.stringify(doc, program.setting); | ||
} | ||
expectOutput = false; | ||
} else if (expectOption) { | ||
argument | ||
.split(',') | ||
.map(function (value) { | ||
var values; | ||
if (program.output) { | ||
debug('Writing document to `%s`', program.output); | ||
values = value.split(':'); | ||
write(program.output, doc, function (exception) { | ||
if (exception) { | ||
fail(exception); | ||
} | ||
}); | ||
} else { | ||
debug('Writing document to standard out'); | ||
return [ | ||
camelCase(values.shift().trim()), | ||
values.join(':').trim() | ||
]; | ||
}) | ||
.map(function (values) { | ||
var value; | ||
stdout.write(doc); | ||
} | ||
} | ||
value = values[1]; | ||
var files = program.args; | ||
if (value === 'true') { | ||
value = true; | ||
} else if (value === 'false') { | ||
value = false; | ||
} else if (value === '') { | ||
value = true; | ||
} else if (Number(value) === Number(value)) { | ||
value = Number(value); | ||
} | ||
if (program.settings) { | ||
program.emit('--settings'); | ||
} else { | ||
if (!expextPipeIn && !files.length) { | ||
if (program.output) { | ||
debug('Using output `%s` as input', program.output); | ||
values[1] = value; | ||
return values; | ||
}) | ||
.forEach(function (values) { | ||
options[values[0]] = values[1]; | ||
}); | ||
expectOption = false; | ||
files.push(program.output); | ||
} else { | ||
files.push(argument); | ||
program.outputHelp(); | ||
process.exit(1); | ||
} | ||
}); | ||
if (expectOption || expectPlugin || expectOutput) { | ||
fail(); | ||
} else if (!expextPipeIn && !files.length) { | ||
fail(); | ||
} else if ( | ||
@@ -342,3 +318,5 @@ (expextPipeIn && files.length) || | ||
if (files[0]) { | ||
fs.readFile(files[0], function (exception, content) { | ||
debug('Reading from `%s` using encoding `%s`', files[0], ENCODING); | ||
read(files[0], ENCODING, function (exception, value) { | ||
if (exception) { | ||
@@ -348,11 +326,9 @@ fail(exception); | ||
program(content.toString()); | ||
run(value); | ||
}); | ||
} else { | ||
process.stdin.resume(); | ||
process.stdin.setEncoding('utf8'); | ||
process.stdin.on('data', program); | ||
stdin.resume(); | ||
stdin.setEncoding(ENCODING); | ||
stdin.on('data', run); | ||
} | ||
} |
@@ -0,1 +1,27 @@ | ||
0.3.0 / 2015-02-08 | ||
================== | ||
* Add man docs for mdast(1) | ||
* Refactor cli to use commander | ||
* Refactor to simplify options validation | ||
* Add support for YAML front matter | ||
* Update mdast, eslint as dev-dependencies | ||
* Replace file name underscores with dashes in `test/` | ||
* Fix option casing in `cli.js` | ||
* Merge branch 'feature/stringification/prefer-spaced-tables' | ||
* Add docs for `options.spacedTable` | ||
* Add support for `spacedTable` | ||
* Add tests for incorrect `spacedTable` option | ||
* Add fixtures for spaced table style | ||
* Merge branch 'feature/stringification/prefer-loose-tables' | ||
* Add docs for `options.looseTable` | ||
* Add support for `looseTable` | ||
* Add tests for incorrect `looseTable` option | ||
* Add fixtures for loose table style | ||
* Add auto inferring of input file if an output file is provided | ||
* Add `fence` parse option to `Readme.md` | ||
* Add `example.js` to `.npmignore`, `bower.json` ignore | ||
0.2.0 / 2015-02-02 | ||
@@ -2,0 +28,0 @@ ================== |
@@ -21,3 +21,4 @@ 'use strict'; | ||
trimRightLines, | ||
clean; | ||
clean, | ||
validate; | ||
@@ -29,2 +30,3 @@ copy = utilities.copy; | ||
clean = utilities.clean; | ||
validate = utilities.validate; | ||
@@ -362,2 +364,10 @@ /* | ||
/* | ||
* YAML front matter. | ||
*/ | ||
var yamlFrontMatter; | ||
yamlFrontMatter = /^-{3}\n([\s\S]+?\n)?-{3}/; | ||
/* | ||
* Inline-Level Grammar. | ||
@@ -714,2 +724,16 @@ */ | ||
/** | ||
* Tokenise YAML front matter. | ||
* | ||
* @property {boolean} onlyAtStart | ||
* @param {function(string)} eat | ||
* @param {string} $0 - Whole front matter. | ||
* @param {string} $1 - Content. | ||
*/ | ||
function tokenizeYAMLFrontMatter(eat, $0, $1) { | ||
eat($0)(this.renderRaw('yaml', $1 ? trimRightLines($1) : '')); | ||
} | ||
tokenizeYAMLFrontMatter.onlyAtStart = true; | ||
/** | ||
* Tokenise a footnote definition. | ||
@@ -1504,2 +1528,3 @@ * | ||
self.atTop = true; | ||
self.atStart = true; | ||
self.inBlockquote = false; | ||
@@ -1540,2 +1565,6 @@ | ||
if (options.yaml) { | ||
blockRules.yamlFrontMatter = yamlFrontMatter; | ||
} | ||
if (options.footnotes) { | ||
@@ -1675,2 +1704,3 @@ blockRules.footnoteDefinition = footnoteDefinition; | ||
Parser.prototype.blockTokenizers = { | ||
'yamlFrontMatter': tokenizeYAMLFrontMatter, | ||
'newline': tokenizeNewline, | ||
@@ -1698,2 +1728,3 @@ 'code': tokenizeCode, | ||
Parser.prototype.blockMethods = [ | ||
'yamlFrontMatter', | ||
'newline', | ||
@@ -1884,2 +1915,6 @@ 'code', | ||
if (self.atStart && tokens.length) { | ||
self.exitStart(); | ||
} | ||
return token; | ||
@@ -1941,2 +1976,3 @@ } | ||
match = rules[name] && | ||
(!method.onlyAtStart || self.atStart) && | ||
(!method.onlyAtTop || self.atTop) && | ||
@@ -2075,2 +2111,3 @@ (!method.notInBlockquote || !self.inBlockquote) && | ||
Parser.prototype.exitTop = stateToggler('atTop', true); | ||
Parser.prototype.exitStart = stateToggler('atStart', true); | ||
Parser.prototype.enterBlockquote = stateToggler('inBlockquote', false); | ||
@@ -2087,8 +2124,2 @@ | ||
function parse(value, options, CustomParser) { | ||
var gfm, | ||
tables, | ||
footnotes, | ||
breaks, | ||
pedantic; | ||
if (typeof value !== 'string') { | ||
@@ -2106,47 +2137,16 @@ raise(value, 'value'); | ||
gfm = options.gfm; | ||
tables = options.tables; | ||
footnotes = options.footnotes; | ||
breaks = options.breaks; | ||
pedantic = options.pedantic; | ||
validate.bool(options, 'gfm', true); | ||
validate.bool(options, 'tables', options.gfm); | ||
validate.bool(options, 'yaml', true); | ||
validate.bool(options, 'footnotes', false); | ||
validate.bool(options, 'breaks', false); | ||
validate.bool(options, 'pedantic', false); | ||
if (gfm === null || gfm === undefined) { | ||
options.gfm = true; | ||
gfm = options.gfm; | ||
} else if (typeof gfm !== 'boolean') { | ||
raise(gfm, 'options.gfm'); | ||
} | ||
options.gfm = gfm; | ||
if (tables === null || tables === undefined) { | ||
options.tables = gfm; | ||
} else if (typeof tables !== 'boolean') { | ||
raise(tables, 'options.tables'); | ||
} else if (!gfm && tables) { | ||
if (!options.gfm && options.tables) { | ||
throw new Error( | ||
'Invalid value `' + tables + '` with ' + | ||
'`gfm: ' + gfm + '` for `options.tables`' | ||
'Invalid value `' + options.tables + '` with ' + | ||
'`gfm: ' + options.gfm + '` for `options.tables`' | ||
); | ||
} | ||
if (footnotes === null || footnotes === undefined) { | ||
options.footnotes = false; | ||
} else if (typeof footnotes !== 'boolean') { | ||
raise(footnotes, 'options.footnotes'); | ||
} | ||
if (breaks === null || breaks === undefined) { | ||
options.breaks = false; | ||
} else if (typeof breaks !== 'boolean') { | ||
raise(breaks, 'options.breaks'); | ||
} | ||
if (pedantic === null || pedantic === undefined) { | ||
options.pedantic = false; | ||
} else if (typeof pedantic !== 'boolean') { | ||
raise(pedantic, 'options.pedantic'); | ||
} | ||
return new (CustomParser || Parser)(options).parse(value); | ||
@@ -2153,0 +2153,0 @@ } |
@@ -19,3 +19,4 @@ 'use strict'; | ||
raise, | ||
trimLeft; | ||
trimLeft, | ||
validate; | ||
@@ -25,2 +26,3 @@ copy = utilities.copy; | ||
trimLeft = utilities.trimLeft; | ||
validate = utilities.validate; | ||
@@ -64,2 +66,3 @@ /* | ||
PARENTHESIS_CLOSE, | ||
PIPE, | ||
PLUS, | ||
@@ -87,2 +90,3 @@ QUOTE_DOUBLE, | ||
PARENTHESIS_CLOSE = ')'; | ||
PIPE = '|'; | ||
PLUS = '+'; | ||
@@ -255,14 +259,3 @@ QUOTE_DOUBLE = '"'; | ||
var self, | ||
bullet, | ||
rule, | ||
ruleSpaces, | ||
ruleRepetition, | ||
setext, | ||
referenceLinks, | ||
referenceFootnotes, | ||
fences, | ||
fence, | ||
emphasis, | ||
strong, | ||
closeAtx; | ||
ruleRepetition; | ||
@@ -283,88 +276,20 @@ self = this; | ||
bullet = options.bullet; | ||
rule = options.rule; | ||
ruleSpaces = options.ruleSpaces; | ||
validate.map(options, 'bullet', LIST_BULLETS, DASH); | ||
validate.map(options, 'rule', HORIZONTAL_RULE_BULLETS, ASTERISK); | ||
validate.map(options, 'emphasis', EMPHASIS_MARKERS, UNDERSCORE); | ||
validate.map(options, 'strong', EMPHASIS_MARKERS, ASTERISK); | ||
validate.map(options, 'fence', FENCE_MARKERS, TICK); | ||
validate.bool(options, 'ruleSpaces', true); | ||
validate.bool(options, 'setext', false); | ||
validate.bool(options, 'closeAtx', false); | ||
validate.bool(options, 'looseTable', false); | ||
validate.bool(options, 'spacedTable', true); | ||
validate.bool(options, 'referenceLinks', false); | ||
validate.bool(options, 'referenceFootnotes', true); | ||
validate.bool(options, 'fences', false); | ||
validate.num(options, 'ruleRepetition', 3); | ||
ruleRepetition = options.ruleRepetition; | ||
setext = options.setext; | ||
referenceLinks = options.referenceLinks; | ||
referenceFootnotes = options.referenceFootnotes; | ||
fences = options.fences; | ||
fence = options.fence; | ||
emphasis = options.emphasis; | ||
strong = options.strong; | ||
closeAtx = options.closeAtx; | ||
if (bullet === null || bullet === undefined) { | ||
options.bullet = DASH; | ||
} else if (!(bullet in LIST_BULLETS)) { | ||
raise(bullet, 'options.bullet'); | ||
} | ||
if (rule === null || rule === undefined) { | ||
options.rule = ASTERISK; | ||
} else if (!(rule in HORIZONTAL_RULE_BULLETS)) { | ||
raise(rule, 'options.rule'); | ||
} | ||
if (ruleSpaces === null || ruleSpaces === undefined) { | ||
options.ruleSpaces = true; | ||
} else if (typeof ruleSpaces !== 'boolean') { | ||
raise(ruleSpaces, 'options.ruleSpaces'); | ||
} | ||
if (emphasis === null || emphasis === undefined) { | ||
options.emphasis = UNDERSCORE; | ||
} else if (!(emphasis in EMPHASIS_MARKERS)) { | ||
raise(emphasis, 'options.emphasis'); | ||
} | ||
if (strong === null || strong === undefined) { | ||
options.strong = ASTERISK; | ||
} else if (!(strong in EMPHASIS_MARKERS)) { | ||
raise(strong, 'options.strong'); | ||
} | ||
if (setext === null || setext === undefined) { | ||
options.setext = false; | ||
} else if (typeof setext !== 'boolean') { | ||
raise(setext, 'options.setext'); | ||
} | ||
if (closeAtx === null || closeAtx === undefined) { | ||
options.closeAtx = false; | ||
} else if (typeof closeAtx !== 'boolean') { | ||
raise(closeAtx, 'options.closeAtx'); | ||
} | ||
if (referenceLinks === null || referenceLinks === undefined) { | ||
options.referenceLinks = false; | ||
} else if (typeof referenceLinks !== 'boolean') { | ||
raise(referenceLinks, 'options.referenceLinks'); | ||
} | ||
if (referenceFootnotes === null || referenceFootnotes === undefined) { | ||
options.referenceFootnotes = true; | ||
} else if (typeof referenceFootnotes !== 'boolean') { | ||
raise(referenceFootnotes, 'options.referenceFootnotes'); | ||
} | ||
if (fences === null || fences === undefined) { | ||
options.fences = false; | ||
} else if (typeof fences !== 'boolean') { | ||
raise(fences, 'options.fences'); | ||
} | ||
if (fence === null || fence === undefined) { | ||
options.fence = TICK; | ||
} else if (!(fence in FENCE_MARKERS)) { | ||
raise(fence, 'options.fence'); | ||
} | ||
if (ruleRepetition === null || ruleRepetition === undefined) { | ||
options.ruleRepetition = 3; | ||
} else if ( | ||
typeof ruleRepetition !== 'number' || | ||
ruleRepetition < 3 || | ||
ruleRepetition !== ruleRepetition | ||
) { | ||
if (ruleRepetition < 3 || ruleRepetition !== ruleRepetition) { | ||
raise(ruleRepetition, 'options.ruleRepetition'); | ||
@@ -770,2 +695,18 @@ } | ||
/** | ||
* Stringify YAML front matter. | ||
* | ||
* @param {Object} token | ||
* @return {string} | ||
*/ | ||
compilerPrototype.yaml = function (token) { | ||
var delimiter, | ||
value; | ||
delimiter = repeat(3, DASH); | ||
value = token.value ? LINE + token.value : EMPTY; | ||
return delimiter + value + LINE + delimiter; | ||
}; | ||
/** | ||
* Stringify a code block. | ||
@@ -796,3 +737,3 @@ * | ||
return fence + (token.lang || '') + LINE + value + LINE + fence; | ||
return fence + (token.lang || EMPTY) + LINE + value + LINE + fence; | ||
}; | ||
@@ -965,6 +906,12 @@ | ||
rows, | ||
result; | ||
result, | ||
loose, | ||
spaced, | ||
start; | ||
self = this; | ||
loose = self.options.looseTable; | ||
spaced = self.options.spacedTable; | ||
rows = token.children; | ||
@@ -982,2 +929,4 @@ | ||
start = loose ? EMPTY : spaced ? PIPE + SPACE : PIPE; | ||
/* | ||
@@ -990,3 +939,6 @@ * There was a bug in markdown-table@0.3.0, fixed | ||
return table(result, { | ||
'align': token.align.concat() | ||
'align': token.align.concat(), | ||
'start': start, | ||
'end': start.split(EMPTY).reverse().join(EMPTY), | ||
'delimiter': spaced ? SPACE + PIPE + SPACE : PIPE | ||
}); | ||
@@ -993,0 +945,0 @@ }; |
@@ -66,2 +66,78 @@ 'use strict'; | ||
/** | ||
* Validate a value to be boolean. Defaults to `def`. | ||
* Raises an exception with `options.$name` when not | ||
* a boolean. | ||
* | ||
* @param {Object} obj | ||
* @param {string} name | ||
* @param {boolean} def | ||
*/ | ||
function validateBoolean(obj, name, def) { | ||
var value; | ||
value = obj[name]; | ||
if (value === null || value === undefined) { | ||
value = def; | ||
} | ||
if (typeof value !== 'boolean') { | ||
raise(value, 'options.' + name); | ||
} | ||
obj[name] = value; | ||
} | ||
/** | ||
* Validate a value to be boolean. Defaults to `def`. | ||
* Raises an exception with `options.$name` when not | ||
* a boolean. | ||
* | ||
* @param {Object} obj | ||
* @param {string} name | ||
* @param {number} def | ||
*/ | ||
function validateNumber(obj, name, def) { | ||
var value; | ||
value = obj[name]; | ||
if (value === null || value === undefined) { | ||
value = def; | ||
} | ||
if (typeof value !== 'number') { | ||
raise(value, 'options.' + name); | ||
} | ||
obj[name] = value; | ||
} | ||
/** | ||
* Validate a value to be in `map`. Defaults to `def`. | ||
* Raises an exception with `options.$name` when not | ||
* not in `map`. | ||
* | ||
* @param {Object} obj | ||
* @param {string} name | ||
* @param {Object} map | ||
* @param {boolean} def | ||
*/ | ||
function validateMap(obj, name, map, def) { | ||
var value; | ||
value = obj[name]; | ||
if (value === null || value === undefined) { | ||
value = def; | ||
} | ||
if (!(value in map)) { | ||
raise(value, 'options.' + name); | ||
} | ||
obj[name] = value; | ||
} | ||
/** | ||
* Remove final white space from `value`. | ||
@@ -123,2 +199,12 @@ * | ||
/* | ||
* Expose `validate`. | ||
*/ | ||
exports.validate = { | ||
'bool': validateBoolean, | ||
'map': validateMap, | ||
'num': validateNumber | ||
}; | ||
/* | ||
* Expose `trim` methods. | ||
@@ -125,0 +211,0 @@ */ |
{ | ||
"name": "mdast", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Speedy Markdown parser/stringifier for multipurpose analysis", | ||
@@ -20,2 +20,4 @@ "license": "MIT", | ||
"dependencies": { | ||
"commander": "^2.0.0", | ||
"debug": "^2.0.0", | ||
"he": "^0.5.0", | ||
@@ -36,2 +38,5 @@ "markdown-table": "^0.3.0", | ||
}, | ||
"directories": { | ||
"man": "./man" | ||
}, | ||
"devDependencies": { | ||
@@ -41,3 +46,3 @@ "browserify": "^8.0.0", | ||
"diff": "^1.0.0", | ||
"eslint": "^0.13.0", | ||
"eslint": "^0.14.0", | ||
"esmangle": "^1.0.0", | ||
@@ -47,4 +52,5 @@ "istanbul": "^0.3.0", | ||
"jscs-jsdoc": "^0.4.0", | ||
"marked-man": "^0.1.0", | ||
"matcha": "^0.6.0", | ||
"mdast": "^0.1.12", | ||
"mdast": "^0.2.0", | ||
"mdast-usage": "^0.1.0", | ||
@@ -60,3 +66,3 @@ "mocha": "^2.0.0" | ||
"test": "npm run test-api && npm run test-cli", | ||
"lint-api": "eslint index.js lib/parse.js lib/stringify.js lib/utilities.js", | ||
"lint-api": "eslint --env browser index.js lib/parse.js lib/stringify.js lib/utilities.js", | ||
"lint-benchmark": "eslint --global suite,set,bench benchmark.js", | ||
@@ -70,2 +76,3 @@ "lint-cli": "eslint --rule no-process-exit:false cli.js", | ||
"benchmark": "matcha benchmark.js", | ||
"build-man": "marked-man doc/mdast.1.md > man/mdast.1", | ||
"build-usage": "mdast --use mdast-usage Readme.md -o Readme.md", | ||
@@ -75,5 +82,5 @@ "build-options": "node script/build-options.js", | ||
"postbuild-bundle": "esmangle mdast.js > mdast.min.js", | ||
"build": "npm run build-usage && npm run build-options && npm run build-bundle", | ||
"build": "npm run build-usage && npm run build-options && npm run build-man && npm run build-bundle", | ||
"prepublish": "npm run build" | ||
} | ||
} |
@@ -242,2 +242,3 @@ # ![mdast](https://cdn.rawgit.com/wooorm/mdast/master/logo.svg) | ||
- `tables` (`boolean`, default: `true`). See [Tables](doc/Options.md#tables); | ||
- `yaml` (`boolean`, default: `true`). See [YAML](doc/Options.md#yaml); | ||
- `footnotes` (`boolean`, default: `false`). See [Footnotes](doc/Options.md#footnotes). | ||
@@ -259,4 +260,7 @@ - `pedantic` (`boolean`, default: `false`). See [Pedantic](doc/Options.md#pedantic); | ||
- `closeAtx` (`boolean`, default: `false`). See [Closed ATX Headings](doc/Options.md#closed-atx-headings); | ||
- `looseTable` (`boolean`, default: `false`). See [Loose Tables](doc/Options.md#loose-tables); | ||
- `spacedTable` (`boolean`, default: `true`). See [Spaced Tables](doc/Options.md#spaced-tables); | ||
- `referenceLinks` (`boolean`, default: `false`). See [Reference Links](doc/Options.md#reference-links); | ||
- `referenceFootnotes` (`boolean`, default: `true`). See [Inline Footnotes](doc/Options.md#inline-footnotes); | ||
- `fence: string` (`"~"` or ``"`"``, default: `~`). See [Fence](doc/Options.md#fence); | ||
- `fences` (`boolean`, default: `false`). See [Fences](doc/Options.md#fences); | ||
@@ -302,24 +306,24 @@ - `bullet` (`"-"`, `"*"`, or `"+"`, default: `"-"`). See [List Item Bullets](doc/Options.md#list-item-bullets); | ||
-h, --help output usage information | ||
-v, --version output version number | ||
-a, --ast output AST information | ||
--options output available settings | ||
-o, --output <path> specify output location | ||
-O, --option <option> specify settings | ||
-u, --use <plugin> specify plugins | ||
-h, --help output usage information | ||
-V, --version output the version number | ||
-o, --output <path> specify output location | ||
-s, --setting <settings> specify settings | ||
-u, --use <plugins> use transform plugin(s) | ||
-a, --ast output AST information | ||
--settings output available settings | ||
# Note that bash does not allow reading and writing | ||
# to the same file through pipes | ||
Usage: | ||
# Note that bash does not allow reading and writing to the | ||
# same file through pipes | ||
# Pass `Readme.md` through mdast | ||
$ mdast Readme.md -o Readme.md | ||
# Pass stdin through mdast, with options, to stdout | ||
$ cat Readme.md | mdast --option "setext, bullet: *" > Readme-new.md | ||
# Pass stdin through mdast, with settings, to stdout | ||
$ cat Readme.md | mdast --setting "setext, bullet: *" > Readme-new.md | ||
# Use an npm module | ||
$ npm install some-plugin | ||
$ mdast --use some-plugin History.md > History-new.md | ||
# use a plugin | ||
$ npm install mdast-toc | ||
$ mdast --use mdast-toc -o Readme.md | ||
``` | ||
@@ -326,0 +330,0 @@ |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
110024
345
2
5
13
3114
+ Addedcommander@^2.0.0
+ Addeddebug@^2.0.0
+ Addedcommander@2.20.3(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addedms@2.0.0(transitive)