diff --git a/lib/index.js b/lib/index.js index 6b301e8..a3dd099 100644 --- a/lib/index.js +++ b/lib/index.js @@ -57,7 +57,7 @@ function normalizeLink(url) { if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) { try { parsed.hostname = punycode.toASCII(parsed.hostname); - } catch (er) { /**/ } + } catch(er) { /**/ } } } @@ -77,7 +77,7 @@ function normalizeLinkText(url) { if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) { try { parsed.hostname = punycode.toUnicode(parsed.hostname); - } catch (er) { /**/ } + } catch(er) { /**/ } } } @@ -483,7 +483,7 @@ MarkdownIt.prototype.use = function (plugin /*, params, ... */) { * AST). * * `env` is used to pass data between "distributed" rules and return additional - * metadata like reference info, needed for the renderer. It also can be used to + * metadata like reference info, needed for for renderer. It also can be used to * inject data in specific cases. Usually, you will be ok to pass `{}`, * and then pass updated object to renderer. **/ @@ -514,6 +514,21 @@ MarkdownIt.prototype.render = function (src, env) { }; +/** + * MarkdownIt.renderTokens(src [, env]) -> String + * - src (String): source string + * - env (Object): environment sandbox + * + * Render markdown string into an array of html-like tokens. + * If you want to render each token separately (for example with React) + **/ +MarkdownIt.prototype.renderTokens = function (src, env) { + env = env || {}; + + return this.renderer.renderTokens(this.parse(src, env), this.options, env); +}; + + /** internal * MarkdownIt.parseInline(src, env) -> Array * - src (String): source string diff --git a/lib/renderer.js b/lib/renderer.js index b1000d5..0db3bc6 100644 --- a/lib/renderer.js +++ b/lib/renderer.js @@ -226,20 +226,16 @@ Renderer.prototype.renderToken = function renderToken(tokens, idx, options) { **/ Renderer.prototype.renderInline = function (tokens, options, env) { var type, - result = '', rules = this.rules; - for (var i = 0, len = tokens.length; i < len; i++) { - type = tokens[i].type; + return tokens.map(function(token, i) { + type = token.type; if (typeof rules[type] !== 'undefined') { - result += rules[type](tokens, i, options, env, this); - } else { - result += this.renderToken(tokens, i, options); - } - } + return rules[type](tokens, i, options, env, this); - return result; + return this.renderToken(tokens, i, options); + }, this); }; @@ -279,23 +275,40 @@ Renderer.prototype.renderInlineAsText = function (tokens, options, env) { * this method directly. **/ Renderer.prototype.render = function (tokens, options, env) { - var i, len, type, + return this.renderTokens(tokens, options, env).reduce(function(collector, token) { + return collector + token; + }, ''); +}; + + +/** + * Renderer.renderTokens(tokens, options, env) -> String + * - tokens (Array): list on block tokens to renter + * - options (Object): params of parser instance + * - env (Object): additional data from parsed input (references, for example) + * + * Takes token stream and generates html-like tokens. Probably, you will never need to call + * this method directly. + **/ +Renderer.prototype.renderTokens = function (tokens, options, env) { + var len, type, result = '', rules = this.rules; - for (i = 0, len = tokens.length; i < len; i++) { - type = tokens[i].type; + return tokens.reduce(function(collector, token, i) { + type = token.type; - if (type === 'inline') { - result += this.renderInline(tokens[i].children, options, env); - } else if (typeof rules[type] !== 'undefined') { - result += rules[tokens[i].type](tokens, i, options, env, this); - } else { - result += this.renderToken(tokens, i, options, env); + if (type === 'inline') + return collector.concat(this.renderInline(token.children, options, env)); + + if (typeof rules[type] !== 'undefined') { + collector.push(rules[type](tokens, i, options, env, this)); + return collector; } - } - return result; + collector.push(this.renderToken(tokens, i, options, env)); + return collector; + }.bind(this), []); }; module.exports = Renderer; diff --git a/test/misc.js b/test/misc.js index 82e2381..e22dbce 100644 --- a/test/misc.js +++ b/test/misc.js @@ -213,6 +213,12 @@ describe('Misc', function () { assert.strictEqual(md.render('[foo](bar)'), '
\n'); }); + it('Should render tokens into an array', function() { + var md = markdownit(); + + assert.deepEqual(md.renderTokens('foo'), [ '', 'foo', '
\n' ]); + }); + });