/**
* Manages a collection of rules used to convert HTML to Markdown
*/
export default function Rules (options) {
this.options = options
this._keep = []
this._remove = []
this.blankRule = {
replacement: options.blankReplacement
}
this.keepReplacement = options.keepReplacement
this.defaultRule = {
replacement: options.defaultReplacement
}
this.array = []
for (var key in options.rules) this.array.push(options.rules[key])
}
Rules.prototype = {
add: function (key, rule) {
this.array.unshift(rule)
},
keep: function (filter) {
this._keep.unshift({
filter: filter,
replacement: this.keepReplacement
})
},
remove: function (filter) {
this._remove.unshift({
filter: filter,
replacement: function () {
return ''
}
})
},
forNode: function (node) {
if (node.isBlank) return this.blankRule
var rule
if ((rule = findRule(this.array, node, this.options))) return rule
if ((rule = findRule(this._keep, node, this.options))) return rule
if ((rule = findRule(this._remove, node, this.options))) return rule
return this.defaultRule
},
forEach: function (fn) {
for (var i = 0; i < this.array.length; i++) fn(this.array[i], i)
}
}
function findRule (rules, node, options) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i]
if (filterValue(rule, node, options)) return rule
}
return void 0
}
function filterValue (rule, node, options) {
var filter = rule.filter
if (typeof filter === 'string') {
if (filter === node.nodeName.toLowerCase()) return true
} else if (Array.isArray(filter)) {
if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true
} else if (typeof filter === 'function') {
if (filter.call(rule, node, options)) return true
} else {
throw new TypeError('`filter` needs to be a string, array, or function')
}
}
|