0

I'm building a Q&A chat widget that uses marked.js for Markdown rendering and KaTeX for mathematical expressions. The backend returns LaTeX-formatted math, but it's displaying as raw text instead of properly rendered equations. I need all mathematical expressions to be properly formatted, regardless of how they're delimited in the source.

Current Behavior

The AI response comes back with LaTeX math like this:

The symbol \pm indicates that there are generally two solutions...
The term b^2 - 4ac is known as the discriminant...
If b^2 - 4ac > 0: Two distinct real roots.
If b^2 - 4ac = 0: One real root (a repeated root).
If b^2 - 4ac < 0: No real roots (the roots are complex).

Instead of properly rendered math symbols (±, b²-4ac, >, =, <), I see the raw LaTeX code as plain text.

Expected Behavior

All math expressions should render as formatted equations using KaTeX:

  • \pm should render as ±
  • b^2 - 4ac should render as b²-4ac with proper superscripts
  • All mathematical operators and expressions should be beautifully formatted
  • Both inline and display math should work seamlessly.

Relevant Code

HTML Setup:

<!-- KaTeX CSS and JS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"></script>

<!-- Markdown parser -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>

JavaScript rendering function:

function renderMath(element) {
  if (window.renderMathInElement) {
    renderMathInElement(element, {
      delimiters: [
        {left: '$$', right: '$$', display: true},
        {left: '$', right: '$', display: false},
        {left: '\\[', right: '\\]', display: true},
        {left: '\\(', right: '\\)', display: false},
        {left: '[ ', right: ' ]', display: true},
        {left: '[', right: ']', display: true}
      ],
      throwOnError: false,
      ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
      processEscapes: true
    });
  }
}

Message appending function:

function appendMessage(text, from) {
  window.chatBuffer.push({ text, from });
  if (window.chatBuffer.length > 50) window.chatBuffer.shift();

  const wrap = document.createElement("div");
  wrap.className = `message ${from}`;
  const bubble = document.createElement("div");
  
  if (text.startsWith('Selected subject:') || text.startsWith('Welcome!')) {
    bubble.className = "subject-notification";
    bubble.textContent = text;
  } else {
    bubble.className = "bubble";
    
    if (from === "model") {
      bubble.innerHTML = marked.parse(text);
      
      // Render math expressions after DOM insertion
      setTimeout(() => {
        renderMath(bubble);
      }, 10);
    } else {
      bubble.textContent = text;
    }
  }

  wrap.appendChild(bubble);
  messagesEl.appendChild(wrap);
  messagesEl.scrollTop = messagesEl.scrollHeight;
}

How can I ensure ALL math expressions are properly formatted?

0

1 Answer 1

1

This part

delimiters: [
        {left: '$$', right: '$$', display: true},
        {left: '$', right: '$', display: false},
        {left: '\\[', right: '\\]', display: true},
        {left: '\\(', right: '\\)', display: false},
        {left: '[ ', right: ' ]', display: true},
        {left: '[', right: ']', display: true}
],

tells the parser to look for specific delimiters such as "$$" in the text. When it sees the delimiter around an expression, it starts evaluating the expression in order to render it.

Try with this text instead :

The symbol \pm indicates that there are generally two solutions...
The term b^2 - 4ac is known as the discriminant...
If $$b^2 - 4ac > 0$$: Two distinct real roots.
If [b^2 - 4ac = 0]: One real root (a repeated root).
If \(b^2 - 4ac < 0]\): No real roots (the roots are complex).

As you can see, the first expression isn't rendered (no delimiters) but the others are (and the last one is inline too). So in order to solve your problem, you need to add those delimiters to your text, when there are mathematical expressions. I suppose you could do this server side.

Full working minimal example :

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"></script>

<p>The symbol \pm indicates that there are generally two solutions...
The term b^2 - 4ac is known as the discriminant...
If $$b^2 - 4ac > 0$$: Two distinct real roots.
If [b^2 - 4ac = 0]: One real root (a repeated root).
If \(b^2 - 4ac < 0]\): No real roots (the roots are complex).</p>

<script>
  function renderMath(element) {
  if (window.renderMathInElement) {
    renderMathInElement(element, {
      delimiters: [
        {left: '$$', right: '$$', display: true},
        {left: '$', right: '$', display: false},
        {left: '\\[', right: '\\]', display: true},
        {left: '\\(', right: '\\)', display: false},
        {left: '[ ', right: ' ]', display: true},
        {left: '[', right: ']', display: true}
      ],
      throwOnError: false,
      ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
      processEscapes: true
    });
  }
}

renderMath(document.body)
</script>

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.