diff --git a/fasthtml/js.py b/fasthtml/js.py
index d379e435..4b5d54e0 100644
--- a/fasthtml/js.py
+++ b/fasthtml/js.py
@@ -1,3 +1,4 @@
+import re
from fastcore.utils import *
from fasthtml.xtend import Script,jsd,Style,Link
@@ -12,17 +13,42 @@ def MarkdownJS(sel='.marked'):
src = "proc_htmx('%s', e => e.innerHTML = marked.parse(e.textContent));" % sel
return Script(marked_imp+src, type='module')
-def KatexMarkdownJS(sel='.marked', katex_tags='$'):
- right_tags = '\\$' if katex_tags=='$' else '\\]'
- src = """
- import katex from "https://cdn.jsdelivr.net/npm/katex/dist/katex.mjs";
- const renderMath = tex => katex.renderToString(tex, {throwOnError: false, displayMode: false});
+def KatexMarkdownJS(sel='.marked', inline_delim='$', display_delim='$$', math_envs=None):
+ math_envs = math_envs or ['equation', 'align', 'gather', 'multline']
+ env_list = ','.join(f"'{env}'" for env in math_envs)
- proc_htmx('%s', e => {
- e.innerHTML = marked.parse(e.textContent).replace(/%s{1,2}\\n*(.+?)\\n*%s{1,2}/g, (_, tex) => renderMath(tex));
+ src = r"""
+ import katex from "https://cdn.jsdelivr.net/npm/katex/dist/katex.mjs";
+ const renderMath = (tex, displayMode) => { return katex.renderToString(tex, {
+ throwOnError: false,
+ displayMode: displayMode,
+ output: 'html',
+ trust: true
+ });
+ };
+ const processLatexEnvironments = (content) => {
+ return content.replace(/\\begin{(\w+)}([\s\S]*?)\\end{\1}/g, (match, env, innerContent) => {
+ if ([%(env_list)s].includes(env)) { return `%(display_delim)s${match}%(display_delim)s`; }
+ return match;
+ });
+ };
+ proc_htmx('%(sel)s', e => {
+ let content = processLatexEnvironments(e.textContent);
+ // Handle display math (including environments)
+ content = content.replace(/%(display_delim)s([\s\S]+?)%(display_delim)s/gm, (_, tex) => renderMath(tex.trim(), true));
+ // Handle inline math
+ content = content.replace(/(? renderMath(tex.trim(), false));
+ e.innerHTML = marked.parse(content);
});
- """ % (sel, "\\"+katex_tags, right_tags)
- return (Script(marked_imp+src, type='module'),
+ """
+ format_dict = {
+ 'env_list': env_list,
+ 'sel': sel,
+ 'display_delim': re.escape(display_delim),
+ 'inline_delim': re.escape(inline_delim)
+ }
+ formatted_src = src % format_dict
+ return (Script(marked_imp + formatted_src, type='module'),
Link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css"))