Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix items between lists #1936

Merged
merged 7 commits into from Feb 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 36 additions & 18 deletions lib/marked.esm.js
Expand Up @@ -532,39 +532,51 @@ var Tokenizer_1 = class Tokenizer {
addBack,
loose,
istask,
ischecked;
ischecked,
endMatch;

let l = itemMatch.length;
bcurr = this.rules.block.listItemStart.exec(itemMatch[0]);
for (let i = 0; i < l; i++) {
item = itemMatch[i];
raw = item;

if (!this.options.pedantic) {
// Determine if current item contains the end of the list
endMatch = item.match(new RegExp('\\n\\s*\\n {0,' + (bcurr[0].length - 1) + '}\\S'));
if (endMatch) {
addBack = item.length - endMatch.index + itemMatch.slice(i + 1).join('\n').length;
list.raw = list.raw.substring(0, list.raw.length - addBack);

item = item.substring(0, endMatch.index);
raw = item;
l = i + 1;
}
}

// Determine whether the next list item belongs here.
// Backpedal if it does not belong in this list.
if (i !== l - 1) {
bnext = this.rules.block.listItemStart.exec(itemMatch[i + 1]);
if (
!this.options.pedantic
? bnext[1].length > bcurr[0].length || bnext[1].length > 3
? bnext[1].length >= bcurr[0].length || bnext[1].length > 3
: bnext[1].length > bcurr[1].length
) {
// nested list
itemMatch.splice(i, 2, itemMatch[i] + '\n' + itemMatch[i + 1]);
// nested list or continuation
itemMatch.splice(i, 2, itemMatch[i] + (!this.options.pedantic && bnext[1].length < bcurr[0].length && !itemMatch[i].match(/\n$/) ? '' : '\n') + itemMatch[i + 1]);
i--;
l--;
continue;
} else {
if (
// different bullet style
!this.options.pedantic || this.options.smartLists
? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1]
: isordered === (bnext[2].length === 1)
) {
addBack = itemMatch.slice(i + 1).join('\n');
list.raw = list.raw.substring(0, list.raw.length - addBack.length);
i = l - 1;
}
} else if (
// different bullet style
!this.options.pedantic || this.options.smartLists
? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1]
: isordered === (bnext[2].length === 1)
) {
addBack = itemMatch.slice(i + 1).join('\n').length;
list.raw = list.raw.substring(0, list.raw.length - addBack);
i = l - 1;
}
bcurr = bnext;
}
Expand All @@ -583,12 +595,18 @@ var Tokenizer_1 = class Tokenizer {
: item.replace(/^ {1,4}/gm, '');
}

// trim item newlines at end
item = rtrim$1(item, '\n');
if (i !== l - 1) {
raw = raw + '\n';
}

// Determine whether item is loose or not.
// Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
// for discount behavior.
loose = next || /\n\n(?!\s*$)/.test(item);
loose = next || /\n\n(?!\s*$)/.test(raw);
if (i !== l - 1) {
next = item.charAt(item.length - 1) === '\n';
next = raw.slice(-2) === '\n\n';
if (!loose) loose = next;
}

Expand Down Expand Up @@ -1072,7 +1090,7 @@ block.item = edit$1(block.item, 'gm')
.replace(/bull/g, block.bullet)
.getRegex();

block.listItemStart = edit$1(/^( *)(bull)/)
block.listItemStart = edit$1(/^( *)(bull) */)
.replace('bull', block.bullet)
.getRegex();

Expand Down
50 changes: 35 additions & 15 deletions lib/marked.js
Expand Up @@ -631,31 +631,44 @@
addBack,
loose,
istask,
ischecked;
ischecked,
endMatch;
var l = itemMatch.length;
bcurr = this.rules.block.listItemStart.exec(itemMatch[0]);

