Browse Source

Fix edge case for list indents

Now list items cannot be indented more than 4 spaces from the first,
as per commonmark 0.29 spec:
 - item 1
  - item 2
   - item 3
    - item 4
     - this one is a paragraph continuation
pull/570/head
Alex Kocharin 6 years ago
parent
commit
fa7a419161
  1. 36
      lib/rules_block/list.js
  2. 5
      lib/rules_block/state_block.js
  3. 67
      test/fixtures/commonmark/bad.txt
  4. 41
      test/fixtures/commonmark/good.txt

36
lib/rules_block/list.js

@ -114,9 +114,9 @@ module.exports = function list(state, startLine, endLine, silent) {
max, max,
nextLine, nextLine,
offset, offset,
oldIndent, oldListIndent,
oldLIndent,
oldParentType, oldParentType,
oldSCount,
oldTShift, oldTShift,
oldTight, oldTight,
pos, 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 it's indented more than 3 spaces, it should be a code block
if (state.sCount[startLine] - state.blkIndent >= 4) { return false; } 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 // limit conditions when list can interrupt
// a paragraph (validation mode only) // a paragraph (validation mode only)
if (silent && state.parentType === 'paragraph') { if (silent && state.parentType === 'paragraph') {
@ -243,11 +255,19 @@ module.exports = function list(state, startLine, endLine, silent) {
token.markup = String.fromCharCode(markerCharCode); token.markup = String.fromCharCode(markerCharCode);
token.map = itemLines = [ startLine, 0 ]; token.map = itemLines = [ startLine, 0 ];
oldIndent = state.blkIndent; // change current state, then restore it after parser subcall
oldTight = state.tight; oldTight = state.tight;
oldTShift = state.tShift[startLine]; 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.blkIndent = indent;
state.tight = true; state.tight = true;
state.tShift[startLine] = contentStart - state.bMarks[startLine]; state.tShift[startLine] = contentStart - state.bMarks[startLine];
state.sCount[startLine] = offset; 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 // but we should filter last element, because it means list finish
prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1); 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.tShift[startLine] = oldTShift;
state.sCount[startLine] = oldLIndent; state.sCount[startLine] = oldSCount;
state.tight = oldTight; state.tight = oldTight;
token = state.push('list_item_close', 'li', -1); 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 (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 // fail if terminating block found
terminate = false; terminate = false;
for (i = 0, l = terminatorRules.length; i < l; i++) { for (i = 0, l = terminatorRules.length; i < l; i++) {

5
lib/rules_block/state_block.js

@ -40,12 +40,13 @@ function StateBlock(src, md, env, tokens) {
this.bsCount = []; this.bsCount = [];
// block parser variables // block parser variables
this.blkIndent = 0; // required block content indent this.blkIndent = 0; // required block content indent (for example, if we are
// (for example, if we are in list) // inside a list, it would be positioned after list marker)
this.line = 0; // line index in src this.line = 0; // line index in src
this.lineMax = 0; // lines count this.lineMax = 0; // lines count
this.tight = false; // loose/tight mode for lists this.tight = false; // loose/tight mode for lists
this.ddIndent = -1; // indent of the current dd block (-1 if there isn't any) 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' // can be 'blockquote', 'list', 'root', 'paragraph' or 'reference'
// used in lists to determine if they interrupt a paragraph // used in lists to determine if they interrupt a paragraph

67
test/fixtures/commonmark/bad.txt

@ -1,67 +0,0 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5176
.
- a
- b
- c
- d
- e
.
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d
- e</li>
</ul>
.
error:
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
</ul>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5196
.
1. a
2. b
3. c
.
<ol>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
</ol>
<pre><code>3. c
</code></pre>
.
error:
<ol>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
<li>
<p>c</p>
</li>
</ol>

41
test/fixtures/commonmark/good.txt

@ -4027,6 +4027,47 @@ src line: 5152
</ol> </ol>
. .
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5176
.
- a
- b
- c
- d
- e
.
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d
- e</li>
</ul>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5196
.
1. a
2. b
3. c
.
<ol>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
</ol>
<pre><code>3. c
</code></pre>
.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src line: 5219 src line: 5219

Loading…
Cancel
Save