Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for KaTeX #292

Closed
adius opened this issue Oct 20, 2015 · 16 comments
Closed

Support for KaTeX #292

adius opened this issue Oct 20, 2015 · 16 comments
Assignees

Comments

@adius
Copy link

adius commented Oct 20, 2015

Kramdown should have a math engine for KaTeX!

@gettalong
Copy link
Owner

Pull-requests are welcome!

@jkm
Copy link

jkm commented Jun 18, 2016

What do you prefer a nodejs solution similar to the MathjaxNode engine or a solution based on execjs? In the former case the user needs to keep katex up to date via npm whereas in the latter case one needs to download the katex.min.js and possibly add checking if an updated version becomes available.

@gettalong
Copy link
Owner

If I understand correctly KaTeX is in the same league as MathJax, so kramdown would just need to emit the correct HTML fragments for KaTeX - or am I wrong?

@jkm
Copy link

jkm commented Jun 18, 2016

Yes. I think that's the case. katex will generate the HTML for given LaTeX-like input.

@gettalong
Copy link
Owner

Okay, then there is no need for NodeJS or execjs or anything which is good.

@jkm
Copy link

jkm commented Jun 19, 2016

Not sure I get it. I assume katex is installed.
Then executing

$ node ka.js

results in

<span class="katex">
    <span class="katex-mathml">
        <math>
            <semantics>
            <mrow>
            <mi>c</mi>
            <mo>=</mo>
            <mo>±</mo>
            <msqrt>
            <mrow>
            <msup>
            <mi>a</mi>
            <mn>2</mn>
            </msup>
            <mo>+</mo>
            <msup>
            <mi>b</mi>
            <mn>2</mn>
            </msup>
            </mrow>
            </msqrt>
            </mrow>
            <annotation encoding="application/x-tex">c = \pm\sqrt{a^2 + b^2}</annotation></semantics>
        </math>
    </span>
    <span class="katex-html" aria-hidden="true">
        <span class="strut" style="height:0.913389em;"></span>
        <span class="strut bottom" style="height:1.04em;vertical-align:-0.12661100000000008em;"></span>
        <span class="base textstyle uncramped">
            <span class="mord mathit">c</span>
            <span class="mrel">=</span>
            <span class="mord">±</span>
            <span class="sqrt mord">
                <span class="sqrt-sign" style="top:-0.07338899999999993em;">
                    <span class="style-wrap reset-textstyle textstyle uncramped"></span>
                </span>
                <span class="vlist"><span style="top:0em;">
                        <span class="fontsize-ensurer reset-size5 size5">
                            <span style="font-size:1em;"></span>
                        </span>
                        <span class="mord textstyle cramped">
                            <span class="mord">
                                <span class="mord mathit">a</span>
                                <span class="vlist">
                                    <span style="top:-0.289em;margin-right:0.05em;">
                                        <span class="fontsize-ensurer reset-size5 size5">
                                            <span style="font-size:0em;"></span>
                                        </span>
                                        <span class="reset-textstyle scriptstyle cramped">
                                            <span class="mord mathrm">2</span>
                                        </span>
                                    </span>
                                    <span class="baseline-fix">
                                        <span class="fontsize-ensurer reset-size5 size5">
                                            <span style="font-size:0em;"></span>
                                        </span></span>
                                </span>
                            </span>
                            <span class="mbin">+</span>
                            <span class="mord">
                                <span class="mord mathit">b</span>
                                <span class="vlist">
                                    <span style="top:-0.289em;margin-right:0.05em;">
                                        <span class="fontsize-ensurer reset-size5 size5">
                                            <span style="font-size:0em;"></span>
                                        </span>
                                        <span class="reset-textstyle scriptstyle cramped">
                                            <span class="mord mathrm">2</span>
                                        </span>
                                    </span>
                                    <span class="baseline-fix">
                                        <span class="fontsize-ensurer reset-size5 size5">
                                            <span style="font-size:0em;"></span>
                                        </span></span>
                                </span>
                            </span>
                        </span>
                    </span>
                    <span style="top:-0.8333889999999999em;">
                        <span class="fontsize-ensurer reset-size5 size5">
                            <span style="font-size:1em;"></span>
                        </span>
                        <span class="reset-textstyle textstyle uncramped sqrt-line"></span>
                    </span>
                    <span class="baseline-fix">
                        <span class="fontsize-ensurer reset-size5 size5">
                            <span style="font-size:1em;"></span>
                        </span></span>
                </span>
            </span>
        </span>
    </span>
</span>

where ka.js is

var katex = require('katex');
var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}");
console.log(html);

@gettalong
Copy link
Owner

If I understand the KaTeX website correctly, you could do server side rendering but better for kramdown is client side rendering. So no need for any Javascript interpreter whatsoever.

@jkm
Copy link

jkm commented Jun 19, 2016

