You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.3 KiB
JavaScript
84 lines
2.3 KiB
JavaScript
// took from: https://github.com/sxyazi/marked-extended-latex
|
|
// this has a peer dependency bug
|
|
|
|
const CLASS_NAME = 'latex-b172fea480b'
|
|
|
|
const extBlock = options => ({
|
|
name: 'latex-block',
|
|
level: 'block',
|
|
start(src) {
|
|
return src.match(/\$\$[^\$]/)?.index ?? -1
|
|
},
|
|
tokenizer(src, _tokens) {
|
|
const match = /^\$\$([^\$]+)\$\$/.exec(src)
|
|
return match ? { type: 'latex-block', raw: match[0], formula: match[1] } : undefined
|
|
},
|
|
renderer(token) {
|
|
if (!options.lazy) return options.render(token.formula, true)
|
|
return `<span class="${CLASS_NAME}" block>${token.formula}</span>`
|
|
},
|
|
})
|
|
|
|
const extInline = options => ({
|
|
name: 'latex',
|
|
level: 'inline',
|
|
start(src) {
|
|
return src.match(/\$[^\$]/)?.index ?? -1
|
|
},
|
|
tokenizer(src, _tokens) {
|
|
const match = /^\$([^\$]+)\$/.exec(src)
|
|
return match ? { type: 'latex', raw: match[0], formula: match[1] } : undefined
|
|
},
|
|
renderer(token) {
|
|
if (!options.lazy) return options.render(token.formula, false)
|
|
return `<span class="${CLASS_NAME}">${token.formula}</span>`
|
|
},
|
|
})
|
|
|
|
let observer
|
|
/* istanbul ignore next */
|
|
export default (options = {}) => {
|
|
/* istanbul ignore next */
|
|
if (options.lazy && options.env !== 'test') {
|
|
observer = new IntersectionObserver(
|
|
(entries, self) => {
|
|
for (const entry of entries) {
|
|
if (!entry.isIntersecting) {
|
|
continue
|
|
}
|
|
|
|
const span = entry.target
|
|
self.unobserve(span)
|
|
|
|
Promise.resolve(options.render(span.innerText, span.hasAttribute('block'))).then(html => {
|
|
span.innerHTML = html
|
|
})
|
|
span.classList.add('latex-rendered')
|
|
}
|
|
},
|
|
{ threshold: 1.0 },
|
|
)
|
|
}
|
|
|
|
return {
|
|
extensions: [extBlock(options), extInline(options)],
|
|
}
|
|
}
|
|
|
|
/* istanbul ignore next */
|
|
export const observe = () => {
|
|
if (!observer) {
|
|
return
|
|
}
|
|
|
|
observer.disconnect()
|
|
document.querySelectorAll(`span.${CLASS_NAME}:not(.latex-rendered)`).forEach(span => {
|
|
observer.observe(span)
|
|
})
|
|
}
|
|
|
|
/* istanbul ignore next */
|
|
export const disconnect = () => {
|
|
observer?.disconnect()
|
|
}
|