Browse Source

Updated line breaks rendering logic

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

93
lib/renderer.js

@ -8,31 +8,6 @@ var replaceEntities = require('./common/utils').replaceEntities;
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 = {};
@ -42,14 +17,14 @@ var rules = {};
rules.blockquote_open = function (/* tokens, idx, options, env */) {
return '<blockquote>\n';
};
rules.blockquote_close = function (tokens, idx /*, options, env */) {
return '</blockquote>' + getBreak(tokens, idx);
rules.blockquote_close = function (/* tokens, idx, options, env */) {
return '</blockquote>\n';
};
rules.code = function (tokens, idx /*, options, env */) {
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>';
@ -91,7 +66,7 @@ rules.fence = function (tokens, idx, options, env, self) {
return '<pre><code' + langClass + '>'
+ highlighted
+ '</code></pre>' + getBreak(tokens, idx);
+ '</code></pre>\n';
};
rules.fence_custom = {};
@ -105,30 +80,35 @@ rules.heading_close = 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 */) {
return '<ul>\n';
};
rules.bullet_list_close = function (tokens, idx /*, options, env */) {
return '</ul>' + getBreak(tokens, idx);
rules.bullet_list_close = function (/* tokens, idx, options, env */) {
return '</ul>\n';
};
rules.list_item_open = function (/* tokens, idx, options, env */) {
rules.list_item_open = function (tokens, idx /*, options, env */) {
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 */) {
return '</li>\n';
};
rules.ordered_list_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];
return '<ol'
+ (token.order > 1 ? ' start="' + token.order + '"' : '')
+ '>\n';
if (tokens[idx].order > 1) {
return '<ol start="' + tokens[idx].order + '">\n';
}
return '<ol>\n';
};
rules.ordered_list_close = function (tokens, idx /*, options, env */) {
return '</ol>' + getBreak(tokens, idx);
rules.ordered_list_close = function (/* tokens, idx, options, env */) {
return '</ol>\n';
};
@ -136,8 +116,21 @@ rules.paragraph_open = function (tokens, idx /*, options, env */) {
return tokens[idx].tight ? '' : '<p>';
};
rules.paragraph_close = function (tokens, idx /*, options, env */) {
var addBreak = !(tokens[idx].tight && idx && tokens[idx - 1].type === 'inline' && !tokens[idx - 1].content);
return (tokens[idx].tight ? '' : '</p>') + (addBreak ? getBreak(tokens, idx) : '');
// We have 2 cases of "hidden" paragraphs
//
// 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';
};
rules.th_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];
return '<th'
+ (token.align ? ' style="text-align:' + token.align + '"' : '')
+ '>';
if (tokens[idx].align) {
return '<th style="text-align:' + tokens[idx].align + '">';
}
return '<th>';
};
rules.th_close = function (/* tokens, idx, options, env */) {
return '</th>';
};
rules.td_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];
return '<td'
+ (token.align ? ' style="text-align:' + token.align + '"' : '')
+ '>';
if (tokens[idx].align) {
return '<td style="text-align:' + tokens[idx].align + '">';
}
return '<td>';
};
rules.td_close = function (/* tokens, idx, options, env */) {
return '</td>';
@ -335,8 +328,6 @@ 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;
}

3
support/specsplit.js

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

1210
test/fixtures/commonmark/bad.txt

File diff suppressed because it is too large

963
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
.
<ul>
<li><table>
<li>
<table>
<thead>
<tr><th>foo</th><th>foo</th></tr>
</thead>

4
test/misc.js

@ -219,10 +219,10 @@ describe('Custom fences', function () {
it('should render differently overriden rule', function () {
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">' +
md.utils.escapeHtml(tokens[idx].content) +
'</div>' + self.getBreak(tokens, idx);
'</div>\n';
};
var text = '```foo bar\n' +

Loading…
Cancel
Save