|
|
@ -3,6 +3,7 @@ |
|
|
|
'use strict'; |
|
|
|
|
|
|
|
|
|
|
|
var Ruler = require('./ruler'); |
|
|
|
var StateInline = require('./rules_inline/state_inline'); |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -24,92 +25,26 @@ rules.push(require('./rules_inline/entity')); |
|
|
|
rules.push(require('./rules_inline/escape_html_char')); |
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Parser class
|
|
|
|
|
|
|
|
|
|
|
|
function functionName(fn) { |
|
|
|
var ret = fn.toString(); |
|
|
|
ret = ret.substr('function '.length); |
|
|
|
ret = ret.substr(0, ret.indexOf('(')); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
function findByName(self, name) { |
|
|
|
for (var i = 0; i < self.rules.length; i++) { |
|
|
|
if (functionName(self.rules[i]) === name) { |
|
|
|
return i; |
|
|
|
} |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Block Parser class
|
|
|
|
// Inline Parser class
|
|
|
|
//
|
|
|
|
function ParserInline() { |
|
|
|
this.rules = []; |
|
|
|
this._rules = []; |
|
|
|
|
|
|
|
// Rule to skip pure text
|
|
|
|
// - '{$%@}' reserved for extentions
|
|
|
|
// - '<>"' added for internal html escaping
|
|
|
|
this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"]+/; |
|
|
|
|
|
|
|
for (var i = 0; i < rules.length; i++) { |
|
|
|
this.after(null, rules[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this.ruler = new Ruler(this.rulesUpdate.bind(this)); |
|
|
|
|
|
|
|
// Replace/delete parser function
|
|
|
|
//
|
|
|
|
ParserInline.prototype.at = function (name, fn) { |
|
|
|
var index = findByName(name); |
|
|
|
if (index === -1) { |
|
|
|
throw new Error('Parser rule not found: ' + name); |
|
|
|
} |
|
|
|
|
|
|
|
if (fn) { |
|
|
|
this.rules[index] = fn; |
|
|
|
} else { |
|
|
|
this.rules = this.rules.slice(0, index).concat(this.rules.slice(index + 1)); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Add function to parser chain before one with given name.
|
|
|
|
// Or add to start, if name not defined
|
|
|
|
//
|
|
|
|
ParserInline.prototype.before = function (name, fn) { |
|
|
|
if (!name) { |
|
|
|
this.rules.unshift(fn); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var index = findByName(name); |
|
|
|
if (index === -1) { |
|
|
|
throw new Error('Parser rule not found: ' + name); |
|
|
|
for (var i = 0; i < rules.length; i++) { |
|
|
|
this.ruler.after(rules[i]); |
|
|
|
} |
|
|
|
|
|
|
|
this.rules.splice(index, 0, fn); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Add function to parser chain after one with given name.
|
|
|
|
// Or add to end, if name not defined
|
|
|
|
//
|
|
|
|
ParserInline.prototype.after = function (name, fn) { |
|
|
|
if (!name) { |
|
|
|
this.rules.push(fn); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var index = findByName(name); |
|
|
|
if (index === -1) { |
|
|
|
throw new Error('Parser rule not found: ' + name); |
|
|
|
} |
|
|
|
|
|
|
|
this.rules.splice(index + 1, 0, fn); |
|
|
|
ParserInline.prototype.rulesUpdate = function () { |
|
|
|
this._rules = this.ruler.getRules(); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -118,8 +53,8 @@ ParserInline.prototype.after = function (name, fn) { |
|
|
|
//
|
|
|
|
ParserInline.prototype.tokenizeSingle = function (state) { |
|
|
|
var ok, i, |
|
|
|
rules = this.rules, |
|
|
|
len = this.rules.length; |
|
|
|
rules = this._rules, |
|
|
|
len = this._rules.length; |
|
|
|
|
|
|
|
for (i = 0; i < len; i++) { |
|
|
|
ok = rules[i](state); |
|
|
@ -134,8 +69,8 @@ ParserInline.prototype.tokenizeSingle = function (state) { |
|
|
|
//
|
|
|
|
ParserInline.prototype.tokenize = function (state) { |
|
|
|
var ok, i, |
|
|
|
rules = this.rules, |
|
|
|
len = this.rules.length, |
|
|
|
rules = this._rules, |
|
|
|
len = this._rules.length, |
|
|
|
end = state.posMax; |
|
|
|
|
|
|
|
while (state.pos < end) { |
|
|
|