diff --git a/CHANGELOG.md b/CHANGELOG.md index c7dd144..e7a6f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ - Added footnotes support. - Added definitions lists support. -- Exposed `./common/utils` to simplify custom renderer write. +- Added `fence_custom` renderer extension to easy override + named fenced blocks (useful for diagrams and so on). +- Exposed `./common/utils` to simplify custom renderers. 1.4.1 / 2014-11-13 diff --git a/lib/renderer.js b/lib/renderer.js index 1da33eb..2a92f2a 100644 --- a/lib/renderer.js +++ b/lib/renderer.js @@ -55,16 +55,29 @@ rules.code = function (tokens, idx /*, options, env */) { }; -rules.fence = function (tokens, idx, options /*, env */) { +rules.fence = function (tokens, idx, options, env, self) { var token = tokens[idx]; var langClass = ''; var langPrefix = options.langPrefix; - var params, langName = ''; + var langName = '', fenceName; var highlighted; if (token.params) { - params = token.params.split(/ +/g); - langName = escapeHtml(replaceEntities(unescapeMd(params[0]))); + + // + // ```foo bar + // + // Try custom renderer "foo" first. That will simplify overwrite + // for diagrams, latex, and any other fenced block with custom look + // + + fenceName = token.params.split(/\s+/g)[0]; + + if (self.rules.fence_custom.hasOwnProperty(fenceName)) { + return self.rules.fence_custom[fenceName](tokens, idx, options, env, self); + } + + langName = escapeHtml(replaceEntities(unescapeMd(fenceName))); langClass = ' class="' + langPrefix + langName + '"'; } @@ -80,6 +93,7 @@ rules.fence = function (tokens, idx, options /*, env */) { + '' + getBreak(tokens, idx); }; +rules.fence_custom = {}; rules.heading_open = function (tokens, idx /*, options, env */) { return ''; @@ -310,6 +324,8 @@ rules.dd_close = function() { function Renderer() { // Clone rules object to allow local modifications this.rules = assign({}, rules); + // exported helper, for custom rules only + this.getBreak = getBreak; } @@ -318,7 +334,7 @@ Renderer.prototype.renderInline = function (tokens, options, env) { _rules = this.rules; for (var i = 0, len = tokens.length; i < len; i++) { - result += _rules[tokens[i].type](tokens, i, options, env); + result += _rules[tokens[i].type](tokens, i, options, env, this); } return result; @@ -334,7 +350,7 @@ Renderer.prototype.render = function (tokens, options, env) { if (tokens[i].type === 'inline') { result += this.renderInline(tokens[i].children, options, env); } else { - result += _rules[tokens[i].type](tokens, i, options, env); + result += _rules[tokens[i].type](tokens, i, options, env, this); } } diff --git a/test/misc.js b/test/misc.js index e8f380c..c2f9d3d 100644 --- a/test/misc.js +++ b/test/misc.js @@ -4,6 +4,7 @@ var assert = require('assert'); var Remarkable = require('../'); +var utils = require('../').utils; describe('Utils', function () { @@ -181,3 +182,23 @@ describe('Links validation', function () { }); }); + + +describe('Custom fences', function () { + + it('should render differently overriden rule', function () { + var md = new Remarkable(); + + md.renderer.rules.fence_custom.foo = function (tokens, idx, options, env, self) { + return '
' + + utils.escapeHtml(tokens[idx].content) + + '
' + self.getBreak(tokens, idx); + }; + + var text = '```foo bar\n' + + '123&45\n' + + '```'; + assert.strictEqual(md.render(text), '
123&45\n
\n'); + }); + +});