123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /** internal
- * class ParserBlock
- *
- * Block-level tokenizer.
- **/
- 'use strict';
- var Ruler = require('./ruler');
- var _rules = [
- // First 2 params - rule name & source. Secondary array - list of rules,
- // which can be terminated by this one.
- [ 'table', require('./rules_block/table'), [ 'paragraph', 'reference' ] ],
- [ 'code', require('./rules_block/code') ],
- [ 'fence', require('./rules_block/fence'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
- [ 'blockquote', require('./rules_block/blockquote'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
- [ 'hr', require('./rules_block/hr'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
- [ 'list', require('./rules_block/list'), [ 'paragraph', 'reference', 'blockquote' ] ],
- [ 'reference', require('./rules_block/reference') ],
- [ 'html_block', require('./rules_block/html_block'), [ 'paragraph', 'reference', 'blockquote' ] ],
- [ 'heading', require('./rules_block/heading'), [ 'paragraph', 'reference', 'blockquote' ] ],
- [ 'lheading', require('./rules_block/lheading') ],
- [ 'paragraph', require('./rules_block/paragraph') ]
- ];
- /**
- * new ParserBlock()
- **/
- function ParserBlock() {
- /**
- * ParserBlock#ruler -> Ruler
- *
- * [[Ruler]] instance. Keep configuration of block rules.
- **/
- this.ruler = new Ruler();
- for (var i = 0; i < _rules.length; i++) {
- this.ruler.push(_rules[i][0], _rules[i][1], { alt: (_rules[i][2] || []).slice() });
- }
- }
- // Generate tokens for input range
- //
- ParserBlock.prototype.tokenize = function (state, startLine, endLine) {
- var ok, i,
- rules = this.ruler.getRules(''),
- len = rules.length,
- line = startLine,
- hasEmptyLines = false,
- maxNesting = state.md.options.maxNesting;
- while (line < endLine) {
- state.line = line = state.skipEmptyLines(line);
- if (line >= endLine) { break; }
- // Termination condition for nested calls.
- // Nested calls currently used for blockquotes & lists
- if (state.sCount[line] < state.blkIndent) { break; }
- // If nesting level exceeded - skip tail to the end. That's not ordinary
- // situation and we should not care about content.
- if (state.level >= maxNesting) {
- state.line = endLine;
- break;
- }
- // Try all possible rules.
- // On success, rule should:
- //
- // - update `state.line`
- // - update `state.tokens`
- // - return true
- for (i = 0; i < len; i++) {
- ok = rules[i](state, line, endLine, false);
- if (ok) { break; }
- }
- // set state.tight if we had an empty line before current tag
- // i.e. latest empty line should not count
- state.tight = !hasEmptyLines;
- // paragraph might "eat" one newline after it in nested lists
- if (state.isEmpty(state.line - 1)) {
- hasEmptyLines = true;
- }
- line = state.line;
- if (line < endLine && state.isEmpty(line)) {
- hasEmptyLines = true;
- line++;
- state.line = line;
- }
- }
- };
- /**
- * ParserBlock.parse(str, md, env, outTokens)
- *
- * Process input string and push block tokens into `outTokens`
- **/
- ParserBlock.prototype.parse = function (src, md, env, outTokens) {
- var state;
- if (!src) { return; }
- state = new this.State(src, md, env, outTokens);
- this.tokenize(state, state.line, state.lineMax);
- };
- ParserBlock.prototype.State = require('./rules_block/state_block');
- module.exports = ParserBlock;
|