for (var i = 0; i < l; i++) {
item = itemMatch[i];
raw = item; // Determine whether the next list item belongs here.
raw = item;

if (!this.options.pedantic) {
// Determine if current item contains the end of the list
endMatch = item.match(new RegExp('\\n\\s*\\n {0,' + (bcurr[0].length - 1) + '}\\S'));

if (endMatch) {
addBack = item.length - endMatch.index + itemMatch.slice(i + 1).join('\n').length;
list.raw = list.raw.substring(0, list.raw.length - addBack);
item = item.substring(0, endMatch.index);
raw = item;
l = i + 1;
}
} // Determine whether the next list item belongs here.
// Backpedal if it does not belong in this list.


if (i !== l - 1) {
bnext = this.rules.block.listItemStart.exec(itemMatch[i + 1]);

if (!this.options.pedantic ? bnext[1].length > bcurr[0].length || bnext[1].length > 3 : bnext[1].length > bcurr[1].length) {
// nested list
itemMatch.splice(i, 2, itemMatch[i] + '\n' + itemMatch[i + 1]);
if (!this.options.pedantic ? bnext[1].length >= bcurr[0].length || bnext[1].length > 3 : bnext[1].length > bcurr[1].length) {
// nested list or continuation
itemMatch.splice(i, 2, itemMatch[i] + (!this.options.pedantic && bnext[1].length < bcurr[0].length && !itemMatch[i].match(/\n$/) ? '' : '\n') + itemMatch[i + 1]);
i--;
l--;
continue;
} else {
if ( // different bullet style
!this.options.pedantic || this.options.smartLists ? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1] : isordered === (bnext[2].length === 1)) {
addBack = itemMatch.slice(i + 1).join('\n');
list.raw = list.raw.substring(0, list.raw.length - addBack.length);
i = l - 1;
}
} else if ( // different bullet style
!this.options.pedantic || this.options.smartLists ? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1] : isordered === (bnext[2].length === 1)) {
addBack = itemMatch.slice(i + 1).join('\n').length;
list.raw = list.raw.substring(0, list.raw.length - addBack);
i = l - 1;
}

bcurr = bnext;
Expand All @@ -670,15 +683,22 @@
if (~item.indexOf('\n ')) {
space -= item.length;
item = !this.options.pedantic ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') : item.replace(/^ {1,4}/gm, '');
} // trim item newlines at end


item = rtrim$1(item, '\n');

if (i !== l - 1) {
raw = raw + '\n';
} // Determine whether item is loose or not.
// Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
// for discount behavior.


loose = next || /\n\n(?!\s*$)/.test(item);
loose = next || /\n\n(?!\s*$)/.test(raw);

if (i !== l - 1) {
next = item.charAt(item.length - 1) === '\n';
next = raw.slice(-2) === '\n\n';
if (!loose) loose = next;
}

Expand Down Expand Up @@ -1179,7 +1199,7 @@
block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
block.item = /^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/;
block.item = edit$1(block.item, 'gm').replace(/bull/g, block.bullet).getRegex();
block.listItemStart = edit$1(/^( *)(bull)/).replace('bull', block.bullet).getRegex();
block.listItemStart = edit$1(/^( *)(bull) */).replace('bull', block.bullet).getRegex();
block.list = edit$1(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex();
block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul';
block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
Expand Down
2 changes: 1 addition & 1 deletion marked.min.js

Large diffs are not rendered by default.

52 changes: 35 additions & 17 deletions src/Tokenizer.js
Expand Up @@ -220,39 +220,51 @@ module.exports = class Tokenizer {
addBack,
loose,
istask,
ischecked;
ischecked,
endMatch;

let l = itemMatch.length;
bcurr = this.rules.block.listItemStart.exec(itemMatch[0]);
for (let i = 0; i < l; i++) {
item = itemMatch[i];
raw = item;

if (!this.options.pedantic) {
// Determine if current item contains the end of the list
endMatch = item.match(new RegExp('\\n\\s*\\n {0,' + (bcurr[0].length - 1) + '}\\S'));
if (endMatch) {
addBack = item.length - endMatch.index + itemMatch.slice(i + 1).join('\n').length;
list.raw = list.raw.substring(0, list.raw.length - addBack);

item = item.substring(0, endMatch.index);
raw = item;
l = i + 1;
}
}

// Determine whether the next list item belongs here.
// Backpedal if it does not belong in this list.
if (i !== l - 1) {
bnext = this.rules.block.listItemStart.exec(itemMatch[i + 1]);
if (
!this.options.pedantic
? bnext[1].length > bcurr[0].length || bnext[1].length > 3
? bnext[1].length >= bcurr[0].length || bnext[1].length > 3
: bnext[1].length > bcurr[1].length
) {
// nested list
itemMatch.splice(i, 2, itemMatch[i] + '\n' + itemMatch[i + 1]);
// nested list or continuation
itemMatch.splice(i, 2, itemMatch[i] + (!this.options.pedantic && bnext[1].length < bcurr[0].length && !itemMatch[i].match(/\n$/) ? '' : '\n') + itemMatch[i + 1]);
i--;
l--;
continue;
} else {
if (
// different bullet style
!this.options.pedantic || this.options.smartLists
? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1]
: isordered === (bnext[2].length === 1)
) {
addBack = itemMatch.slice(i + 1).join('\n');
list.raw = list.raw.substring(0, list.raw.length - addBack.length);
i = l - 1;
}
} else if (
// different bullet style
!this.options.pedantic || this.options.smartLists
? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1]
: isordered === (bnext[2].length === 1)
) {
addBack = itemMatch.slice(i + 1).join('\n').length;
list.raw = list.raw.substring(0, list.raw.length - addBack);
i = l - 1;
}
bcurr = bnext;
}
Expand All @@ -271,12 +283,18 @@ module.exports = class Tokenizer {
: item.replace(/^ {1,4}/gm, '');
}

// trim item newlines at end
item = rtrim(item, '\n');
if (i !== l - 1) {
raw = raw + '\n';
}

// Determine whether item is loose or not.
// Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
// for discount behavior.
loose = next || /\n\n(?!\s*$)/.test(item);
loose = next || /\n\n(?!\s*$)/.test(raw);
if (i !== l - 1) {
next = item.charAt(item.length - 1) === '\n';
next = raw.slice(-2) === '\n\n';
if (!loose) loose = next;
}

Expand Down
2 changes: 1 addition & 1 deletion src/rules.js
Expand Up @@ -48,7 +48,7 @@ block.item = edit(block.item, 'gm')
.replace(/bull/g, block.bullet)
.getRegex();

block.listItemStart = edit(/^( *)(bull)/)
block.listItemStart = edit(/^( *)(bull) */)
.replace('bull', block.bullet)
.getRegex();

Expand Down
15 changes: 5 additions & 10 deletions test/specs/commonmark/commonmark.0.29.json
Expand Up @@ -1805,8 +1805,7 @@
"example": 225,
"start_line": 3834,
"end_line": 3843,
"section": "List items",
"shouldFail": true
"section": "List items"
},
{
"markdown": "- one\n\n two\n",
Expand All @@ -1822,8 +1821,7 @@
"example": 227,
"start_line": 3860,
"end_line": 3870,
"section": "List items",
"shouldFail": true
"section": "List items"
},
{
"markdown": " - one\n\n two\n",
Expand Down Expand Up @@ -1979,8 +1977,7 @@
"example": 246,
"start_line": 4192,
"end_line": 4201,
"section": "List items",
"shouldFail": true
"section": "List items"
},
{
"markdown": "- foo\n\n bar\n",
Expand Down Expand Up @@ -2273,17 +2270,15 @@
"example": 282,
"start_line": 5177,
"end_line": 5191,
"section": "Lists",
"shouldFail": true
"section": "Lists"
},
{
"markdown": "1. a\n\n 2. b\n\n 3. c\n",
"html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n</ol>\n<pre><code>3. c\n</code></pre>\n",
"example": 283,
"start_line": 5197,
"end_line": 5214,
"section": "Lists",
"shouldFail": true
"section": "Lists"
},
{
"markdown": "- a\n- b\n\n- c\n",
Expand Down
15 changes: 5 additions & 10 deletions test/specs/gfm/commonmark.0.29.json
Expand Up @@ -1805,8 +1805,7 @@
"example": 225,
"start_line": 3834,
"end_line": 3843,
"section": "List items",
"shouldFail": true
"section": "List items"
},
{
"markdown": "- one\n\n two\n",
Expand All @@ -1822,8 +1821,7 @@
"example": 227,
"start_line": 3860,
"end_line": 3870,
"section": "List items",
"shouldFail": true
"section": "List items"
},
{
"markdown": " - one\n\n two\n",
Expand Down Expand Up @@ -1979,8 +1977,7 @@
"example": 246,
"start_line": 4192,
"end_line": 4201,
"section": "List items",
"shouldFail": true
"section": "List items"
},
{
"markdown": "- foo\n\n bar\n",
Expand Down Expand Up @@ -2273,17 +2270,15 @@
"example": 282,
"start_line": 5177,
"end_line": 5191,
"section": "Lists",
"shouldFail": true
"section": "Lists"
},
{
"markdown": "1. a\n\n 2. b\n\n 3. c\n",
"html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n</ol>\n<pre><code>3. c\n</code></pre>\n",
"example": 283,
"start_line": 5197,
"end_line": 5214,
"section": "Lists",
"shouldFail": true
"section": "Lists"
},
{
"markdown": "- a\n- b\n\n- c\n",
Expand Down
3 changes: 3 additions & 0 deletions test/specs/new/list_item_text.md
@@ -1,3 +1,6 @@
---
pedantic: true
---
* item1

* item2
Expand Down
1 change: 0 additions & 1 deletion test/specs/original/literal_quotes_in_titles.md
Expand Up @@ -8,4 +8,3 @@ Foo [bar](/url/ "Title with "quotes" inside").


[bar]: /url/ "Title with "quotes" inside"