rich-text-editor
Version:
Rich text editor
92 lines (83 loc) • 2.88 kB
JavaScript
const mjAPI = require('mathjax-node')
const MAX_NESTING_LEVEL = 20
const MAX_LENGTH = 5000
const nestedContextStartedRegexes = ['\\left', '{', '\\begin']
const nestedContextEndingRegexes = ['\\right', '}', '\\end']
const errorResponse = ` xml version="1.0" encoding="UTF-8" standalone="no"
<svg width="305px" height="20px" viewBox="0 0 305 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Group 2</title>
<defs></defs>
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-241.000000, -219.000000)">
<g transform="translate(209.000000, 207.000000)">
<rect x="-1.58632797e-14" y="0" width="80" height="40"></rect>
<g transform="translate(32.000000, 12.000000)">
<polygon id="Combined-Shape" fill="#9B0000" fill-rule="nonzero" points="0 18 8.04006 2 16.08012 18"></polygon>
<polygon id="Combined-Shape-path" fill="#FFFFFF" points="7 14 9 14 9 16 7 16"></polygon>
<polygon id="Combined-Shape-path" fill="#FFFFFF" points="7 7 9 7 9 12 7 12"></polygon>
</g>
</g>
</g>
</g>
<text x="25" y="16" fill="red">Virhe LaTeX-koodissa / Fel i LaTeX-koden</text>
</svg>`
module.exports = { mathSvgResponse, latexToSvg }
mjAPI.config({
extensions: 'Safe,TeX/mhchem.js',
MathJax: {
SVG: {
font: 'Latin-Modern',
},
},
})
mjAPI.start()
function mathSvgResponse(req, res) {
res.type('svg')
const latex = req.query.latex
if (latex === undefined) {
res.sendStatus(400)
return
}
// non-breaking spaces are replaced server side as well to render existing formulas correctly
const normalizedLatex = latex.replaceAll('\u00A0', '\\ ')
latexToSvg(normalizedLatex, (svg) => res.send(svg))
}
function latexIsTooLong(latex) {
return latex && latex.length > MAX_LENGTH
}
function nestingIsTooDeep(latex) {
let nestingLevel = 0
const matches = latex.match(/\\right|\\left|\\begin|\\end|\{|\}/g)
if (!matches) {
return false
}
for (var matchedString of matches) {
if (nestedContextStartedRegexes.some((startingRegex) => startingRegex === matchedString)) nestingLevel++
else if (nestedContextEndingRegexes.some((endingRegex) => endingRegex === matchedString)) nestingLevel--
if (nestingLevel > MAX_NESTING_LEVEL) return true
}
return false
}
function latexToSvg(latex, cb) {
if (latexIsTooLong(latex) || nestingIsTooDeep(latex)) {
cb(errorResponse)
return
}
mjAPI.typeset(
{
math: latex,
format: 'TeX', // "inline-TeX", "MathML"
mml: false,
svg: true,
linebreaks: true,
width: 100,
},
(data) => {
if (data.errors) {
cb(errorResponse)
} else {
cb(data.svg)
}
},
)
}