Markdown parser, done right. 100% CommonMark support, extensions, syntax plugins & high speed https://markdown-it.github.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.0 KiB

/** internal
* class ParserBlock
*
* Block-level tokenizer.
**/
import Ruler from './ruler.mjs';
import StateBlock from './rules_block/state_block.mjs';
import r_table from './rules_block/table.mjs';
import r_code from './rules_block/code.mjs';
import r_fence from './rules_block/fence.mjs';
import r_blockquote from './rules_block/blockquote.mjs';
import r_hr from './rules_block/hr.mjs';
import r_list from './rules_block/list.mjs';
import r_reference from './rules_block/reference.mjs';
import r_html_block from './rules_block/html_block.mjs';
import r_heading from './rules_block/heading.mjs';
import r_lheading from './rules_block/lheading.mjs';
import r_paragraph from './rules_block/paragraph.mjs';
var _rules = [
// First 2 params - rule name & source. Secondary array - list of rules,
// which can be terminated by this one.
[ 'table', r_table, [ 'paragraph', 'reference' ] ],
[ 'code', r_code ],
[ 'fence', r_fence, [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
[ 'blockquote', r_blockquote, [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
[ 'hr', r_hr, [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
[ 'list', r_list, [ 'paragraph', 'reference', 'blockquote' ] ],
[ 'reference', r_reference ],
[ 'html_block', r_html_block, [ 'paragraph', 'reference', 'blockquote' ] ],
[ 'heading', r_heading, [ 'paragraph', 'reference', 'blockquote' ] ],
[ 'lheading', r_lheading ],
[ 'paragraph', r_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, prevLine,
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
prevLine = state.line;
for (i = 0; i < len; i++) {
ok = rules[i](state, line, endLine, false);
if (ok) {
if (prevLine >= state.line) {
throw new Error("block rule didn't increment state.line");
}
break;
}
}
// this can only happen if user disables paragraph rule
if (!ok) throw new Error('none of the block rules matched');
// 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;
}
}
};
/**
10 years ago
* 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 = StateBlock;
export default ParserBlock;