blob: 4add90e01e891ad96b785b0616685ccb2dd939d9 [file] [log] [blame]
'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
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)
}
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 = [
['atxHeading', {pedantic: false}],
['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 = {
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
}