|
|
'use strict';
|
|
|
|
|
|
var trim = require('trim');
|
|
|
var decimal = require('is-decimal');
|
|
|
var trimTrailingLines = require('trim-trailing-lines');
|
|
|
var interrupt = require('../util/interrupt');
|
|
|
|
|
|
module.exports = paragraph;
|
|
|
|
|
|
var C_NEWLINE = '\n';
|
|
|
var C_TAB = '\t';
|
|
|
var C_SPACE = ' ';
|
|
|
|
|
|
var TAB_SIZE = 4;
|
|
|
|
|
|
/* Tokenise paragraph. */
|
|
|
function paragraph(eat, value, silent) {
|
|
|
var self = this;
|
|
|
var settings = self.options;
|
|
|
var commonmark = settings.commonmark;
|
|
|
var gfm = settings.gfm;
|
|
|
var tokenizers = self.blockTokenizers;
|
|
|
var interruptors = self.interruptParagraph;
|
|
|
var index = value.indexOf(C_NEWLINE);
|
|
|
var length = value.length;
|
|
|
var position;
|
|
|
var subvalue;
|
|
|
var character;
|
|
|
var size;
|
|
|
var now;
|
|
|
|
|
|
while (index < length) {
|
|
|
/* Eat everything if there’s no following newline. */
|
|
|
if (index === -1) {
|
|
|
index = length;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
/* Stop if the next character is NEWLINE. */
|
|
|
if (value.charAt(index + 1) === C_NEWLINE) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
/* In commonmark-mode, following indented lines
|
|
|
* are part of the paragraph. */
|
|
|
if (commonmark) {
|
|
|
size = 0;
|
|
|
position = index + 1;
|
|
|
|
|
|
while (position < length) {
|
|
|
character = value.charAt(position);
|
|
|
|
|
|
if (character === C_TAB) {
|
|
|
size = TAB_SIZE;
|
|
|
break;
|
|
|
} else if (character === C_SPACE) {
|
|
|
size++;
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
position++;
|
|
|
}
|
|
|
|
|
|
if (size >= TAB_SIZE) {
|
|
|
index = value.indexOf(C_NEWLINE, index + 1);
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
subvalue = value.slice(index + 1);
|
|
|
|
|
|
/* Check if the following code contains a possible
|
|
|
* block. */
|
|
|
if (interrupt(interruptors, tokenizers, self, [eat, subvalue, true])) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
/* Break if the following line starts a list, when
|
|
|
* already in a list, or when in commonmark, or when
|
|
|
* in gfm mode and the bullet is *not* numeric. */
|
|
|
if (
|
|
|
tokenizers.list.call(self, eat, subvalue, true) &&
|
|
|
(
|
|
|
self.inList ||
|
|
|
commonmark ||
|
|
|
(gfm && !decimal(trim.left(subvalue).charAt(0)))
|
|
|
)
|
|
|
) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
position = index;
|
|
|
index = value.indexOf(C_NEWLINE, index + 1);
|
|
|
|
|
|
if (index !== -1 && trim(value.slice(position, index)) === '') {
|
|
|
index = position;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
subvalue = value.slice(0, index);
|
|
|
|
|
|
if (trim(subvalue) === '') {
|
|
|
eat(subvalue);
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/* istanbul ignore if - never used (yet) */
|
|
|
if (silent) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
now = eat.now();
|
|
|
subvalue = trimTrailingLines(subvalue);
|
|
|
|
|
|
return eat(subvalue)({
|
|
|
type: 'paragraph',
|
|
|
children: self.tokenizeInline(subvalue, now)
|
|
|
});
|
|
|
}
|