Skip to content

Commit 5f9cafd

Browse files
authored
fix: list alignment (#1810)
* fix: fix list alignment * test: add test * test: update passing tests * move regex to rules * clean up code * move item back to top
1 parent 7edea11 commit 5f9cafd

File tree

7 files changed

+62
-37
lines changed

7 files changed

+62
-37
lines changed

src/Tokenizer.js

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ module.exports = class Tokenizer {
195195
let raw = cap[0];
196196
const bull = cap[2];
197197
const isordered = bull.length > 1;
198-
const isparen = bull[bull.length - 1] === ')';
199198

200199
const list = {
201200
type: 'list',
@@ -212,17 +211,45 @@ module.exports = class Tokenizer {
212211
let next = false,
213212
item,
214213
space,
215-
b,
214+
bcurr,
215+
bnext,
216216
addBack,
217217
loose,
218218
istask,
219219
ischecked;
220220

221-
const l = itemMatch.length;
221+
let l = itemMatch.length;
222+
bcurr = this.rules.block.listItemStart.exec(itemMatch[0]);
222223
for (let i = 0; i < l; i++) {
223224
item = itemMatch[i];
224225
raw = item;
225226

227+
// Determine whether the next list item belongs here.
228+
// Backpedal if it does not belong in this list.
229+
if (i !== l - 1) {
230+
bnext = this.rules.block.listItemStart.exec(itemMatch[i + 1]);
231+
232+
if (bnext[1].length > bcurr[0].length || bnext[1].length > 3) {
233+
// nested list
234+
itemMatch.splice(i, 2, itemMatch[i] + '\n' + itemMatch[i + 1]);
235+
i--;
236+
l--;
237+
continue;
238+
} else {
239+
if (
240+
// different bullet style
241+
!this.options.pedantic || this.options.smartLists
242+
? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1]
243+
: isordered === (bnext[2].length === 1)
244+
) {
245+
addBack = itemMatch.slice(i + 1).join('\n');
246+
list.raw = list.raw.substring(0, list.raw.length - addBack.length);
247+
i = l - 1;
248+
}
249+
}
250+
bcurr = bnext;
251+
}
252+
226253
// Remove the list item's bullet
227254
// so it is seen as the next token.
228255
space = item.length;
@@ -237,18 +264,6 @@ module.exports = class Tokenizer {
237264
: item.replace(/^ {1,4}/gm, '');
238265
}
239266

240-
// Determine whether the next list item belongs here.
241-
// Backpedal if it does not belong in this list.
242-
if (i !== l - 1) {
243-
b = this.rules.block.bullet.exec(itemMatch[i + 1])[0];
244-
if (isordered ? b.length === 1 || (!isparen && b[b.length - 1] === ')')
245-
: (b.length > 1 || (this.options.smartLists && b !== bull))) {
246-
addBack = itemMatch.slice(i + 1).join('\n');
247-
list.raw = list.raw.substring(0, list.raw.length - addBack.length);
248-
i = l - 1;
249-
}
250-
}
251-
252267
// Determine whether item is loose or not.
253268
// Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
254269
// for discount behavior.

src/rules.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const block = {
1414
hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
1515
heading: /^ {0,3}(#{1,6}) +([^\n]*?)(?: +#+)? *(?:\n+|$)/,
1616
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
17-
list: /^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
17+
list: /^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/,
1818
html: '^ {0,3}(?:' // optional indentation
1919
+ '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
2020
+ '|comment[^\\n]*(\\n+|$)' // (2)
@@ -43,11 +43,15 @@ block.def = edit(block.def)
4343
.getRegex();
4444

4545
block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
46-
block.item = /^( *)(bull) ?[^\n]*(?:\n(?!\1bull ?)[^\n]*)*/;
46+
block.item = /^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/;
4747
block.item = edit(block.item, 'gm')
4848
.replace(/bull/g, block.bullet)
4949
.getRegex();
5050

51+
block.listItemStart = edit(/^( *)(bull)/)
52+
.replace('bull', block.bullet)
53+
.getRegex();
54+
5155
block.list = edit(block.list)
5256
.replace(/bull/g, block.bullet)
5357
.replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')

test/specs/commonmark/commonmark.0.29.json

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,8 +2136,7 @@
21362136
"example": 265,
21372137
"start_line": 4578,
21382138
"end_line": 4590,
2139-
"section": "List items",
2140-
"shouldFail": true
2139+
"section": "List items"
21412140
},
21422141
{
21432142
"markdown": "10) foo\n - bar\n",
@@ -2153,8 +2152,7 @@
21532152
"example": 267,
21542153
"start_line": 4611,
21552154
"end_line": 4621,
2156-
"section": "List items",
2157-
"shouldFail": true
2155+
"section": "List items"
21582156
},
21592157
{
21602158
"markdown": "- - foo\n",
@@ -2186,8 +2184,7 @@
21862184
"example": 271,
21872185
"start_line": 4894,
21882186
"end_line": 4906,
2189-
"section": "Lists",
2190-
"shouldFail": true
2187+
"section": "Lists"
21912188
},
21922189
{
21932190
"markdown": "1. foo\n2. bar\n3) baz\n",
@@ -2261,17 +2258,15 @@
22612258
"example": 280,
22622259
"start_line": 5132,
22632260
"end_line": 5150,
2264-
"section": "Lists",
2265-
"shouldFail": true
2261+
"section": "Lists"
22662262
},
22672263
{
22682264
"markdown": "1. a\n\n 2. b\n\n 3. c\n",
22692265
"html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>c</p>\n</li>\n</ol>\n",
22702266
"example": 281,
22712267
"start_line": 5153,
22722268
"end_line": 5171,
2273-
"section": "Lists",
2274-
"shouldFail": true
2269+
"section": "Lists"
22752270
},
22762271
{
22772272
"markdown": "- a\n - b\n - c\n - d\n - e\n",

test/specs/gfm/commonmark.0.29.json

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,8 +2136,7 @@
21362136
"example": 265,
21372137
"start_line": 4578,
21382138
"end_line": 4590,
2139-
"section": "List items",
2140-
"shouldFail": true
2139+
"section": "List items"
21412140
},
21422141
{
21432142
"markdown": "10) foo\n - bar\n",
@@ -2153,8 +2152,7 @@
21532152
"example": 267,
21542153
"start_line": 4611,
21552154
"end_line": 4621,
2156-
"section": "List items",
2157-
"shouldFail": true
2155+
"section": "List items"
21582156
},
21592157
{
21602158
"markdown": "- - foo\n",
@@ -2186,8 +2184,7 @@
21862184
"example": 271,
21872185
"start_line": 4894,
21882186
"end_line": 4906,
2189-
"section": "Lists",
2190-
"shouldFail": true
2187+
"section": "Lists"
21912188
},
21922189
{
21932190
"markdown": "1. foo\n2. bar\n3) baz\n",
@@ -2261,17 +2258,15 @@
22612258
"example": 280,
22622259
"start_line": 5132,
22632260
"end_line": 5150,
2264-
"section": "Lists",
2265-
"shouldFail": true
2261+
"section": "Lists"
22662262
},
22672263
{
22682264
"markdown": "1. a\n\n 2. b\n\n 3. c\n",
22692265
"html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>c</p>\n</li>\n</ol>\n",
22702266
"example": 281,
22712267
"start_line": 5153,
22722268
"end_line": 5171,
2273-
"section": "Lists",
2274-
"shouldFail": true
2269+
"section": "Lists"
22752270
},
22762271
{
22772272
"markdown": "- a\n - b\n - c\n - d\n - e\n",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<pre><code>1. Item 1
2+
</code></pre>
3+
<ol start="10">
4+
<li>Item 10</li>
5+
<li>Item 100</li>
6+
<li>Item 1000</li>
7+
<li>Item 10000</li>
8+
</ol>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
1. Item 1
2+
10. Item 10
3+
100. Item 100
4+
1000. Item 1000
5+
10000. Item 10000

test/specs/new/same_bullet.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
---
2+
pedantic: true
3+
---
14
* test
25
+ test
36
- test

0 commit comments

Comments
 (0)