From 9728b685ec547c6cca78ecfe61cd5763d9635e40 Mon Sep 17 00:00:00 2001
From: Vitaly Puzrin
Date: Fri, 12 Sep 2014 15:26:33 +0400
Subject: [PATCH] Rewritten string fetch for inline tokenizer + list fixes
---
lib/helpers.js | 34 +-
lib/lexer_block/blockquote.js | 2 +-
lib/lexer_block/code.js | 3 +-
lib/lexer_block/fences.js | 6 +-
lib/lexer_block/heading.js | 2 +-
lib/lexer_block/lheading.js | 2 +-
lib/lexer_block/list.js | 52 ++-
lib/lexer_block/paragraph.js | 4 +-
lib/lexer_block/table.js | 4 +-
lib/lexer_inline.js | 11 +-
lib/renderer.js | 27 +-
lib/state.js | 7 +-
test/fixtures/stmd/bad.txt | 582 +++-------------------------------
test/fixtures/stmd/good.txt | 324 +++++++++++++++++++
14 files changed, 475 insertions(+), 585 deletions(-)
diff --git a/lib/helpers.js b/lib/helpers.js
index e771f9e..eae4bf3 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -49,16 +49,36 @@ function skipCharsBack(state, pos, code, min) {
}
// cut lines range from source.
-function getLines(state, begin, end, keepLastLF) {
- var last;
+function getLines(state, begin, end, indent, keepLastLF) {
+ var i, first, last, queue,
+ line = begin;
- if (keepLastLF) {
- last = end < state.lineMax ? state.bMarks[end] : state.src.length;
- } else {
- last = end < state.lineMax ? state.eMarks[end - 1] : state.src.length;
+ if (begin >= end) {
+ return '';
}
- return state.src.slice(state.bMarks[begin], last);
+ // Opt: don't use push queue for single line;
+ if (line + 1 === end) {
+ first = state.bMarks[line] + Math.min(state.tShift[line], indent);
+ last = keepLastLF ? state.bMarks[end] : state.eMarks[end - 1];
+ return state.src.slice(first, last);
+ }
+
+ queue = new Array(end - begin);
+
+ for (i = 0; line < end; line++, i++) {
+ first = state.bMarks[line] + Math.min(state.tShift[line], indent);
+
+ if (line + 1 < end || keepLastLF) {
+ last = state.bMarks[line + 1];
+ } else {
+ last = state.eMarks[line];
+ }
+
+ queue[i] = state.src.slice(first, last);
+ }
+
+ return queue.join('');
}
exports.isWhiteSpace = isWhiteSpace;
diff --git a/lib/lexer_block/blockquote.js b/lib/lexer_block/blockquote.js
index b18e8c5..d606d49 100644
--- a/lib/lexer_block/blockquote.js
+++ b/lib/lexer_block/blockquote.js
@@ -47,7 +47,7 @@ module.exports = function blockquote(state, startLine, endLine, silent) {
if (isEmpty(state, nextLine)) { break; }
nextLine++;
}
- subState = state.clone(getLines(state, startLine, nextLine, true)
+ subState = state.clone(getLines(state, startLine, nextLine, 0, true)
.replace(/^ {0,3}> ?/mg, ''));
state.lexerBlock.tokenize(subState, 0, insideLines);
nextLine = startLine = subState.line + startLine;
diff --git a/lib/lexer_block/code.js b/lib/lexer_block/code.js
index e569280..c4b6bf1 100644
--- a/lib/lexer_block/code.js
+++ b/lib/lexer_block/code.js
@@ -34,8 +34,7 @@ module.exports = function code(state, startLine, endLine, silent) {
state.tokens.push({
type: 'code',
- content: getLines(state, startLine, last, true).replace(
- new RegExp('^ {1,' + (4 + state.blkIndent) + '}', 'gm'), '')
+ content: getLines(state, startLine, last, 4 + state.blkIndent, true)
});
state.line = nextLine;
diff --git a/lib/lexer_block/fences.js b/lib/lexer_block/fences.js
index 57f519e..42fab96 100644
--- a/lib/lexer_block/fences.js
+++ b/lib/lexer_block/fences.js
@@ -85,11 +85,7 @@ module.exports = function fences(state, startLine, endLine, silent) {
state.tokens.push({
type: 'fence',
params: params ? params.split(/\s+/g) : [],
- content: len === 0 ?
- getLines(state, startLine + 1, nextLine, true)
- :
- getLines(state, startLine + 1, nextLine, true)
- .replace(RegExp('^ {1,' + len + '}', 'mg'), '')
+ content: getLines(state, startLine + 1, nextLine, len, true)
});
state.line = nextLine + (haveEndMarker ? 1 : 0);
diff --git a/lib/lexer_block/heading.js b/lib/lexer_block/heading.js
index 6023e47..f61f02a 100644
--- a/lib/lexer_block/heading.js
+++ b/lib/lexer_block/heading.js
@@ -58,7 +58,7 @@ module.exports = function heading(state, startLine, endLine, silent) {
state.tokens.push({ type: 'heading_open', level: level });
// only if header is not empty
if (pos < max) {
- state.lexerInline.tokenize(state, pos, max);
+ state.lexerInline.tokenize(state, state.src.slice(pos, max));
}
state.tokens.push({ type: 'heading_close', level: level });
diff --git a/lib/lexer_block/lheading.js b/lib/lexer_block/lheading.js
index 1b1bb03..0839b0b 100644
--- a/lib/lexer_block/lheading.js
+++ b/lib/lexer_block/lheading.js
@@ -37,7 +37,7 @@ module.exports = function lheading(state, startLine, endLine, silent) {
max = skipCharsBack(state, state.eMarks[startLine], 0x20/* space */, pos);
state.tokens.push({ type: 'heading_open', level: marker === 0x3D/* = */ ? 1 : 2 });
- state.lexerInline.tokenize(state, pos, max);
+ state.lexerInline.tokenize(state, state.src.slice(pos, max));
state.tokens.push({ type: 'heading_close', level: marker === 0x3D/* = */ ? 1 : 2 });
state.line = next + 1;
diff --git a/lib/lexer_block/list.js b/lib/lexer_block/list.js
index 4e0a084..78e7279 100644
--- a/lib/lexer_block/list.js
+++ b/lib/lexer_block/list.js
@@ -85,11 +85,12 @@ module.exports = function list(state, startLine, endLine, silent) {
max,
indentAfterMarker,
markerValue,
+ markerCharCode,
isOrdered,
contentStart,
listTokIdx,
- endOfList;
- //rules_named = state.lexerBlock.rules_named;
+ prevEmptyEnd,
+ rules_named = state.lexerBlock.rules_named;
// Detect list type and position after marker
if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) {
@@ -99,6 +100,8 @@ module.exports = function list(state, startLine, endLine, silent) {
} else {
return false;
}
+ // We should terminate list on style change. Remember first one to compare.
+ markerCharCode = state.src.charCodeAt(posAfterMarker - 1);
// For validation mode we can terminate immediately
if (silent) { return true; }
@@ -128,18 +131,9 @@ module.exports = function list(state, startLine, endLine, silent) {
//
nextLine = startLine;
- endOfList = false;
-
- while (nextLine < endLine && !endOfList) {
- if (state.tShift[startLine] < state.blkIndent) { return -1; }
- if (isOrdered) {
- posAfterMarker = skipOrderedListMarker(state, nextLine);
- if (posAfterMarker < 0) { break; }
- } else {
- posAfterMarker = skipBulletListMarker(state, nextLine);
- if (posAfterMarker < 0) { break; }
- }
+ prevEmptyEnd = false;
+ while (nextLine < endLine) {
contentStart = skipSpaces(state, posAfterMarker);
max = state.eMarks[nextLine];
@@ -165,18 +159,22 @@ module.exports = function list(state, startLine, endLine, silent) {
// Run sublexer & write tokens
state.tokens.push({ type: 'list_item_open' });
- nextLine++;
+ //nextLine++;
oldIndent = state.blkIndent;
oldTight = state.tight;
state.blkIndent = state.tShift[startLine] = indent;
+ state.tight = true;
state.lexerBlock.tokenize(state, startLine, endLine, true);
- // If any of list item is loose, mark list as loose
- if (!state.tight || isEmpty(state, state.line - 1)) {
+ // If any of list item is tight, mark list as tight
+ if (!state.tight || prevEmptyEnd) {
state.tokens[listTokIdx].tight = false;
}
+ // Item become loose if finish with empty line,
+ // but we should filter last element, because it means list finish
+ prevEmptyEnd = (state.line - startLine) > 1 && isEmpty(state, state.line - 1);
state.blkIndent = state.tShift[startLine] = oldIndent;
state.tight = oldTight;
@@ -195,6 +193,28 @@ module.exports = function list(state, startLine, endLine, silent) {
break;
}
}
+
+ //
+ // Try to ckeck if list is terminated or continued.
+ //
+
+ // fail if terminating block found
+ if (rules_named.fences(state, nextLine, endLine, true)) { break; }
+ if (rules_named.blockquote(state, nextLine, endLine, true)) { break; }
+ if (rules_named.hr(state, nextLine, endLine, true)) { break; }
+
+ // fail if list has another type
+ if (isOrdered) {
+ posAfterMarker = skipOrderedListMarker(state, nextLine);
+ if (posAfterMarker < 0) { break; }
+ } else {
+ posAfterMarker = skipBulletListMarker(state, nextLine);
+ if (posAfterMarker < 0) { break; }
+ }
+
+ if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { break; }
+
+
}
// Finilize list
diff --git a/lib/lexer_block/paragraph.js b/lib/lexer_block/paragraph.js
index 2ccfff2..a3ac70b 100644
--- a/lib/lexer_block/paragraph.js
+++ b/lib/lexer_block/paragraph.js
@@ -4,6 +4,7 @@
var isEmpty = require('../helpers').isEmpty;
+var getLines = require('../helpers').getLines;
module.exports = function paragraph(state, startLine/*, endLine*/) {
@@ -32,8 +33,7 @@ module.exports = function paragraph(state, startLine/*, endLine*/) {
state.tokens.push({ type: 'paragraph_open' });
state.lexerInline.tokenize(
state,
- state.bMarks[startLine] + state.tShift[startLine],
- state.eMarks[nextLine - 1]
+ getLines(state, startLine, nextLine, state.blkIndent, false)
);
state.tokens.push({ type: 'paragraph_close' });
diff --git a/lib/lexer_block/table.js b/lib/lexer_block/table.js
index de6a158..eeb1576 100644
--- a/lib/lexer_block/table.js
+++ b/lib/lexer_block/table.js
@@ -53,7 +53,7 @@ module.exports = function table(state, startLine, endLine, silent) {
for (i = 0; i < rows.length; i++) {
state.tokens.push({ type: 'th_open', align: aligns[i] });
subState = state.clone(rows[i].trim());
- state.lexerInline.tokenize(subState, 0, subState.eMarks[0]);
+ state.lexerInline.tokenize(subState, subState.src);
state.tokens.push({ type: 'th_close' });
}
state.tokens.push({ type: 'tr_close' });
@@ -67,7 +67,7 @@ module.exports = function table(state, startLine, endLine, silent) {
for (i = 0; i < rows.length; i++) {
state.tokens.push({ type: 'td_open', align: aligns[i] });
subState = state.clone(rows[i].replace(/^\|? *| *\|?$/g, ''));
- state.lexerInline.tokenize(subState, 0, subState.eMarks[0]);
+ state.lexerInline.tokenize(subState, subState.src);
state.tokens.push({ type: 'td_close' });
}
state.tokens.push({ type: 'tr_close' });
diff --git a/lib/lexer_inline.js b/lib/lexer_inline.js
index f65e821..06bf2fe 100644
--- a/lib/lexer_inline.js
+++ b/lib/lexer_inline.js
@@ -10,10 +10,10 @@ var rules = [];
// Pure text
-rules.push(function text(state, begin, end) {
+rules.push(function text(state, str, begin, end) {
state.tokens.push({
type: 'text',
- content: state.src.slice(begin, end).replace(/^ {1,}/mg, '')
+ content: str.slice(begin, end).replace(/^ {1,}/mg, '')
});
state.pos = end;
@@ -107,11 +107,12 @@ LexerInline.prototype.after = function (name, fn) {
// Generate tokens for input range
//
-LexerInline.prototype.tokenize = function (state, begin, end) {
+LexerInline.prototype.tokenize = function (state, str) {
var ok, i,
rules = this.rules,
len = this.rules.length,
- pos = begin;
+ pos = 0,
+ end = str.length;
while (pos < end) {
@@ -123,7 +124,7 @@ LexerInline.prototype.tokenize = function (state, begin, end) {
// - return true
for (i = 0; i < len; i++) {
- ok = rules[i](state, pos, end);
+ ok = rules[i](state, str, pos, end);
if (ok) { break; }
}
diff --git a/lib/renderer.js b/lib/renderer.js
index 7cdb15b..25c88eb 100644
--- a/lib/renderer.js
+++ b/lib/renderer.js
@@ -40,12 +40,12 @@ rules.blockquote_close = function (state, token, idx) {
};
-rules.code = function (state, token) {
- state.result += '' + escapeHtml(token.content) + '
\n';
+rules.code = function (state, token, idx) {
+ state.result += '' + escapeHtml(token.content) + '
' + getBreak(state, idx);
};
-rules.fence = function (state, token) {
+rules.fence = function (state, token, idx) {
var langMark = '';
var langPrefix = state.options.codeLangPrefix || '';
@@ -53,7 +53,9 @@ rules.fence = function (state, token) {
langMark = ' class="' + langPrefix + escapeHtml(token.params[0]) + '"';
}
- state.result += '' + escapeHtml(token.content) + '
\n';
+ state.result += ''
+ + escapeHtml(token.content)
+ + '
' + getBreak(state, idx);
};
@@ -130,7 +132,7 @@ rules.td_close = function (state /*, token, idx*/) {
};
-rules.text = function (state, token) {
+rules.text = function (state, token /*, idx*/) {
state.result += escapeHtml(unescapeMd(token.content));
};
@@ -142,7 +144,7 @@ function Renderer() {
}
Renderer.prototype.render = function (state) {
- var i, len, rule, name,
+ var i, len, rule, name, next,
tokens = state.tokens,
rules = this.rules,
tightStack = [];
@@ -170,7 +172,18 @@ Renderer.prototype.render = function (state) {
// in tight mode just ignore paragraphs for lists
// TODO - track right nesting to blockquotes
- if ((name === 'paragraph_open' || name === 'paragraph_close') && state.tight) {
+ if (name === 'paragraph_open' && state.tight) {
+ continue;
+ }
+ if (name === 'paragraph_close' && state.tight) {
+ // 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') {
+ state.result += '\n';
+ }
+ }
+
continue;
}
rule(state, tokens[i], i);
diff --git a/lib/state.js b/lib/state.js
index cf60342..339d1d3 100644
--- a/lib/state.js
+++ b/lib/state.js
@@ -71,6 +71,11 @@ function State(src, lexerBlock, lexerInline, renderer, tokens, options) {
this.tShift.push(indent);
}
+ // Push fake entry to simplify cache bounds checks
+ this.bMarks.push(s.length);
+ this.eMarks.push(s.length);
+ this.tShift.push(0);
+
// inline lexer variables
this.pos = 0; // char index in src
@@ -78,7 +83,7 @@ function State(src, lexerBlock, lexerInline, renderer, tokens, options) {
this.blkLevel = 0;
this.blkIndent = 0;
this.line = 0; // line index in src
- this.lineMax = this.bMarks.length;
+ this.lineMax = this.bMarks.length - 1; // don't count last fake line
this.tight = false; // loose/tight mode for lists
// renderer
diff --git a/test/fixtures/stmd/bad.txt b/test/fixtures/stmd/bad.txt
index 8c0ff7f..a60050a 100644
--- a/test/fixtures/stmd/bad.txt
+++ b/test/fixtures/stmd/bad.txt
@@ -699,75 +699,6 @@ error:
bbb
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2147
-
-.
-> foo
- bar
-.
-
-foo
-
-
-bar
-
-.
-
-error:
-
-
-foo
-bar
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2159
-
-.
-> ```
-foo
-```
-.
-
-
-
-foo
-
-.
-
-error:
-
-
-foo
-
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2236
-
-.
-> foo
->
-> bar
-.
-
-foo
-bar
-
-.
-
-error:
-
-
-foo
-
-
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2414
@@ -794,63 +725,13 @@ error:
A paragraph
-with two lines.
+with two lines.
+indented code
+
+> A block quote.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2540
-
-.
-- foo
-
- bar
-
-- foo
-
-
- bar
-
-- ```
- foo
-
-
- bar
- ```
-.
-
-bar
-
-.
-
-error:
-
-
-
-bar
-
-bar
-
-
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2574
@@ -882,55 +763,8 @@ error:
foo
bar
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2612
-
-.
-- foo
-
- bar
-.
-
-.
-
-error:
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2626
-
-.
- 10. foo
-
- bar
-.
-
-foo
-bar
-
-
-.
-
-error:
-
-
-foo
-bar
-
+baz
+> bam
@@ -956,7 +790,10 @@ src line: 2656
error:
-indented code
+indented code
+paragraph
+more code
+
@@ -982,7 +819,10 @@ src line: 2675
error:
-indented code
+indented code
+paragraph
+more code
+
@@ -1012,7 +852,10 @@ error:
A paragraph
-with two lines.
+with two lines.
+indented code
+
+> A block quote.
@@ -1042,7 +885,10 @@ error:
A paragraph
-with two lines.
+with two lines.
+indented code
+
+> A block quote.
@@ -1072,7 +918,10 @@ error:
A paragraph
-with two lines.
+with two lines.
+indented code
+
+> A block quote.
@@ -1102,7 +951,10 @@ error:
A paragraph
-with two lines.
+with two lines.
+indented code
+
+> A block quote.
@@ -1123,17 +975,6 @@ continued here.
.
-error:
-
-
-
-
-Blockquote
-continued here.
-
-
-
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2880
@@ -1151,156 +992,6 @@ continued here.
.
-error:
-
-
-
-
-Blockquote
-continued here.
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2904
-
-.
-- foo
- - bar
- - baz
-.
-
-.
-
-error:
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 2936
-
-.
-10) foo
- - bar
-.
-
-- foo
-
-
-.
-
-error:
-
-
-- foo
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3222
-
-.
-- foo
-- bar
-+ baz
-.
-
-
-.
-
-error:
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3236
-
-.
-1. foo
-2. bar
-3) baz
-.
-
-- foo
-- bar
-
-
-- baz
-
-.
-
-error:
-
-
-- foo
-- bar
-- baz
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3253
-
-.
-- foo
-
-- bar
-
-
-- baz
-.
-
-
-.
-
-error:
-
-
-
-
-
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3292
@@ -1328,102 +1019,14 @@ src line: 3292
error:
- bim
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3336
-
-.
-- foo
-
- notcode
-
-- foo
-
-
- code
-.
-
-code
-
-.
-
-error:
-
-
-
-code
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3383
-
-.
-- a
-- b
-
-- c
-.
-
-.
-
-error:
-
-
-
-
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3398
-
-.
-* a
-*
-
-* c
-.
+foo
-.
-
-error:
-
+bar
-
+
@@ -1454,39 +1057,6 @@ error:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3446
-
-.
-- a
-- ```
- b
-
-
- ```
-- c
-.
-
-.
-
-error:
-
-
-- c
-
-
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3469
@@ -1510,11 +1080,12 @@ src line: 3469
error:
-- a
@@ -1573,36 +1144,11 @@ error:
- a
b
c
-
-
+
- d
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3536
-
-.
-- a
- - b
-.
-
-.
-
-error:
-
-
-
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3550
@@ -1624,7 +1170,8 @@ src line: 3550
error:
-- foo
+- foo
+
baz
@@ -1660,16 +1207,16 @@ src line: 3565
error:
+- a
+
@@ -4462,39 +4009,4 @@ error:
foo
baz
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 444
-
-.
-* Foo
-* * *
-* Bar
-.
-
-
-
-.
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-src line: 3274
-
-.
-- foo
-
-
- bar
-- baz
-.
-
-bar
-
-.
diff --git a/test/fixtures/stmd/good.txt b/test/fixtures/stmd/good.txt
index 8c64089..baf34bd 100644
--- a/test/fixtures/stmd/good.txt
+++ b/test/fixtures/stmd/good.txt
@@ -210,6 +210,23 @@ bar
bar
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 444
+
+.
+* Foo
+* * *
+* Bar
+.
+
+
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 460
@@ -1312,6 +1329,36 @@ src line: 2133
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2147
+
+.
+> foo
+ bar
+.
+
+foo
+
+
+bar
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2159
+
+.
+> ```
+foo
+```
+.
+
+
+
+foo
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2173
@@ -1376,6 +1423,20 @@ bar
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2236
+
+.
+> foo
+>
+> bar
+.
+
+foo
+bar
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2249
@@ -1613,6 +1674,71 @@ src line: 2521
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2540
+
+.
+- foo
+
+ bar
+
+- foo
+
+
+ bar
+
+- ```
+ foo
+
+
+ bar
+ ```
+.
+
+bar
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2612
+
+.
+- foo
+
+ bar
+.
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2626
+
+.
+ 10. foo
+
+ bar
+.
+
+foo
+bar
+
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2642
@@ -1703,6 +1829,25 @@ with two lines.
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2904
+
+.
+- foo
+ - bar
+ - baz
+.
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2922
@@ -1718,6 +1863,21 @@ src line: 2922
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2936
+
+.
+10) foo
+ - bar
+.
+
+- foo
+
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 2950
@@ -1787,6 +1947,79 @@ src line: 3000
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3222
+
+.
+- foo
+- bar
++ baz
+.
+
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3236
+
+.
+1. foo
+2. bar
+3) baz
+.
+
+- foo
+- bar
+
+
+- baz
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3253
+
+.
+- foo
+
+- bar
+
+
+- baz
+.
+
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3274
+
+.
+- foo
+
+
+ bar
+- baz
+.
+
+bar
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3318
@@ -1808,6 +2041,28 @@ src line: 3318
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3336
+
+.
+- foo
+
+ notcode
+
+- foo
+
+
+ code
+.
+
+code
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3360
@@ -1831,6 +2086,38 @@ src line: 3360
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3383
+
+.
+- a
+- b
+
+- c
+.
+
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3398
+
+.
+* a
+*
+
+* c
+.
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3415
@@ -1849,6 +2136,28 @@ src line: 3415
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3446
+
+.
+- a
+- ```
+ b
+
+
+ ```
+- c
+.
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3528
@@ -1860,6 +2169,21 @@ src line: 3528
.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 3536
+
+.
+- a
+ - b
+.
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 3607