/** * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT * @module remark:parse:tokenize:paragraph * @fileoverview Tokenise a paragraph. */ '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) }); }