1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-18 09:35:20 +02:00
joplin/packages/turndown/src/rules.js
wljince007 294cc4a440
Desktop: Fixes #5626: When web clipper clipping code blocks, keep code in multiline and delete code number lines (#10126)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
2024-04-20 13:48:44 +01:00

84 lines
2.1 KiB
JavaScript

/**
* 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) {
// code block keep blank lines
// See https://github.com/laurent22/joplin/pull/10126 .
// test case: packages/app-cli/tests/html_to_md/code_multiline_4.html
if (node.isCode === false && 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')
}
}