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...
- which text to render Katex.
- 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.


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

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>