diff --git a/lib/rules_block/list.js b/lib/rules_block/list.js index 585f51d..f6d7c8d 100644 --- a/lib/rules_block/list.js +++ b/lib/rules_block/list.js @@ -114,9 +114,9 @@ module.exports = function list(state, startLine, endLine, silent) { max, nextLine, offset, - oldIndent, - oldLIndent, + oldListIndent, oldParentType, + oldSCount, oldTShift, oldTight, pos, @@ -132,6 +132,18 @@ module.exports = function list(state, startLine, endLine, silent) { // if it's indented more than 3 spaces, it should be a code block if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } + // Special case: + // - item 1 + // - item 2 + // - item 3 + // - item 4 + // - this one is a paragraph continuation + if (state.listIndent >= 0 && + state.sCount[startLine] - state.listIndent >= 4 && + state.sCount[startLine] < state.blkIndent) { + return false; + } + // limit conditions when list can interrupt // a paragraph (validation mode only) if (silent && state.parentType === 'paragraph') { @@ -243,11 +255,19 @@ module.exports = function list(state, startLine, endLine, silent) { token.markup = String.fromCharCode(markerCharCode); token.map = itemLines = [ startLine, 0 ]; - oldIndent = state.blkIndent; + // change current state, then restore it after parser subcall oldTight = state.tight; oldTShift = state.tShift[startLine]; - oldLIndent = state.sCount[startLine]; + oldSCount = state.sCount[startLine]; + + // - example list + // ^ listIndent position will be here + // ^ blkIndent position will be here + // + oldListIndent = state.listIndent; + state.listIndent = state.blkIndent; state.blkIndent = indent; + state.tight = true; state.tShift[startLine] = contentStart - state.bMarks[startLine]; state.sCount[startLine] = offset; @@ -273,9 +293,10 @@ module.exports = function list(state, startLine, endLine, silent) { // but we should filter last element, because it means list finish prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1); - state.blkIndent = oldIndent; + state.blkIndent = state.listIndent; + state.listIndent = oldListIndent; state.tShift[startLine] = oldTShift; - state.sCount[startLine] = oldLIndent; + state.sCount[startLine] = oldSCount; state.tight = oldTight; token = state.push('list_item_close', 'li', -1); @@ -292,6 +313,9 @@ module.exports = function list(state, startLine, endLine, silent) { // if (state.sCount[nextLine] < state.blkIndent) { break; } + // if it's indented more than 3 spaces, it should be a code block + if (state.sCount[startLine] - state.blkIndent >= 4) { break; } + // fail if terminating block found terminate = false; for (i = 0, l = terminatorRules.length; i < l; i++) { diff --git a/lib/rules_block/state_block.js b/lib/rules_block/state_block.js index 3119ff1..1b21483 100644 --- a/lib/rules_block/state_block.js +++ b/lib/rules_block/state_block.js @@ -40,12 +40,13 @@ function StateBlock(src, md, env, tokens) { this.bsCount = []; // block parser variables - this.blkIndent = 0; // required block content indent - // (for example, if we are in list) + this.blkIndent = 0; // required block content indent (for example, if we are + // inside a list, it would be positioned after list marker) this.line = 0; // line index in src this.lineMax = 0; // lines count this.tight = false; // loose/tight mode for lists this.ddIndent = -1; // indent of the current dd block (-1 if there isn't any) + this.listIndent = -1; // indent of the current list block (-1 if there isn't any) // can be 'blockquote', 'list', 'root', 'paragraph' or 'reference' // used in lists to determine if they interrupt a paragraph diff --git a/test/fixtures/commonmark/bad.txt b/test/fixtures/commonmark/bad.txt index 6123b52..e69de29 100644 --- a/test/fixtures/commonmark/bad.txt +++ b/test/fixtures/commonmark/bad.txt @@ -1,67 +0,0 @@ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -src line: 5176 - -. -- a - - b - - c - - d - - e -. -
a
-b
-3. c
-
-.
-
-error:
-
-a
-b
-c
-a
+b
+3. c
+
+.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5219