diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 42064621b4..ad7ac4010b 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -315,25 +315,19 @@ export class Tokenizer { for (i = 0; i < l; i++) { this.lexer.state.top = false; list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); - const spacers = list.items[i].tokens.filter(t => t.type === 'space'); - const hasMultipleLineBreaks = spacers.every(t => { - const chars = t.raw.split(''); - let lineBreaks = 0; - for (const char of chars) { - if (char === '\n') { - lineBreaks += 1; - } - if (lineBreaks > 1) { - return true; - } - } - return false; - }); + if (!list.loose) { + // Check if list should be loose + const spacers = list.items[i].tokens.filter(t => t.type === 'space'); + const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw)); - if (!list.loose && spacers.length && hasMultipleLineBreaks) { - // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item - list.loose = true; + list.loose = hasMultipleLineBreaks; + } + } + + // Set all items to loose if list is loose + if (list.loose) { + for (i = 0; i < l; i++) { list.items[i].loose = true; } } diff --git a/test/specs/new/list_loose.html b/test/specs/new/list_loose.html new file mode 100644 index 0000000000..2ae6aebe6c --- /dev/null +++ b/test/specs/new/list_loose.html @@ -0,0 +1,9 @@ + diff --git a/test/specs/new/list_loose.md b/test/specs/new/list_loose.md new file mode 100644 index 0000000000..dc69f434e7 --- /dev/null +++ b/test/specs/new/list_loose.md @@ -0,0 +1,5 @@ +- item 1 +- + item 2 + + still item 2 diff --git a/test/unit/Lexer-spec.js b/test/unit/Lexer-spec.js index 7a1e826fd8..4626a60710 100644 --- a/test/unit/Lexer-spec.js +++ b/test/unit/Lexer-spec.js @@ -605,10 +605,49 @@ paragraph loose: true, items: [ jasmine.objectContaining({ - raw: '- item 1\n\n' + raw: '- item 1\n\n', + loose: true }), jasmine.objectContaining({ - raw: '- item 2' + raw: '- item 2', + loose: true + }) + ] + }) + ]) + }); + }); + + it('end loose', () => { + expectTokens({ + md: ` +- item 1 +- item 2 + + item 2a +- item 3 +`, + tokens: jasmine.arrayContaining([ + jasmine.objectContaining({ + type: 'space', + raw: '\n' + }), + jasmine.objectContaining({ + type: 'list', + raw: '- item 1\n- item 2\n\n item 2a\n- item 3\n', + loose: true, + items: [ + jasmine.objectContaining({ + raw: '- item 1\n', + loose: true + }), + jasmine.objectContaining({ + raw: '- item 2\n\n item 2a\n', + loose: true + }), + jasmine.objectContaining({ + raw: '- item 3', + loose: true }) ] }) @@ -634,6 +673,7 @@ paragraph items: [ jasmine.objectContaining({ raw: '- item 1\n - item 2', + loose: false, tokens: jasmine.arrayContaining([ jasmine.objectContaining({ raw: 'item 1\n'