True. You can run it client-side using javascript or render it once statically. I prefer the second mode. Because my input is static. So I won't need javascript on the client. But what came to my mind is that the statically rendered version is much larger than its input. So maybe I should try the dynamic version first.

@jkm
Copy link

jkm commented Jun 27, 2016

So how do I add client side rendering? Do you have an example on how to use KaTeX inside kramdown?

@gettalong
Copy link
Owner

This should probably help but note that I'm not familiar with KaTeX, I was just googling...

@dato
Copy link

dato commented Nov 2, 2016

TL;DR: I don’t think Kramdown should to anything (for client-side rendering). With some glue, KaTeX already works. See instructions and a longer explanation below.

IMHO this pull request should be closed. (I use KaTeX myself.)


As I understand it, Kramdown parses as math text wrapped in $$ x $$, and outputs it verbatim inside a <script type="math/ext"> block.

If the HTML page loads MathJax, those blocks get rendered as math—because Mathjax searches for them. End of story.

KaTeX provides (I think) no “official” support for live-rendering. There is the contrib/auto-render extension that gettalong linked, but:

  • that extension is normally configured to parse the served HTML for content wrapped in $ x $, or $$ x $$, or \( x \), or $\[ x \] (it’s configurable)—and it interprets it as math.
  • the easy-to-make request here (which I advise against) would be to have Kramdown pass the $$ themselves into HTML—if KaTeX is configured as the math engine. Result: two incompatible versions of HTML generated.
  • alternative: let Kramdown’s output remain the same, and force the use of KaTeX when serving the document:
    1. instead of MathJax Javascript, KaTeX is loaded in the header (auto-render extension not needed)

    2. use a Javascript snippet at the end of the page (jQuery helps) to feed to KaTeX every <script type="math/tex"> block. Example code:

       <script>
         $("script[type='math/tex']").replaceWith(function() {
             var tex = $(this).text();
             return katex.renderToString(tex, {displayMode: false});
         });
      
         $("script[type='math/tex; mode=display']").replaceWith(function() {
             var tex = $(this).html();
             // replace() here is due to CDATA wrapper (#224). KaTeX chokes on the % character,
             // which is unfortunate (and should probably be reported).
             return katex.renderToString(tex.replace(/%.*/g, ''), {displayMode: true});
         });
       </script>
    3. If you use templating, you could wrap the above with {% if page.math %} (and set that variable in pages that need it)

In summary: I believe the customization belongs in the serving step rather than the HTML generation step. MathJax and KaTeX can be exchanged freely, without Kramdown’s involvement.


(Side note: a nice thing would be if Kramdown could accept single-dollar escape for math, e.g. $ x $. It would make it compatible with Pandoc.)

@dato
Copy link

dato commented Nov 2, 2016

Ah! Now that I see #342: if you don’t think you’ll swap with MathJax you could use --math-engine=nil, and use the auto-renderer.

(Though I believe it’s safer to have the fallback, in case there’s a tricky input KaTeX can’t render.)

@gettalong
Copy link
Owner

@dato Thanks for the information. I have updated the documentation on the MathJax page to include information about using KaTeX. Thanks for the script you provided.

gettalong added a commit that referenced this issue Nov 13, 2016
The information and script were provided in issue #292.
@meygerjos
Copy link

@dato This problem occurs with both inline math and display math, so your code should apply the replace statement to both selectors. Something like this:

<script>
   $("script[type='math/tex'],script[type='math/tex; mode=display']").replaceWith(function() {
       var tex = $(this).html();
       // replace() here is due to CDATA wrapper (#224). KaTeX chokes on the % character,
       // which is unfortunate (and should probably be reported).
       return katex.renderToString(tex.replace(/%.*/g, ''), {displayMode: true});
   });
 </script>

(I'm not sure if the jQuery syntax is right.)

@chnn
Copy link

chnn commented Jul 6, 2017

For those not using jQuery, here's a version of @dato's script that should work in IE 9+:

document.querySelectorAll("script[type='math/tex']").forEach(function(el) {
  el.outerHTML = katex.renderToString(el.textContent, { displayMode: false });
});

document.querySelectorAll("script[type='math/tex; mode=display']").forEach(function(el) {
  el.outerHTML = katex.renderToString(el.textContent.replace(/%.*/g, ''), { displayMode: true });
});

zYeoman added a commit to zYeoman/3-Jekyll that referenced this issue Jul 17, 2018
方案来自 gettalong/kramdown#292

另,https://github.com/gettalong/kramdown/issues/342有对katex的支持方案

echo "$$x$$" | kramdown --math-engine nil ->
<div class="kdmath">$$x$$</div>

echo "t$$x$$t" | kramdown --math-engine nil ->
<p>t<span class="kdmath">$x$</span>t</p>
@filipre
Copy link

filipre commented May 5, 2020

@chnn That code was very useful, thanks. However, the display mode will fail if you use the actual percent symbol (\%) and not a comment %.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants