2

I am building an online community for IB Math students and for that I plan to use Circle.so. Circle.so seems like a great option given its features (like code injection) and design.

One of the features that the forum tool (such as Circle) needs to have is the ability to render Math notation (LaTeX) or allow code injection so KaTeX or MathJax can be used. KaTeX seems to solve the problem. I am testing/trying to install KaTeX and I have the options to inject code in the head and as a javascript snippet (as shown in the image below).

enter image description here

I have zero programming skills, I wonder if anyone has done it or could help me accomplish that. For the head portion, I placed the following code (it didn't work).

<!-- The loading of KaTeX is deferred to speed up page rendering -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.6/dist/katex.min.js" integrity="sha384-ljao5I1l+8KYFXG7LNEA7DyaFvuvSCmedUf6Y6JI7LJqiu8q5dEivP2nDdFH31V4" crossorigin="anonymous"></script>

<!-- To automatically render math in text elements, include the auto-render extension: -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.6/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"
    onload="renderMathInElement(document.body);"></script>

KaTeX's documentation can be found here.

Obs: Circle.so has the option to insert custom CSS (if that helps)

bru1987
  • 56
  • 2
  • 14
  • Looks like maybe this should be migrated to https://webapps.stackexchange.com , not sure though. – Jacob May 30 '22 at 11:58
  • From the screenshot you have provided, it looks like the second field (javascript) is for some inline code only, it states please exclude the ``` – Luke Celitan May 30 '22 at 12:09

1 Answers1

1

This is a 2 part problem, one pretty easy the other a bit harder.

Problem 1

Parsing KATEX

This is relatively easy,

We add the scripts and styles on the page and our custom script to select and render text.

This can go under Header code snippets

Notice: No defer attribute to make it load before JS code runs.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.6/dist/katex.css" integrity="sha384-jJFDzw6Rh7jzIumRp31oSKurBXlvFPBHbzi9KbVukp6ZNECGD4UKyhO5tJaJ1uHA" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.6/dist/katex.js" integrity="sha384-Xfbu6aqAjKdi+UhRmQROxVxvx/iT6irqZqIPGKTbtyjUVRkdg3aEiaxuMdfVqNyu" crossorigin="anonymous"></script>

And some JS to render KATEX strings.

katex.renderToString( katexText, {
  throwOnError: false
});

Unresolved issues

We don't know...

  1. which text to render Katex.
  2. where to place the rendered text.

Problem 2

How do users insert Katex

This is a challenging one coz we don't control the UI. However a workaround could be to use Code option from the toolbar.

enter image description here

enter image description here

However we don't want to parse and potentially break all code blocks, but only specific ones, for this we could add in a key word to trigger katex and keyword can just be katex. So to use katex, users would add a code block with katex on first line and our JS will take it from there.

This can go under Header code snippets

<script id=''>
    // Find all `pre` tags
    document.querySelectorAll('.trix-content pre').forEach(function(el) {
        // Get text inside
        var text = el.innerText.replace(/^\s+|\s+$/gm, '');
        // Do stuff if text starts with `latex`
        if (0 === text.indexOf('katex')) {
            var renderedKatex = katex.renderToString(
                text.replace('katex', ''),
                {throwOnError: false}
            );
            // Populate katex and additional markup for formatting
            el.outerHTML =
                '<span></span><section class="katex-wrap">' +
                renderedKatex + '</section>';
        }
    })
<script>
Before scripts

Before scripts

After scripts

After scripts

Working snippet

// Find all `pre` tags
document.querySelectorAll('.trix-content pre').forEach(function(el) {
  // Get text inside
  var text = el.innerText.replace(/^\s+|\s+$/gm, '');
  // Do stuff if text starts with `latex`
  if (0 === text.indexOf('katex')) {
    var renderedKatex = katex.renderToString(text.replace('katex', ''), {
      throwOnError: false
    });
    // Populat katex and additional markup for formatting
    el.outerHTML = '<span></span><section class="katex-wrap">' + renderedKatex + '</section>';
  }
})
.post__more {
  display: none;
}
<!-- THIS GOES IN HEAD CODE SNIPPETS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.6/dist/katex.css" integrity="sha384-jJFDzw6Rh7jzIumRp31oSKurBXlvFPBHbzi9KbVukp6ZNECGD4UKyhO5tJaJ1uHA" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.6/dist/katex.js" integrity="sha384-Xfbu6aqAjKdi+UhRmQROxVxvx/iT6irqZqIPGKTbtyjUVRkdg3aEiaxuMdfVqNyu" crossorigin="anonymous"></script>

<h1>Typical circle.so markup</h1>

<h2>Main post content markup</h2>

<div class="post__body">
  <div class="post__inside trix-v2  expanded">
    <div class="react-trix-content fullscreen-preview-enabled">
      <div>
        <div class="trix-content">
          <pre>katex
c = \pm\sqrt{a^2 + b^2}</pre>
        </div>
      </div>
    </div>
  </div>
</div>

<h2>Comment post content markup</h2>

<div class="post__body" data-controller="post">
  <div class="post__inside">
    <div class="trix-content">
      <div>Ordinary code block,</div>
      <pre>const jsVar = 'mi secreto';</pre>
      <div>
        <br>Latex code block<br><br>
      </div>
      <pre>katex
e = mc^2</pre>
      <div></div>
    </div>
  </div>
</div>
shramee
  • 5,030
  • 1
  • 22
  • 46