summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2015-01-09 19:10:24 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2015-01-09 19:10:24 -0800
commita1bc760fef3ae9e98f039fa50f31fc2d5eb877a2 (patch)
tree31112fdecb5e60ccc9c318391e30f551d78522c9
parent7bfb5dd6915fd455e93086fc2b546802bdd77027 (diff)
Added options to render, implemented sourcepos option.
This adds data-sourcepos attributes on block-level tags in the HTML output. Also added `--sourcepos` command-line option to `js/bin/commonmark`.
-rwxr-xr-xjs/bin/commonmark27
-rw-r--r--js/lib/html.js42
2 files changed, 45 insertions, 24 deletions
diff --git a/js/bin/commonmark b/js/bin/commonmark
index ac53e6e..72ad344 100755
--- a/js/bin/commonmark
+++ b/js/bin/commonmark
@@ -6,19 +6,26 @@ var util = require('util');
var commonmark = require('../lib/index.js');
var parser = new commonmark.DocParser();
-var renderer;
+var renderer = new commonmark.HtmlRenderer();
var inps = [];
var file;
var files = [];
+var options = { sourcepos: false, };
-if (process.argv[2] === '--ast') {
- files = process.argv.slice(3);
- renderer = { render: function(x) {
- return util.inspect(x.toAST(), null, Infinity, true) + '\n';
- } };
-} else {
- files = process.argv.slice(2);
- renderer = new commonmark.HtmlRenderer();
+for (var i = 2; i < process.argv.length; i++) {
+ var arg = process.argv[i];
+ if (arg == '--ast') {
+ renderer = { render: function(x) {
+ return util.inspect(x.toAST(), null, Infinity, true) + '\n';
+ } };
+ } else if (arg == '--sourcepos') {
+ options.sourcepos = true;
+ } else if (/^--/.test(arg)) {
+ process.stderr.write('Unknown option ' + arg + '\n');
+ process.exit(1);
+ } else {
+ files.push(arg);
+ }
}
if (files.length === 0) {
@@ -30,4 +37,4 @@ for (var i = 0; i < files.length; i++) {
inps.push(fs.readFileSync(file, 'utf8'));
}
-process.stdout.write(renderer.render(parser.parse(inps.join('\n'))));
+process.stdout.write(renderer.render(parser.parse(inps.join('\n')), options));
diff --git a/js/lib/html.js b/js/lib/html.js
index 57f87e5..ca5b477 100644
--- a/js/lib/html.js
+++ b/js/lib/html.js
@@ -1,12 +1,12 @@
"use strict";
// Helper function to produce an HTML tag.
-var tag = function(name, attribs, selfclosing) {
+var tag = function(name, attrs, selfclosing) {
var result = '<' + name;
- if (attribs) {
+ if (attrs && attrs.length > 0) {
var i = 0;
var attrib;
- while ((attrib = attribs[i]) !== undefined) {
+ while ((attrib = attrs[i]) !== undefined) {
result = result.concat(' ', attrib[0], '="', attrib[1], '"');
i++;
}
@@ -19,7 +19,7 @@ var tag = function(name, attribs, selfclosing) {
return result;
};
-var renderNodes = function(block) {
+var renderNodes = function(block, options) {
var attrs;
var info_words;
@@ -43,10 +43,22 @@ var renderNodes = function(block) {
}
};
+ options = options || {};
+
while ((event = walker.next())) {
entering = event.entering;
node = event.node;
+ attrs = [];
+ if (options.sourcepos) {
+ var pos = node.sourcepos;
+ if (pos) {
+ attrs.push(['data-sourcepos', String(pos[0][0]) + ':' +
+ String(pos[0][1]) + '-' + String(pos[1][0]) + ':' +
+ String(pos[1][1])]);
+ }
+ }
+
switch (node.t) {
case 'Text':
out(esc(node.c));
@@ -79,7 +91,7 @@ var renderNodes = function(block) {
case 'Link':
if (entering) {
- attrs = [['href', esc(node.destination, true)]];
+ attrs.push(['href', esc(node.destination, true)]);
if (node.title) {
attrs.push(['title', esc(node.title, true)]);
}
@@ -124,7 +136,7 @@ var renderNodes = function(block) {
}
if (entering) {
cr();
- out(tag('p'));
+ out(tag('p', attrs));
} else {
out(tag('/p'));
cr();
@@ -134,7 +146,7 @@ var renderNodes = function(block) {
case 'BlockQuote':
if (entering) {
cr();
- out(tag('blockquote'));
+ out(tag('blockquote', attrs));
cr();
} else {
cr();
@@ -145,7 +157,7 @@ var renderNodes = function(block) {
case 'ListItem':
if (entering) {
- out(tag('li'));
+ out(tag('li', attrs));
} else {
out(tag('/li'));
cr();
@@ -155,8 +167,9 @@ var renderNodes = function(block) {
case 'List':
tagname = node.list_data.type === 'Bullet' ? 'ul' : 'ol';
if (entering) {
- attrs = (!node.list_data.start || node.list_data.start === 1) ?
- [] : [['start', node.list_data.start.toString()]];
+ if (node.list_data.start && node.list_data.start > 1) {
+ attrs.push(['start', node.list_data.start.toString()]);
+ }
cr();
out(tag(tagname, attrs));
cr();
@@ -171,7 +184,7 @@ var renderNodes = function(block) {
tagname = 'h' + node.level;
if (entering) {
cr();
- out(tag(tagname));
+ out(tag(tagname, attrs));
} else {
out(tag('/' + tagname));
cr();
@@ -180,8 +193,9 @@ var renderNodes = function(block) {
case 'CodeBlock':
info_words = node.info ? node.info.split(/ +/) : [];
- attrs = (info_words.length === 0 || info_words[0].length === 0)
- ? [] : [['class', 'language-' + esc(info_words[0], true)]];
+ if (info_words.length > 0 && info_words[0].length > 0) {
+ attrs.push(['class', 'language-' + esc(info_words[0], true)]);
+ }
cr();
out(tag('pre') + tag('code', attrs));
out(this.escape(node.c));
@@ -197,7 +211,7 @@ var renderNodes = function(block) {
case 'HorizontalRule':
cr();
- out(tag('hr', [], true));
+ out(tag('hr', attrs, true));
cr();
break;