diff --git a/packages/remark-parse/lib/parser.js b/packages/remark-parse/lib/parser.js index 4add90e01..b932d4615 100644 --- a/packages/remark-parse/lib/parser.js +++ b/packages/remark-parse/lib/parser.js @@ -97,7 +97,7 @@ proto.interruptBlockquote = [ // Handlers. proto.blockTokenizers = { - newline: require('./tokenize/newline'), + blankLine: require('./tokenize/blank-line'), indentedCode: require('./tokenize/code-indented'), fencedCode: require('./tokenize/code-fenced'), blockquote: require('./tokenize/blockquote'), diff --git a/packages/remark-parse/lib/tokenize/blank-line.js b/packages/remark-parse/lib/tokenize/blank-line.js new file mode 100644 index 000000000..04eae7af9 --- /dev/null +++ b/packages/remark-parse/lib/tokenize/blank-line.js @@ -0,0 +1,38 @@ +'use strict' + +// A line containing no characters, or a line containing only spaces (U+0020) or tabs (U+0009), is called a blank line. +// See https://spec.commonmark.org/0.29/#blank-line +var reBlankLine = /^[\u0020\t]*(\n|$)/ + +// NOTE: Though blank lines play a special role in lists to determine whether the list is tight or loose (https://spec.commonmark.org/0.29/#blank-lines), +// it's done by the list tokenizer and this blank-line tokenizer does not have to be responsible for that. +// Therefore, configs such as `blankLine.notInList` do not have to be set here. +module.exports = blankLine + +function blankLine(eat, value, silent) { + var match + var subvalue = '' + var index = 0 + var length = value.length + + while (index < length) { + match = reBlankLine.exec(value.slice(index)) + if (match == null) { + break + } + + index += match[0].length + subvalue += match[0] + } + + if (subvalue === '') { + return + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true + } + + eat(subvalue) +} diff --git a/packages/remark-parse/lib/tokenize/newline.js b/packages/remark-parse/lib/tokenize/newline.js deleted file mode 100644 index 680020cf0..000000000 --- a/packages/remark-parse/lib/tokenize/newline.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict' - -var whitespace = require('is-whitespace-character') - -module.exports = newline - -var lineFeed = '\n' - -function newline(eat, value, silent) { - var character = value.charAt(0) - var length - var subvalue - var queue - var index - - if (character !== lineFeed) { - return - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true - } - - index = 1 - length = value.length - subvalue = character - queue = '' - - while (index < length) { - character = value.charAt(index) - - if (!whitespace(character)) { - break - } - - queue += character - - if (character === lineFeed) { - subvalue += queue - queue = '' - } - - index++ - } - - eat(subvalue) -} diff --git a/packages/remark-parse/lib/tokenize/paragraph.js b/packages/remark-parse/lib/tokenize/paragraph.js index 13db0ff40..c367d12a4 100644 --- a/packages/remark-parse/lib/tokenize/paragraph.js +++ b/packages/remark-parse/lib/tokenize/paragraph.js @@ -96,12 +96,6 @@ function paragraph(eat, value, silent) { subvalue = value.slice(0, index) - if (trim(subvalue) === '') { - eat(subvalue) - - return null - } - /* istanbul ignore if - never used (yet) */ if (silent) { return true diff --git a/packages/remark-parse/readme.md b/packages/remark-parse/readme.md index f9d1e8ae5..ea975cb42 100644 --- a/packages/remark-parse/readme.md +++ b/packages/remark-parse/readme.md @@ -252,7 +252,7 @@ Precedence of default block methods is as follows: -* `newline` +* `blankLine` * `indentedCode` * `fencedCode` * `blockquote` diff --git a/test/fixtures/input/isolated-hard-break.text b/test/fixtures/input/isolated-hard-break.text new file mode 100644 index 000000000..b34a1910b --- /dev/null +++ b/test/fixtures/input/isolated-hard-break.text @@ -0,0 +1,2 @@ + +The previous line, which contains 2 spaces, should be considered to be empty. diff --git a/test/fixtures/tree/isolated-hard-break.json b/test/fixtures/tree/isolated-hard-break.json new file mode 100644 index 000000000..2b4639b1d --- /dev/null +++ b/test/fixtures/tree/isolated-hard-break.json @@ -0,0 +1,52 @@ +{ + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The previous line, which contains 2 spaces, should be considered to be empty.", + "position": { + "start": { + "line": 2, + "column": 1, + "offset": 3 + }, + "end": { + "line": 2, + "column": 78, + "offset": 80 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 2, + "column": 1, + "offset": 3 + }, + "end": { + "line": 2, + "column": 78, + "offset": 80 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 3, + "column": 1, + "offset": 81 + } + } +}