diff --git a/lib/lexer_block.js b/lib/lexer_block.js index edaa2a1..6f5194d 100644 --- a/lib/lexer_block.js +++ b/lib/lexer_block.js @@ -18,6 +18,7 @@ rules.push(require('./lexer_block/hr')); rules.push(require('./lexer_block/list')); rules.push(require('./lexer_block/heading')); rules.push(require('./lexer_block/lheading')); +rules.push(require('./lexer_block/html')); rules.push(require('./lexer_block/table')); rules.push(require('./lexer_block/paragraph')); diff --git a/lib/lexer_block/html.js b/lib/lexer_block/html.js new file mode 100644 index 0000000..e39178c --- /dev/null +++ b/lib/lexer_block/html.js @@ -0,0 +1,98 @@ +// HTML block + +'use strict'; + + +var isEmpty = require('../helpers').isEmpty; +var getLines = require('../helpers').getLines; + + +function replace(regex, options) { + regex = regex.source; + options = options || ''; + + return function self(name, val) { + if (!name) { + return new RegExp(regex, options); + } + val = val.source || val; + val = val.replace(/(^|[^\[])\^/g, '$1'); + regex = regex.replace(name, val); + return self; + }; +} + + +var attr_name = /[a-zA-Z_:][a-zA-Z0-9:._-]*/; + +var unquoted = /[^"'=<>`\x00-\x20]+/; +var single_quoted = /'[^']*'/; +var double_quoted = /"[^"]*"/; + +/*eslint no-spaced-func:0*/ +var attr_value = replace(/(?:unquoted|single_quoted|double_quoted)/) + ('unquoted', unquoted) + ('single_quoted', single_quoted) + ('double_quoted', double_quoted) + (); + +var attribute = replace(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/) + ('attr_name', attr_name) + ('attr_value', attr_value) + (); + +var open_tag = replace(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/) + ('attribute', attribute) + (); + +var close_tag = /<\/[A-Za-z][A-Za-z0-9]*\s*>/; +var comment = //; +var processing = /<[?].*?[?]>/; +var declaration = /]*>/; +var cdata = /])*\]\]>/; + +var html_tag = replace(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/, 'i') + ('open_tag', open_tag) + ('close_tag', close_tag) + ('comment', comment) + ('processing', processing) + ('declaration', declaration) + ('cdata', cdata) + (); + + +module.exports = function html(state, startLine, endLine, silent) { + var nextLine, + pos = state.bMarks[startLine], + max = state.eMarks[startLine], + shift = state.tShift[startLine]; + + pos += shift; + + if (pos + 3 >= max || + shift > 3 || + state.blkLevel > 0) { return false; } + + if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; } + + // TODO: (?) optimize check. + + nextLine = startLine + 1; + while (nextLine < state.lineMax && !isEmpty(state, nextLine)) { + nextLine++; + } + + if (!html_tag.test(state.src.slice(pos, state.eMarks[nextLine - 1]).replace(/\n/g,' '))) { + return false; + } + + if (silent) { return true; } + + state.tokens.push({ + type: 'html', + content: getLines(state, startLine, nextLine, 0, true) + }); + + state.line = nextLine; + return true; +}; diff --git a/lib/lexer_block/paragraph.js b/lib/lexer_block/paragraph.js index 0115ccf..3c8bf67 100644 --- a/lib/lexer_block/paragraph.js +++ b/lib/lexer_block/paragraph.js @@ -28,6 +28,7 @@ module.exports = function paragraph(state, startLine/*, endLine*/) { // setex header can't interrupt paragraph // if (rules_named.lheading(state, nextLine, endLine, true)) { break; } if (rules_named.blockquote(state, nextLine, endLine, true)) { break; } + if (rules_named.html(state, nextLine, endLine, true)) { break; } if (rules_named.table(state, nextLine, endLine, true)) { break; } //if (rules_named.tag(state, nextLine, endLine, true)) { break; } //if (rules_named.def(state, nextLine, endLine, true)) { break; } diff --git a/lib/renderer.js b/lib/renderer.js index 25c88eb..b6a5eca 100644 --- a/lib/renderer.js +++ b/lib/renderer.js @@ -137,6 +137,11 @@ rules.text = function (state, token /*, idx*/) { }; +rules.html = function (state, token /*, idx*/) { + state.result += token.content; +}; + + // Renderer class function Renderer() { // Clone rules object to allow local modifications @@ -169,6 +174,14 @@ Renderer.prototype.render = function (state) { if (name === 'ordered_list_close' || name === 'bullet_list_close') { state.tight = tightStack.pop(); } + if (name === 'blockquote_open') { + tightStack.push(state.tight); + state.tight = false; + } + if (name === 'blockquote_close') { + state.tight = tightStack.pop(); + } + // in tight mode just ignore paragraphs for lists // TODO - track right nesting to blockquotes @@ -179,7 +192,9 @@ Renderer.prototype.render = function (state) { // Quick hack - texts should have LF if followed by blocks if (i + 1 < state.tokens.length) { next = state.tokens[i + 1].type; - if (next === 'bullet_list_open' || next === 'ordered_list_open') { + if (next === 'bullet_list_open' || + next === 'ordered_list_open' || + next === 'blockquote_open') { state.result += '\n'; } } diff --git a/test/fixtures/stmd/bad.txt b/test/fixtures/stmd/bad.txt index a60050a..ddfbb43 100644 --- a/test/fixtures/stmd/bad.txt +++ b/test/fixtures/stmd/bad.txt @@ -80,62 +80,6 @@ error: foo
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1373 - -. -- hi - | -
- hi - | -
okay.
-. - -error: - -<table> -<tr> -<td> -hi -</td> -</tr> -</table>
-okay.
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1394 - -. -<div> -*hello* -<foo><a>
- - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1406 @@ -153,187 +97,9 @@ src line: 1406 error: -<DIV CLASS="foo">
+*Markdown*
-</DIV>
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1422 - -. - -``` c -int x = 33; -``` -. - -``` c -int x = 33; -``` -. - -error: - -<div></div>
-int x = 33;
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 1436
-
-.
-
-.
-
-.
-
-error:
-
-<!-- Foo -bar -baz -->
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1448 - -. - -. - -. - -error: - -<?php -echo 'foo' -?>
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1460 - -. - -. - -. - -error: - -<![CDATA[ -function matchwo(a,b) -{ -if (a < b && a < 0) then -{ -return 1; -} -else -{ -return 0; -} -} -]]>
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1492 - -. - - - -. - -<!-- foo -->
-
-.
-
-error:
-
-<!-- foo -->
-<!-- foo -->
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 1505
-
-.
-Foo
-Foo
-Foo -<div> -bar -</div>
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1520 - -. -<div> -bar -</div> -*foo*
+<div>
-*Emphasized* text.
-</div>
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1584 - -. -*Emphasized* text.
<div> -*Emphasized* text. -</div>
- - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 1605 - -. --Hi - | - -
-Hi - | -
<table>
-<tr>
-<td> -Hi -</td>
-</tr>
-</table>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -501,9 +211,9 @@ src line: 1678 error: -[Foo bar]: -<my url> -'title'
+[Foo bar]:
+[Foo bar]
@@ -728,7 +438,10 @@ error: with two lines.indented code
-> A block quote.
++@@ -764,65 +477,10 @@ error:+> A block quote. +
bar
baz
-> bam
- - - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 2656 - -. -1. indented code - - paragraph - - more code -. -indented code
-
-paragraph
-more code
-
indented code
-paragraph
-more code
-
indented code
+
+> bam
-paragraph
-more code
-
indented code
-paragraph
-more code
-
indented code
-> A block quote.
++@@ -888,7 +549,10 @@ error: with two lines.+> A block quote. +
indented code
-> A block quote.
++@@ -921,7 +585,10 @@ error: with two lines.+> A block quote. +
indented code
-> A block quote.
++@@ -954,7 +621,10 @@ error: with two lines.+> A block quote. +
indented code
-> A block quote.
++@@ -1089,66 +759,6 @@ error: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 3489 - -. -* a - > b - > -* c -. -+> A block quote. +
-b
-
-b
--b
-
c
-
-b-
c
-
<a href="/bar/)">
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1423,7 +1033,7 @@ src line: 3791 error: -<a href="öö.html">
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1646,7 +1256,7 @@ src line: 3954 error: -<a href="`">`
+` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3653,7 +3263,7 @@ src line: 5627 error: -<a><bab><c2c>
+<a/><b2/>
+<a /><b2 -data="foo" >
+<a foo="bar" bam = 'baz <em>"</em>' -_boolean zoop:33=zoop:33 />
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3717,8 +3327,8 @@ src line: 5705 error: -</a> -</foo >
+<a href="ö">
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3805,7 +3415,7 @@ src line: 5771 error: -<a href="*">
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3972,8 +3582,8 @@ bar"> error: -<a href="foo -bar">
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3989,8 +3599,8 @@ bar"> error: -<a href="foo\ -bar">
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/test/fixtures/stmd/good.txt b/test/fixtures/stmd/good.txt index baf34bd..25be3d4 100644 --- a/test/fixtures/stmd/good.txt +++ b/test/fixtures/stmd/good.txt @@ -1042,6 +1042,198 @@ src line: 1338 . +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1373 + +. ++ hi + | +
+ hi + | +
okay.
+. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1394 + +. +<!-- foo -->
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1505
+
+.
+Foo
+Foo
++Hi + | + +
+Hi + | +
indented code
+
+paragraph
+more code
+
indented code
+
+paragraph
+more code
+
+b
+
++b
+
c
+