diff --git a/Makefile b/Makefile index 504038d..17bc0ca 100644 --- a/Makefile +++ b/Makefile @@ -72,5 +72,5 @@ todo: grep 'TODO' -n -r ./lib 2>/dev/null || test true -.PHONY: publish lint test gh-pages todo demo +.PHONY: publish lint test gh-pages todo demo coverage .SILENT: help lint test todo diff --git a/lib/common/utils.js b/lib/common/utils.js index 98f2498..a230260 100644 --- a/lib/common/utils.js +++ b/lib/common/utils.js @@ -15,8 +15,8 @@ function assign(obj /*from1, from2, from3, ...*/) { var source = sources.shift(); if (!source) { continue; } - if (typeof(source) !== 'object') { - throw new TypeError(source + 'must be non-object'); + if (typeof source !== 'object') { + throw new TypeError(source + 'must be object'); } for (var p in source) { diff --git a/lib/configs/commonmark.js b/lib/configs/commonmark.js index 5a6b868..4aa4259 100644 --- a/lib/configs/commonmark.js +++ b/lib/configs/commonmark.js @@ -20,7 +20,10 @@ module.exports = { // Highlighter function. Should return escaped HTML, // or '' if input not changed - highlight: function (/*str, lang*/) { return ''; }, + // + // function (/*str, lang*/) { return ''; } + // + highlight: null, maxNesting: 20 // Internal protection, recursion limit }, diff --git a/lib/configs/default.js b/lib/configs/default.js index 423fd9a..9a2bacb 100644 --- a/lib/configs/default.js +++ b/lib/configs/default.js @@ -20,7 +20,10 @@ module.exports = { // Highlighter function. Should return escaped HTML, // or '' if input not changed - highlight: function (/*str, lang*/) { return ''; }, + // + // function (/*str, lang*/) { return ''; } + // + highlight: null, maxNesting: 20 // Internal protection, recursion limit }, diff --git a/lib/configs/full.js b/lib/configs/full.js index 243cbf2..59d9af3 100644 --- a/lib/configs/full.js +++ b/lib/configs/full.js @@ -20,7 +20,10 @@ module.exports = { // Highlighter function. Should return escaped HTML, // or '' if input not changed - highlight: function (/*str, lang*/) { return ''; }, + // + // function (/*str, lang*/) { return ''; } + // + highlight: null, maxNesting: 20 // Internal protection, recursion limit }, diff --git a/lib/index.js b/lib/index.js index b3114de..94801e1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -65,7 +65,7 @@ Remarkable.prototype.set = function (options) { Remarkable.prototype.configure = function (presets) { var self = this; - if (!presets) { throw new Error('Wrong config name'); } + if (!presets) { throw new Error('Wrong preset name'); } if (presets.options) { self.set(presets.options); } @@ -100,15 +100,9 @@ Remarkable.prototype.use = function (plugin, opts) { // definitions data. // Remarkable.prototype.parse = function (src, env) { - var i, len, - rules = this.core.ruler.getRules(''), - state = new StateCore(this, src, env); + var state = new StateCore(this, src, env); - len = rules.length; - - for (i = 0; i < len; i++) { - rules[i](state); - } + this.core.process(state); return state.tokens; }; diff --git a/lib/renderer.js b/lib/renderer.js index 89d104f..615a484 100644 --- a/lib/renderer.js +++ b/lib/renderer.js @@ -101,7 +101,12 @@ rules.fence = function (tokens, idx, options) { langClass = ' class="' + langPrefix + langName + '"'; } - highlighted = options.highlight(token.content, langName) || escapeHtml(token.content); + if (options.highlight) { + highlighted = options.highlight(token.content, langName) || escapeHtml(token.content); + } else { + highlighted = escapeHtml(token.content); + } + return '
'
+ highlighted
diff --git a/test/fixtures/remarkable/commonmark_extras.txt b/test/fixtures/remarkable/commonmark_extras.txt
index 314e9a7..73eb6af 100644
--- a/test/fixtures/remarkable/commonmark_extras.txt
+++ b/test/fixtures/remarkable/commonmark_extras.txt
@@ -64,6 +64,7 @@ Issue #55:
![test](foo bar)
.
+
Should unescape only needed things in link destinations/titles:
.
@@ -77,3 +78,21 @@ Should unescape only needed things in link destinations/titles:
.
.
+
+
+Not a closing tag
+
+.
+ 123>
+.
+</ 123>
+.
+
+
+Not a list item
+
+.
+1.list
+.
+1.list
+.
diff --git a/test/misc.js b/test/misc.js
index 46e9303..9ca6c20 100644
--- a/test/misc.js
+++ b/test/misc.js
@@ -6,6 +6,66 @@ var assert = require('assert');
var Remarkable = require('../');
+describe('Utils', function () {
+
+ it('utils.fromCodePoint', function () {
+ var fromCodePoint = require('../lib/common/utils').fromCodePoint;
+
+ assert.strictEqual(fromCodePoint(0x20), ' ');
+ assert.strictEqual(fromCodePoint(0x1F601), '😁');
+ });
+
+ it('utils.isValidEntityCode', function () {
+ var isValidEntityCode = require('../lib/common/utils').isValidEntityCode;
+
+ assert.strictEqual(isValidEntityCode(0x20), true);
+ assert.strictEqual(isValidEntityCode(0xD800), false);
+ assert.strictEqual(isValidEntityCode(0xFDD0), false);
+ assert.strictEqual(isValidEntityCode(0x1FFFF), false);
+ assert.strictEqual(isValidEntityCode(0x1FFFE), false);
+ assert.strictEqual(isValidEntityCode(0x00), false);
+ assert.strictEqual(isValidEntityCode(0x0B), false);
+ assert.strictEqual(isValidEntityCode(0x0E), false);
+ assert.strictEqual(isValidEntityCode(0x7F), false);
+ });
+
+ it('utils.assign', function () {
+ var assign = require('../lib/common/utils').assign;
+
+ assert.deepEqual(assign({ a: 1 }, null, { b: 2 }), { a: 1, b: 2 });
+ assert.throws(function () {
+ assign({}, 123);
+ });
+ });
+
+});
+
+
+describe('API', function () {
+
+ it('Constructor', function () {
+ assert.throws(function () {
+ var md = new Remarkable('bad preset');
+ md.render('123');
+ });
+ });
+
+ it('Plugin', function () {
+ var succeeded = false;
+
+ function plugin(self, opts) { if (opts === 'bar') { succeeded = true; } }
+
+ var md = new Remarkable();
+
+ md.use(plugin, 'foo');
+ assert.strictEqual(succeeded, false);
+ md.use(plugin, 'bar');
+ assert.strictEqual(succeeded, true);
+ });
+
+});
+
+
describe('Misc', function () {
it('Should correctly parse strings without tailing \\n', function () {
@@ -14,4 +74,22 @@ describe('Misc', function () {
assert.strictEqual(md.render('123'), '123
\n');
assert.strictEqual(md.render('123\n'), '123
\n');
});
+
+});
+
+
+describe('Links validation', function () {
+
+ it('Override validator, disable everything', function () {
+ var md = new Remarkable({ linkify: true });
+
+ md.inline.validateLink = function () { return false; };
+
+ assert.strictEqual(md.render('foo@example.com'), 'foo@example.com
\n');
+ assert.strictEqual(md.render('http://example.com'), 'http://example.com
\n');
+ assert.strictEqual(md.render(''), '<foo@example.com>
\n');
+ assert.strictEqual(md.render(''), '<http://example.com>
\n');
+ assert.strictEqual(md.render('[test](http://example.com)'), '[test](http://example.com)
\n');
+ });
+
});