52 lines
1.3 KiB
JavaScript
52 lines
1.3 KiB
JavaScript
import fmts from './_fmts.js'
|
|
|
|
const toText = function (term) {
|
|
const pre = term.pre || ''
|
|
const post = term.post || ''
|
|
return pre + term.text + post
|
|
}
|
|
|
|
// the match's pre and post are added around fn(m), so m.text() should leave them out
|
|
const withoutEnds = function (m) {
|
|
const text = m.text
|
|
m.text = fmt => {
|
|
const opts = typeof fmt === 'string' ? fmts[fmt] : fmt
|
|
return text.call(m, { keepEndPunct: false, ...opts })
|
|
}
|
|
return m
|
|
}
|
|
|
|
const findStarts = function (doc, obj) {
|
|
const starts = {}
|
|
Object.keys(obj).forEach(reg => {
|
|
const m = doc.match(reg)
|
|
m.fullPointer.forEach(a => {
|
|
starts[a[3]] = { fn: obj[reg], end: a[2] }
|
|
})
|
|
})
|
|
return starts
|
|
}
|
|
|
|
const wrap = function (doc, obj) {
|
|
// index ids to highlight
|
|
const starts = findStarts(doc, obj)
|
|
let text = ''
|
|
doc.docs.forEach((terms, n) => {
|
|
for (let i = 0; i < terms.length; i += 1) {
|
|
const t = terms[i]
|
|
// do a span tag
|
|
if (Object.hasOwn(starts, t.id)) {
|
|
const { fn, end } = starts[t.id]
|
|
const m = withoutEnds(doc.update([[n, i, end]]))
|
|
text += terms[i].pre || ''
|
|
text += fn(m)
|
|
i = end - 1
|
|
text += terms[i].post || ''
|
|
} else {
|
|
text += toText(t)
|
|
}
|
|
}
|
|
})
|
|
return text
|
|
}
|
|
export default wrap |