Skip to content

Commit

Permalink
Attempt to fix markdown KaTeX rendering issue (#290)
Browse files Browse the repository at this point in the history
* Attempt to fix markdown KaTeX rendering issue

**Disclaimer**: I only "tested" this with the math shown in the
description of `/jobs/b6187b88-a423-4ab4-94d2-e7eba2b0bd25`.

* Attempt to fix KaTeX for quizes

* Fix KaTeX rendering for coding challenge card

---------

Co-authored-by: Jonathan2k19 <[email protected]>
Co-authored-by: Felix Bargfeldt <[email protected]>
  • Loading branch information
3 people authored Nov 1, 2024
1 parent 9c32221 commit 21ca1be
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 25 deletions.
4 changes: 2 additions & 2 deletions components/CodingChallenge/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<article class="flex gap-3 justify-between">
<p
v-if="!!codingChallenge?.description"
class="sm:w-3/4 clamp tight line-1 text-accent"
class="sm:w-3/4 tight text-accent"
>
{{ codingChallenge?.description ?? "" }}
<span v-html="$md.render(codingChallenge?.description ?? '')"></span>
</p>

<ArrowRightIcon
Expand Down
2 changes: 1 addition & 1 deletion components/form/QuizAnswer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
ref="refForm"
>
<h4 class="text-heading-3 text-accent">
Q). {{ subtask?.question ?? "" }}
Q). <span v-html="$md.render(subtask?.question ?? '')"></span>
</h4>
<p
class="text-heading2 text-sm"
Expand Down
4 changes: 3 additions & 1 deletion components/quiz/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
v-else-if="user?.id == data?.creator && !user.admin"
class="bg-accent rounded-full p-0.5 h-6 w-6 text-white absolute -right-1 -top-1.5"
/>
<h3 class="text-heading-4 clamp line-2">Q). {{ data?.question ?? "" }}</h3>
<h3 class="text-heading-4">
Q). <span v-html="$md.render(data?.question ?? '')"></span>
</h3>

<div class="flex justify-between gap-box items-center">
<p class="text-body-2" v-if="data?.single_choice">
Expand Down
59 changes: 38 additions & 21 deletions plugins/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import MarkdownIt from 'markdown-it';
import katex from 'katex';
import hljs from 'highlight.js';
import DOMPurify from 'dompurify';
import 'katex/dist/katex.min.css';

export default defineNuxtPlugin((app) => {
const md = new MarkdownIt({
Expand Down Expand Up @@ -32,31 +33,47 @@ export default defineNuxtPlugin((app) => {

const start = state.pos;
const end = state.posMax;
let tex = '';
let isDisplayMath = false;

if (state.src[start] !== '$' || state.src[start + 1] !== '$') return false;
if (state.src[end - 1] !== '$' || state.src[end - 2] !== '$') return false;
/* Display math is surrounded by $$. Inline math is surrounded by $. */
if (state.src[start] === '$' && state.src[end - 1] === '$') {
if (state.src[start + 1] === '$' && state.src[end - 2] === '$') {
isDisplayMath = true;
state.pos += 2;

state.pos = start + 2;
while (state.pos < end - 2) {
if (state.src[state.pos] === '$' && state.src[state.pos + 1] === '$')
break;
state.pos++;
}
state.pos += 2;

const tex = state.src.slice(start + 2, state.pos - 2);

try {
const html = katex.renderToString(tex);
const sanitizedHtml = DOMPurify.sanitize(html);
const token = state.push('html_inline', '', 0);
token.content = sanitizedHtml;
} catch (err) {
if (!silent) console.error(err);
return false;
while (state.pos < end - 2) {
if (state.src[state.pos] === '$' && state.src[state.pos + 1] === '$')
break;
tex += state.src[state.pos++];
}
} else {
isDisplayMath = false;
state.pos++;

while (state.pos < end - 1) {
if (state.src[state.pos] === '$')
break;
tex += state.src[state.pos++];
}
}

try {
/* Remove invalid characters from input. Then try rendering. */
const cleanedTex = tex.replace(/[^a-zA-Z0-9{}()\\^_\/\+\-\=\[\] \:\;\.,]/g, '');
const html = katex.renderToString(cleanedTex, { displayMode: isDisplayMath });
const sanitizedHtml = DOMPurify.sanitize(html);
const token = state.push('html_inline', '', 0);
token.content = sanitizedHtml;
} catch (err) {
if (!silent) console.error(err);
return false;
}

return true;
}

return true;
return false;
});

app.provide('md', md);
Expand Down

0 comments on commit 21ca1be

Please sign in to comment.