diff --git a/app/assets/javascripts/notebook/cells/markdown.vue b/app/assets/javascripts/notebook/cells/markdown.vue index 4e0e60284f1..3e8240d10ec 100644 --- a/app/assets/javascripts/notebook/cells/markdown.vue +++ b/app/assets/javascripts/notebook/cells/markdown.vue @@ -10,8 +10,61 @@ import marked from 'marked'; import Prompt from './prompt.vue'; + const renderer = new marked.Renderer(); + + /* + Regex to match KaTex blocks. + + Supports the following: + + \begin{equation}\end{equation} + $$$$ + inline $$ + + The matched text then goes through the KaTex renderer & then outputs the HTML + */ + const katexRegexString = `( + ^\\\\begin{[a-zA-Z]+}\\s + | + ^\\$\\$ + | + \\s\\$(?!\\$) + ) + (.+?) + ( + \\s\\\\end{[a-zA-Z]+}$ + | + \\$\\$$ + | + \\$ + ) + `.replace(/\s/g, '').trim(); + + renderer.paragraph = (t) => { + let text = t; + let inline = false; + + if (typeof katex !== 'undefined') { + const katexString = text.replace(/\\/g, '\\'); + const matches = new RegExp(katexRegexString, 'gi').exec(katexString); + + if (matches && matches.length > 0) { + if (matches[1].trim() === '$' && matches[3].trim() === '$') { + inline = true; + + text = `${katexString.replace(matches[0], '')} ${katex.renderToString(matches[2])}`; + } else { + text = katex.renderToString(matches[2]); + } + } + } + + return `

${text}

`; + }; + marked.setOptions({ sanitize: true, + renderer, }); export default { @@ -26,20 +79,7 @@ }, computed: { markdown() { - const regex = new RegExp('^\\$\\$(.*)\\$\\$$', 'g'); - - const source = this.cell.source.map((line) => { - const matches = regex.exec(line.trim()); - - // Only render use the Katex library if it is actually loaded - if (matches && matches.length > 0 && typeof katex !== 'undefined') { - return katex.renderToString(matches[1]); - } - - return line; - }); - - return marked(source.join('')); + return marked(this.cell.source.join('')); }, }, }; @@ -50,4 +90,9 @@ display: block; text-align: center; } + +.markdown .inline-katex .katex { + display: inline; + text-align: initial; +}