Browse Source

Fixed fenses & updated tests

pull/14/head
Vitaly Puzrin 10 years ago
parent
commit
4e0453e4a5
  1. 44
      lib/lexer_block/fences.js
  2. 18
      lib/renderer.js
  3. 8
      test/fixtures/remarkable/code/fence_matching.html
  4. 0
      test/fixtures/remarkable/code/fence_matching.md
  5. 24
      test/fixtures/remarkable/code/fenced_code_blocks.html
  6. 0
      test/fixtures/remarkable/code/fenced_code_blocks.md
  7. 0
      test/fixtures/remarked_conflicting/code/gfm_code.html
  8. 0
      test/fixtures/remarked_conflicting/code/gfm_code.md
  9. 0
      test/fixtures/stmd_conflicting/Code/FenceMatching.html
  10. 10
      test/fixtures/stmd_conflicting/Code/FenceMatching.markdown
  11. 0
      test/fixtures/stmd_conflicting/Code/FencedCodeBlocks.html
  12. 35
      test/fixtures/stmd_conflicting/Code/FencedCodeBlocks.markdown
  13. 5
      test/remarked.js
  14. 4
      test/utils.js

44
lib/lexer_block/fences.js

@ -3,11 +3,13 @@
'use strict';
var skipEmptyLines = require('../helpers').skipEmptyLines;
var skipEmptyLines = require('../helpers').skipEmptyLines;
var skipSpaces = require('../helpers').skipSpaces;
var skipChars = require('../helpers').skipChars;
module.exports =function fences(state, startLine, endLine, silent) {
var marker, len, params, nextLine,
var marker, len, params, nextLine, mem,
pos = state.bMarks[startLine] + state.tShift[startLine],
max = state.eMarks[startLine];
@ -20,43 +22,41 @@ module.exports =function fences(state, startLine, endLine, silent) {
}
// scan marker length
len = 1;
while (state.src.charCodeAt(++pos) === marker) {
len++;
}
mem = pos;
pos = skipChars(state, pos, marker);
len = pos - mem;
if (len < 3) { return false; }
params = state.src.slice(pos, max).trim();
if (!/\S/.test(params)) { return false; }
// search end of block
nextLine = startLine;
do {
nextLine++;
if (nextLine > endLine) { return false; }
if (nextLine >= endLine) {
// unclosed block should be autoclosed by end of document.
if (state.blkLevel === 0) {
break;
}
return false;
}
pos = state.bMarks[nextLine] + state.tShift[nextLine];
pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];
max = state.eMarks[nextLine];
if (pos + 3 > max) { continue; }
if (state.src.charCodeAt(pos) !== marker) { continue; }
// check markers
if (state.src.charCodeAt(pos) !== marker &&
state.src.charCodeAt(pos + 1) !== marker &&
state.src.charCodeAt(pos + 2) !== marker) {
continue;
}
pos = skipChars(state, pos, marker);
pos += 3;
// closing code fence must be at least as long as the opening one
if (pos - mem < len) { continue; }
// make sure tail has spaces only
//pos = pos < max ? skipSpaces(state, pos) : pos;
// stmd allow any combonation of markers and spaces in tail
pos = skipSpaces(state, pos);
if (pos < max) { continue; }
@ -69,7 +69,7 @@ module.exports =function fences(state, startLine, endLine, silent) {
state.tokens.push({
type: 'fence',
params: params.split(/\s+/g),
params: params ? params.split(/\s+/g) : [],
startLine: startLine + 1,
endLine: nextLine
});

18
lib/renderer.js

@ -1,13 +1,16 @@
'use strict';
function escapeHTML(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
function escapeHtml(str) {
return str.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
var MD_UNESCAPE_RE = /\\([!"#$%&\'()*+,.\/:;<=>?@[\\\]^_`{|}~-])/g;
function unescapeMD(str) {
function unescapeMd(str) {
return str.replace(MD_UNESCAPE_RE, '$1');
}
@ -40,19 +43,20 @@ rules.bullet_list_close = function (state, token) {
rules.code = function (state, token) {
var content = joinLines(state, token.startLine, token.endLine).replace(/^ {4}/gm, '');
state.result += '<pre><code>' + escapeHTML(content) + '</code></pre>\n';
state.result += '<pre><code>' + escapeHtml(content) + '</code></pre>\n';
};
rules.fence = function (state, token) {
var content = joinLines(state, token.startLine, token.endLine);
var langMark = '';
var langPrefix = state.options.codeLangPrefix || '';
if (token.params.length) {
langMark = ' class="language-' + escapeHTML(token.params[0]) + '"';
langMark = ' class="' + langPrefix + escapeHtml(token.params[0]) + '"';
}
state.result += '<pre><code' + langMark + '>' + escapeHTML(content) + '</code></pre>\n';
state.result += '<pre><code' + langMark + '>' + escapeHtml(content) + '</code></pre>\n';
};
@ -86,7 +90,7 @@ rules.paragraph_close = function (state, token) {
rules.text = function (state, token) {
state.result += escapeHTML(unescapeMD(state.src.slice(token.begin, token.end)));
state.result += escapeHtml(unescapeMd(state.src.slice(token.begin, token.end)));
};

8
test/fixtures/remarkable/code/fence_matching.html

@ -0,0 +1,8 @@
<pre><code class="abc">```
</code></pre>
<pre><code class="blah">
`````
````
</code></pre>

0
test/fixtures/stmd_pending/Code/FenceMatching.markdown → test/fixtures/remarkable/code/fence_matching.md

24
test/fixtures/remarkable/code/fenced_code_blocks.html

@ -0,0 +1,24 @@
<p>This is a fenced code block:</p>
<pre><code class="haskell">pairs :: [(Int,Char)]
pairs = [(x,y) | x &lt;- [0..10], y &lt;- ['a'..'z']]
</code></pre>
<p>Here is one with tildes:</p>
<pre><code class="haskell">pairs :: [(Int,Char)]
pairs = [(x,y) | x &lt;- [0..10], y &lt;- ['a'..'z']]
</code></pre>
<p>More metadata:</p>
<pre><code class="haskell">pairs :: [(Int,Char)]
pairs = [(x,y) | x &lt;- [0..10], y &lt;- ['a'..'z']]
</code></pre>
<p>More backticks:</p>
<pre><code class="haskell">pairs :: [(Int,Char)]
pairs = [(x,y) | x &lt;- [0..10], y &lt;- ['a'..'z']]
backticks :: String
backticks = &quot;`````&quot;
</code></pre>
<p>Without an end:</p>
<pre><code>code with
no end
</code></pre>

0
test/fixtures/stmd_pending/Code/FencedCodeBlocks.markdown → test/fixtures/remarkable/code/fenced_code_blocks.md

0
test/fixtures/remarked_pending/gfm_code.html → test/fixtures/remarked_conflicting/code/gfm_code.html

0
test/fixtures/remarked_pending/gfm_code.md → test/fixtures/remarked_conflicting/code/gfm_code.md

0
test/fixtures/stmd_pending/Code/FenceMatching.html → test/fixtures/stmd_conflicting/Code/FenceMatching.html

10
test/fixtures/stmd_conflicting/Code/FenceMatching.markdown

@ -0,0 +1,10 @@
````abc
```
````
``````blah
`````
````
```````````

0
test/fixtures/stmd_pending/Code/FencedCodeBlocks.html → test/fixtures/stmd_conflicting/Code/FencedCodeBlocks.html

35
test/fixtures/stmd_conflicting/Code/FencedCodeBlocks.markdown

@ -0,0 +1,35 @@
This is a fenced code block:
```haskell
pairs :: [(Int,Char)]
pairs = [(x,y) | x <- [0..10], y <- ['a'..'z']]
```
Here is one with tildes:
~~~ haskell
pairs :: [(Int,Char)]
pairs = [(x,y) | x <- [0..10], y <- ['a'..'z']]
~~~
More metadata:
```haskell numberLines start=50
pairs :: [(Int,Char)]
pairs = [(x,y) | x <- [0..10], y <- ['a'..'z']]
```
More backticks:
```````` haskell
pairs :: [(Int,Char)]
pairs = [(x,y) | x <- [0..10], y <- ['a'..'z']]
backticks :: String
backticks = "`````"
`````````````
Without an end:
```
code with
no end

5
test/remarked.js

@ -12,6 +12,11 @@ var Remarked = require('../');
describe('remarked', function () {
var md = new Remarked();
// Set options, to give output more close to remarked
md.set({
codeLangPrefix: 'lang-'
});
utils.addTests(path.join(__dirname, 'fixtures/remarked_ok'), md);
});

4
test/utils.js

@ -41,11 +41,11 @@ function addTests(dir, md, skip) {
if (!skip) {
it(base, function () {
assert.strictEqual(right, md.render(src));
assert.strictEqual(md.render(src), right);
});
} else {
it.skip(base, function () {
assert.strictEqual(right, md.render(src));
assert.strictEqual(md.render(src), right);
});
}
}

Loading…
Cancel
Save