Browse Source

Updated line breaks rendering logic

pull/14/head
Vitaly Puzrin 10 years ago
parent
commit
2a9218cf60
  1. 95
      lib/renderer.js
  2. 3
      support/specsplit.js
  3. 1210
      test/fixtures/commonmark/bad.txt
  4. 1053
      test/fixtures/commonmark/good.txt
  5. 3
      test/fixtures/markdown-it/tables.txt
  6. 4
      test/misc.js

95
lib/renderer.js

@ -8,31 +8,6 @@ var replaceEntities = require('./common/utils').replaceEntities;
var escapeHtml = require('./common/utils').escapeHtml; var escapeHtml = require('./common/utils').escapeHtml;
////////////////////////////////////////////////////////////////////////////////
// Helpers
function nextToken(tokens, idx) {
if (++idx >= tokens.length - 2) { return idx; }
if ((tokens[idx].type === 'paragraph_open' && tokens[idx].tight) &&
(tokens[idx + 1].type === 'inline' && tokens[idx + 1].content.length === 0) &&
(tokens[idx + 2].type === 'paragraph_close' && tokens[idx + 2].tight)) {
return nextToken(tokens, idx + 2);
}
return idx;
}
// check if we need to hide '\n' before next token
function getBreak(tokens, idx) {
idx = nextToken(tokens, idx);
if (idx < tokens.length &&
tokens[idx].type === 'list_item_close') {
return '';
}
return '\n';
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
var rules = {}; var rules = {};
@ -42,14 +17,14 @@ var rules = {};
rules.blockquote_open = function (/* tokens, idx, options, env */) { rules.blockquote_open = function (/* tokens, idx, options, env */) {
return '<blockquote>\n'; return '<blockquote>\n';
}; };
rules.blockquote_close = function (tokens, idx /*, options, env */) { rules.blockquote_close = function (/* tokens, idx, options, env */) {
return '</blockquote>' + getBreak(tokens, idx); return '</blockquote>\n';
}; };
rules.code = function (tokens, idx /*, options, env */) { rules.code = function (tokens, idx /*, options, env */) {
if (tokens[idx].block) { if (tokens[idx].block) {
return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>' + getBreak(tokens, idx); return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>\n';
} }
return '<code>' + escapeHtml(tokens[idx].content) + '</code>'; return '<code>' + escapeHtml(tokens[idx].content) + '</code>';
@ -91,7 +66,7 @@ rules.fence = function (tokens, idx, options, env, self) {
return '<pre><code' + langClass + '>' return '<pre><code' + langClass + '>'
+ highlighted + highlighted
+ '</code></pre>' + getBreak(tokens, idx); + '</code></pre>\n';
}; };
rules.fence_custom = {}; rules.fence_custom = {};
@ -105,30 +80,35 @@ rules.heading_close = function (tokens, idx /*, options, env */) {
rules.hr = function (tokens, idx, options /*, env */) { rules.hr = function (tokens, idx, options /*, env */) {
return (options.xhtmlOut ? '<hr />' : '<hr>') + getBreak(tokens, idx); return (options.xhtmlOut ? '<hr />\n' : '<hr>\n');
}; };
rules.bullet_list_open = function (/* tokens, idx, options, env */) { rules.bullet_list_open = function (/* tokens, idx, options, env */) {
return '<ul>\n'; return '<ul>\n';
}; };
rules.bullet_list_close = function (tokens, idx /*, options, env */) { rules.bullet_list_close = function (/* tokens, idx, options, env */) {
return '</ul>' + getBreak(tokens, idx); return '</ul>\n';
}; };
rules.list_item_open = function (/* tokens, idx, options, env */) { rules.list_item_open = function (tokens, idx /*, options, env */) {
return '<li>'; var next = tokens[idx + 1];
if ((next.type === 'list_item_close') ||
(next.type === 'paragraph_open' && next.tight)) {
return '<li>';
}
return '<li>\n';
}; };
rules.list_item_close = function (/* tokens, idx, options, env */) { rules.list_item_close = function (/* tokens, idx, options, env */) {
return '</li>\n'; return '</li>\n';
}; };
rules.ordered_list_open = function (tokens, idx /*, options, env */) { rules.ordered_list_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx]; if (tokens[idx].order > 1) {
return '<ol' return '<ol start="' + tokens[idx].order + '">\n';
+ (token.order > 1 ? ' start="' + token.order + '"' : '') }
+ '>\n'; return '<ol>\n';
}; };
rules.ordered_list_close = function (tokens, idx /*, options, env */) { rules.ordered_list_close = function (/* tokens, idx, options, env */) {
return '</ol>' + getBreak(tokens, idx); return '</ol>\n';
}; };
@ -136,8 +116,21 @@ rules.paragraph_open = function (tokens, idx /*, options, env */) {
return tokens[idx].tight ? '' : '<p>'; return tokens[idx].tight ? '' : '<p>';
}; };
rules.paragraph_close = function (tokens, idx /*, options, env */) { rules.paragraph_close = function (tokens, idx /*, options, env */) {
var addBreak = !(tokens[idx].tight && idx && tokens[idx - 1].type === 'inline' && !tokens[idx - 1].content); // We have 2 cases of "hidden" paragraphs
return (tokens[idx].tight ? '' : '</p>') + (addBreak ? getBreak(tokens, idx) : ''); //
// 1. In tight lists
// 2. When content was stripped (reference definition, for example)
//
if (tokens[idx].tight === true) {
if (!tokens[idx - 1].content) {
return '';
}
if (tokens[idx + 1].type === 'list_item_close') {
return '';
}
return '\n';
}
return '</p>\n';
}; };
@ -184,19 +177,19 @@ rules.tr_close = function (/* tokens, idx, options, env */) {
return '</tr>\n'; return '</tr>\n';
}; };
rules.th_open = function (tokens, idx /*, options, env */) { rules.th_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx]; if (tokens[idx].align) {
return '<th' return '<th style="text-align:' + tokens[idx].align + '">';
+ (token.align ? ' style="text-align:' + token.align + '"' : '') }
+ '>'; return '<th>';
}; };
rules.th_close = function (/* tokens, idx, options, env */) { rules.th_close = function (/* tokens, idx, options, env */) {
return '</th>'; return '</th>';
}; };
rules.td_open = function (tokens, idx /*, options, env */) { rules.td_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx]; if (tokens[idx].align) {
return '<td' return '<td style="text-align:' + tokens[idx].align + '">';
+ (token.align ? ' style="text-align:' + token.align + '"' : '') }
+ '>'; return '<td>';
}; };
rules.td_close = function (/* tokens, idx, options, env */) { rules.td_close = function (/* tokens, idx, options, env */) {
return '</td>'; return '</td>';
@ -335,8 +328,6 @@ rules.dd_close = function() {
function Renderer() { function Renderer() {
// Clone rules object to allow local modifications // Clone rules object to allow local modifications
this.rules = assign({}, rules); this.rules = assign({}, rules);
// exported helper, for custom rules only
this.getBreak = getBreak;
} }

3
support/specsplit.js

@ -86,7 +86,8 @@ readFile(options.spec, 'utf8', function (error, input) {
bad.push(result); bad.push(result);
} }
} catch (___) { } catch (___) {
bad.push(result); // bad.push(result);
throw ___;
} }
}); });

1210
test/fixtures/commonmark/bad.txt

File diff suppressed because it is too large

1053
test/fixtures/commonmark/good.txt

File diff suppressed because it is too large

3
test/fixtures/markdown-it/tables.txt

@ -98,7 +98,8 @@ Nested tables inside lists:
baz|baz baz|baz
. .
<ul> <ul>
<li><table> <li>
<table>
<thead> <thead>
<tr><th>foo</th><th>foo</th></tr> <tr><th>foo</th><th>foo</th></tr>
</thead> </thead>

4
test/misc.js

@ -219,10 +219,10 @@ describe('Custom fences', function () {
it('should render differently overriden rule', function () { it('should render differently overriden rule', function () {
var md = markdownit(); var md = markdownit();
md.renderer.rules.fence_custom.foo = function (tokens, idx, options, env, self) { md.renderer.rules.fence_custom.foo = function (tokens, idx /*, options, env */) {
return '<div class="foo">' + return '<div class="foo">' +
md.utils.escapeHtml(tokens[idx].content) + md.utils.escapeHtml(tokens[idx].content) +
'</div>' + self.getBreak(tokens, idx); '</div>\n';
}; };
var text = '```foo bar\n' + var text = '```foo bar\n' +

Loading…
Cancel
Save