diff --git a/src/Tokenizer.js b/src/Tokenizer.js index a957883f28..61ed269a09 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -169,7 +169,7 @@ export class Tokenizer { let cap = this.rules.block.list.exec(src); if (cap) { let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, - line, nextLine, rawLine, itemContents; + line, nextLine, rawLine, itemContents, endEarly; let bull = cap[1].trim(); const isordered = bull.length > 1; @@ -194,6 +194,7 @@ export class Tokenizer { // Check if current bullet point can start a new List Item while (src) { + endEarly = false; if (!(cap = itemRegex.exec(src))) { break; } @@ -223,40 +224,42 @@ export class Tokenizer { if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line raw += nextLine + '\n'; src = src.substring(nextLine.length + 1); - list.loose = true; + endEarly = true; } - const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])`); - - // Check if following lines should be included in List Item - while (src && !list.loose) { - rawLine = src.split('\n', 1)[0]; - line = rawLine; - - // Re-align to follow commonmark nesting rules - if (this.options.pedantic) { - line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); - } - - // End list item if found start of new bullet - if (nextBulletRegex.test(line)) { - break; + if (!endEarly) { + const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])`); + + // Check if following lines should be included in List Item + while (src) { + rawLine = src.split('\n', 1)[0]; + line = rawLine; + + // Re-align to follow commonmark nesting rules + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } + + // End list item if found start of new bullet + if (nextBulletRegex.test(line)) { + break; + } + + if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible + itemContents += '\n' + line.slice(indent); + } else if (!blankLine) { // Until blank line, item doesn't need indentation + itemContents += '\n' + line; + } else { // Otherwise, improper indentation ends this item + break; + } + + if (!blankLine && !line.trim()) { // Check if current line is blank + blankLine = true; + } + + raw += rawLine + '\n'; + src = src.substring(rawLine.length + 1); } - - if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible - itemContents += '\n' + line.slice(indent); - } else if (!blankLine) { // Until blank line, item doesn't need indentation - itemContents += '\n' + line; - } else { // Otherwise, improper indentation ends this item - break; - } - - if (!blankLine && !line.trim()) { // Check if current line is blank - blankLine = true; - } - - raw += rawLine + '\n'; - src = src.substring(rawLine.length + 1); } if (!list.loose) { diff --git a/test/specs/new/multiple_sub_lists.html b/test/specs/new/multiple_sub_lists.html new file mode 100644 index 0000000000..da3cc489b2 --- /dev/null +++ b/test/specs/new/multiple_sub_lists.html @@ -0,0 +1,26 @@ +
    +
  1. list item one

    +
      +
    1. sublist item one
    2. +
    3. sublist item two
    4. +
    +
  2. +
  3. list item two

    +
      +
    1. sublist item one
    2. +
    3. sublist item two
    4. +
    +
  4. +
  5. list item three

    +
      +
    1. sublist item one
    2. +
    3. sublist item two
    4. +
    +
  6. +
  7. list item four

    +
      +
    1. sublist item one
    2. +
    3. sublist item two
    4. +
    +
  8. +
diff --git a/test/specs/new/multiple_sub_lists.md b/test/specs/new/multiple_sub_lists.md new file mode 100644 index 0000000000..0077fbe3a8 --- /dev/null +++ b/test/specs/new/multiple_sub_lists.md @@ -0,0 +1,15 @@ +1. list item one + 1. sublist item one + 2. sublist item two + +2. list item two + 1. sublist item one + 2. sublist item two + +3. list item three + 1. sublist item one + 2. sublist item two + +4. list item four + 1. sublist item one + 2. sublist item two