From 5618e6c81e09ba0ffb9a6f3802974d589f8f7b3b Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 30 Nov 2022 21:21:43 -0600 Subject: [PATCH 1/3] fix: loose list items are loose --- src/Tokenizer.js | 39 +++++++++++++++++++++--------------- test/unit/Lexer-spec.js | 44 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 42064621b4..3100c2579b 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -315,25 +315,32 @@ 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; + + if (!list.loose) { + // Check if list should be loose + const spacers = list.items[i].tokens.filter(t => t.type === 'space'); + const hasMultipleLineBreaks = spacers.length && 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; - }); + return false; + }); - 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/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' From 6a44508b9c910cc37be142234888203b8267663c Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 5 Dec 2022 23:27:27 -0600 Subject: [PATCH 2/3] chore: clean up code --- src/Tokenizer.js | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 3100c2579b..e786450fa9 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -319,22 +319,9 @@ export class Tokenizer { if (!list.loose) { // Check if list should be loose const spacers = list.items[i].tokens.filter(t => t.type === 'space'); - const hasMultipleLineBreaks = spacers.length && 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; - }); + const hasMultipleLineBreaks = spacers.length > 0 && spacers.every(t => /\n.*\n/.test(t.raw)); - list.loose = !!hasMultipleLineBreaks; + list.loose = hasMultipleLineBreaks; } } From 598b262beaf08a34cc01152403934255e921aef9 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 5 Dec 2022 23:47:14 -0600 Subject: [PATCH 3/3] fix: fix loose item with line break at beginning --- src/Tokenizer.js | 2 +- test/specs/new/list_loose.html | 9 +++++++++ test/specs/new/list_loose.md | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/specs/new/list_loose.html create mode 100644 test/specs/new/list_loose.md diff --git a/src/Tokenizer.js b/src/Tokenizer.js index e786450fa9..ad7ac4010b 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -319,7 +319,7 @@ export class Tokenizer { 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.every(t => /\n.*\n/.test(t.raw)); + const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw)); list.loose = hasMultipleLineBreaks; } 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 @@ +
    +
  • +

    item 1

    +
  • +
  • +

    item 2

    +

    still item 2

    +
  • +
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