mirror of https://github.com/lukechilds/node.git
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.
162 lines
4.1 KiB
162 lines
4.1 KiB
/**
|
|
* @author Titus Wormer
|
|
* @copyright 2015 Titus Wormer
|
|
* @license MIT
|
|
* @module remark:parse
|
|
* @fileoverview Markdown parser.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var xtend = require('xtend');
|
|
var toggle = require('state-toggle');
|
|
var vfileLocation = require('vfile-location');
|
|
var unescape = require('./unescape');
|
|
var decode = require('./decode');
|
|
var tokenizer = require('./tokenizer');
|
|
|
|
module.exports = Parser;
|
|
|
|
/* Construct a new parser. */
|
|
function Parser(doc, file) {
|
|
this.file = file;
|
|
this.offset = {};
|
|
this.options = xtend(this.options);
|
|
this.setOptions({});
|
|
|
|
this.inList = false;
|
|
this.inBlock = false;
|
|
this.inLink = false;
|
|
this.atStart = true;
|
|
|
|
this.toOffset = vfileLocation(file).toOffset;
|
|
this.unescape = unescape(this, 'escape');
|
|
this.decode = decode(this);
|
|
}
|
|
|
|
/* Prototype. */
|
|
var proto = Parser.prototype;
|
|
|
|
/* Expose core. */
|
|
proto.setOptions = require('./set-options');
|
|
proto.parse = require('./parse');
|
|
|
|
/* Expose `defaults`. */
|
|
proto.options = require('./defaults');
|
|
|
|
/* Enter and exit helpers. */
|
|
proto.exitStart = toggle('atStart', true);
|
|
proto.enterList = toggle('inList', false);
|
|
proto.enterLink = toggle('inLink', false);
|
|
proto.enterBlock = toggle('inBlock', false);
|
|
|
|
/* Nodes that can interupt a paragraph:
|
|
*
|
|
* ```markdown
|
|
* A paragraph, followed by a thematic break.
|
|
* ___
|
|
* ```
|
|
*
|
|
* In the above example, the thematic break “interupts”
|
|
* the paragraph. */
|
|
proto.interruptParagraph = [
|
|
['thematicBreak'],
|
|
['atxHeading'],
|
|
['fencedCode'],
|
|
['blockquote'],
|
|
['html'],
|
|
['setextHeading', {commonmark: false}],
|
|
['definition', {commonmark: false}],
|
|
['footnote', {commonmark: false}]
|
|
];
|
|
|
|
/* Nodes that can interupt a list:
|
|
*
|
|
* ```markdown
|
|
* - One
|
|
* ___
|
|
* ```
|
|
*
|
|
* In the above example, the thematic break “interupts”
|
|
* the list. */
|
|
proto.interruptList = [
|
|
['fencedCode', {pedantic: false}],
|
|
['thematicBreak', {pedantic: false}],
|
|
['definition', {commonmark: false}],
|
|
['footnote', {commonmark: false}]
|
|
];
|
|
|
|
/* Nodes that can interupt a blockquote:
|
|
*
|
|
* ```markdown
|
|
* > A paragraph.
|
|
* ___
|
|
* ```
|
|
*
|
|
* In the above example, the thematic break “interupts”
|
|
* the blockquote. */
|
|
proto.interruptBlockquote = [
|
|
['indentedCode', {commonmark: true}],
|
|
['fencedCode', {commonmark: true}],
|
|
['atxHeading', {commonmark: true}],
|
|
['setextHeading', {commonmark: true}],
|
|
['thematicBreak', {commonmark: true}],
|
|
['html', {commonmark: true}],
|
|
['list', {commonmark: true}],
|
|
['definition', {commonmark: false}],
|
|
['footnote', {commonmark: false}]
|
|
];
|
|
|
|
/* Handlers. */
|
|
proto.blockTokenizers = {
|
|
yamlFrontMatter: require('./tokenize/yaml'),
|
|
newline: require('./tokenize/newline'),
|
|
indentedCode: require('./tokenize/code-indented'),
|
|
fencedCode: require('./tokenize/code-fenced'),
|
|
blockquote: require('./tokenize/blockquote'),
|
|
atxHeading: require('./tokenize/heading-atx'),
|
|
thematicBreak: require('./tokenize/thematic-break'),
|
|
list: require('./tokenize/list'),
|
|
setextHeading: require('./tokenize/heading-setext'),
|
|
html: require('./tokenize/html-block'),
|
|
footnote: require('./tokenize/footnote-definition'),
|
|
definition: require('./tokenize/definition'),
|
|
table: require('./tokenize/table'),
|
|
paragraph: require('./tokenize/paragraph')
|
|
};
|
|
|
|
proto.inlineTokenizers = {
|
|
escape: require('./tokenize/escape'),
|
|
autoLink: require('./tokenize/auto-link'),
|
|
url: require('./tokenize/url'),
|
|
html: require('./tokenize/html-inline'),
|
|
link: require('./tokenize/link'),
|
|
reference: require('./tokenize/reference'),
|
|
strong: require('./tokenize/strong'),
|
|
emphasis: require('./tokenize/emphasis'),
|
|
deletion: require('./tokenize/delete'),
|
|
code: require('./tokenize/code-inline'),
|
|
break: require('./tokenize/break'),
|
|
text: require('./tokenize/text')
|
|
};
|
|
|
|
/* Expose precedence. */
|
|
proto.blockMethods = keys(proto.blockTokenizers);
|
|
proto.inlineMethods = keys(proto.inlineTokenizers);
|
|
|
|
/* Tokenizers. */
|
|
proto.tokenizeBlock = tokenizer('block');
|
|
proto.tokenizeInline = tokenizer('inline');
|
|
proto.tokenizeFactory = tokenizer;
|
|
|
|
/* Get all keys in `value`. */
|
|
function keys(value) {
|
|
var result = [];
|
|
var key;
|
|
|
|
for (key in value) {
|
|
result.push(key);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|