Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ out
node_modules
npm-debug.log
src/grammar.js
.vscode
82 changes: 51 additions & 31 deletions bin/spec-md
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
#!/usr/bin/env node

var fs = require('fs');
var path = require('path');
var specmd = require('../');
var yargs = require('yargs');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please remove yargs and use the existing simplified argument parsing? My attempt to keep dependencies low and simple


var filepath;
var metadata;
for (var i = 2; i < process.argv.length; i++) {
if (process.argv[i] === '-m' || process.argv[i] === '--metadata') {
metadata = process.argv[++i];
} else if (process.argv[i][0] === '-') {
errorExit('Unknown argument: ' + process.argv[i]);
} else if (!filepath) {
filepath = process.argv[i];
} else {
errorExit('Must provide only one markdown file.');
}
}

if (!filepath) {
errorExit(
'Usage: spec-md initial-file.md\n\n' +
'Options:\n' +
' -m, --metadata filepath to json metadata'
);
}

var options = metadata ? require(path.resolve(process.cwd(), metadata)) : {};
var absPath = path.resolve(process.cwd(), filepath);
yargs.strict()
.config('config')
.option('metadata', {
alias: 'm',
describe: 'Additional metadata to be used in construction of the output',
string: true,
global: true,
coerce: arg=>require(path.resolve(process.cwd(), path.normalize(arg))),
})
.command(['$0 <markdown>','html <markdown>'], 'Outputs HTML5', {},
(argv)=>{
return specmd.html(argv.markdown,argv.metadata ? argv.metadata : {})
.then(_=>process.stdout.write(_))
.catch(errorExit);
}
)
.command(['plugin <package> <markdown> [args..]'], 'Outputs in the format of the specified plugin',
(yargs)=>{},
(argv)=>{
return argv.package([argv.markdown, ...argv.args],
specmd.parse(argv.markdown), argv.metadata ? argv.metadata : {})
.then(_=>process.stdout.write(_))
.catch(errorExit);
})
.coerce('markdown', (arg)=>path.resolve(process.cwd(), path.normalize(arg)))
.coerce('package', (arg)=>{
console.error(`Loading ${arg} ...`);
let package = null;
let plugin = null;
try {
package = require.resolve(arg, {
paths: [process.cwd()]
});
plugin = require(package);
}
catch(error) {
console.error(`Could not load plugin (${arg}).`);
console.error('If the plugin is installed globally, is /usr/lib/node_modules in your NODE_PATH variable (%AppData%\\npm\\node_modules on windows)?');
errorExit(error);
}

specmd.html(absPath, options).then(function (html) {
process.stdout.write(html);
}).catch(function (error) {
errorExit(error.line ? error.message : (error.stack || error));
});
if(typeof plugin !== 'function') {
errorExit(`The specified package (${package}) does not appear to be a plugin...`);
}
return plugin;
})
.help()
.parse();

function errorExit(msg) {
process.stderr.write(msg + '\n');
function errorExit(error) {
error.line ? error.message : (error.stack || error)
process.stderr.write(error + '\n');
process.exit(1);
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
},
"dependencies": {
"prismjs": ">=1.16.0",
"terser": "^4.1.2"
"terser": "^4.1.2",
"yargs": "^15.3.1"
},
"devDependencies": {
"jest-diff": "^24.8.0",
Expand Down
14 changes: 9 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var print = require('./print');
var {print, ...others} = require('./print');
var parse = require('./parse');
var visit = require('./visit');

Expand All @@ -8,7 +8,11 @@ function html(filepath, options) {
});
}

exports.html = html;
exports.print = print;
exports.parse = parse;
exports.visit = visit;
module.exports = {
html,
print,
parse,
visit,
...others
}

10 changes: 7 additions & 3 deletions src/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var fs = require('fs');
var path = require('path');
var grammar = require('./grammar');
var grammar = require(path.resolve(__dirname, './grammar'));
var visit = require('./visit');


Expand All @@ -22,7 +22,10 @@ function readFile(filepath) {
});
}

function importAST(parser, filepath) {
function importAST(parser, filepath, subdir) {
if(!subdir)
subdir = path.dirname(filepath);

return readFile(filepath).then(function (source) {
try {
var ast = parser.parse(source);
Expand All @@ -36,9 +39,10 @@ function importAST(parser, filepath) {
}
var importASTs = [];
visit(ast, function (node) {
node.subdir = subdir;
if (node.type === 'Import') {
var subfilepath = path.resolve(path.dirname(filepath), decodeURI(node.path));
importASTs.push(importAST(parser, subfilepath));
importASTs.push(importAST(parser, subfilepath, path.dirname(subfilepath)));
}
});
return Promise.all(importASTs).then(function (asts) {
Expand Down
30 changes: 22 additions & 8 deletions src/print.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ var terser = require('terser');
var visit = require('./visit');

function print(ast, _options) {
var options = {};
options.highlight = _options && _options.highlight || highlight;
options.biblio = _options && _options.biblio && buildBiblio(_options.biblio) || {};
options.head = _options && _options.head || '';
validateSecIDs(ast, options);
assignExampleNumbers(ast, options);
assignBiblioIDs(ast, options);
var options = updateBiblio(ast, _options);
return (
'<!DOCTYPE html>\n' +
'<!-- Built with spec-md https://spec-md.com -->\n' +
Expand All @@ -23,7 +17,27 @@ function print(ast, _options) {
);
};

module.exports = print;
function updateBiblio(ast, _options) {
var options = {};
options.highlight = _options && _options.highlight || highlight;
options.biblio = _options && _options.biblio && buildBiblio(_options.biblio) || {};
options.head = _options && _options.head || '';
validateSecIDs(ast, options);
assignExampleNumbers(ast, options);
assignBiblioIDs(ast, options);
return options;
}

module.exports = {
print,
formatText,
escape,
escapeCode,
updateBiblio,
getTerms,
anchorize,
join
Comment on lines +33 to +39
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are implementation details that might change in the future - I'd suggest avoiding exporting them and directly relying on them

};

function highlight(code, lang) {
var prismLang = getPrismLanguage(lang);
Expand Down
2 changes: 1 addition & 1 deletion test/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const fs = require('fs');
const path = require('path');
const specMarkdown = require('../');

const shouldRecord = Boolean(process.env.RECORD);
const shouldRecord = process.env.RECORD ? Boolean.parse(process.env.RECORD) : false;

runTests([
['../README.md', 'readme/ast.json', 'readme/output.html'],
Expand Down
Loading