mdBook icon indicating copy to clipboard operation
mdBook copied to clipboard

Support Katex

Open Timmmm opened this issue 6 years ago • 21 comments

It would be good to support Katex as an alternative to MathJax. It's much faster, especially on mobile.

Comparison of speed and rendering differences here.

Timmmm avatar Mar 27 '18 12:03 Timmmm

Another benefit of KaTeX is that it also allows pre-rendering, which can further improve speeds.

clarfonthey avatar Mar 27 '18 16:03 clarfonthey

This would be super cool. My mathjax page is getting super heavy with notation and takes forever to reflow! It's also a painful experience when hot-reloading, because the reliance on reflow means that the scrollbar loses its place. Pre-rendering would be much appreciated!

brendanzab avatar Apr 26 '18 02:04 brendanzab

It sounds like using Katex could make the user experience nicer for people with loads of equations, so I'm all for the idea. Adding Katex support would probably require somebody to champion the feature seeing as it's touching a non-trivial amount of the code base.

The code itself shouldn't be too much, but it requires tweaking the renderer and/or creating a pre-processor to update the source document with appropriate annotations.

I'm also happy to help mentor and or point people in the right direction :grin:

Michael-F-Bryan avatar May 01 '18 12:05 Michael-F-Bryan

How might Katex be included/distributed with the mdbook binary? Seeing as it is a JS thingy?

brendanzab avatar May 01 '18 15:05 brendanzab

I'm not 100% sure. If it's a JS thing and used purely in the browser (i.e. after a book is rendered as HTML) then it should, in theory, be no different from JQuery or highlight.js.

I know @sorin-davidoi and @mattico have done some work with our JS/CSS stuff in the past, so they may be able to elaborate more.

Michael-F-Bryan avatar May 02 '18 10:05 Michael-F-Bryan

It's run as a preprocessing step, so would probably require the user had node installed.

brendanzab avatar May 02 '18 11:05 brendanzab

It can be done by the autorenderer, but yeah, it works best when used in advance for speed.

Doing it fully in the browser, though, would be an improvement on MathJax anyway. It'd be reasonable to start there.

clarfonthey avatar May 03 '18 04:05 clarfonthey

How might Katex be included/distributed with the mdbook binary? Seeing as it is a JS thingy?

Is a node module https://katex.org/docs/node.html

dkotrada avatar Dec 15 '18 16:12 dkotrada

is there anything I can work on to make this a reality?

jens1o avatar Jul 06 '19 11:07 jens1o

How might Katex be included/distributed with the mdbook binary? Seeing as it is a JS thingy?

Is a node module katex.org/docs/node.html

Well, it is indeed a JS thingy. Just like MathJax it is included via CDN.
Browser · KaTeX

May be a preprecessor is better for this, see example mermaid integration.

leesei avatar Jul 08 '19 04:07 leesei

I am willing to help with this, can I get some pointers?

shilangyu avatar Mar 01 '20 20:03 shilangyu

Unfortunately there is no easy way to inject HTML into the default template, but using a preprocesor worked for me. So far this solution has no problems with using $$ and $ delimiters, but it does require \\ and \! to have their slashes doubled.

book.toml:

[preprocessor.katex]
command = "python3 katex.py"
renderer = ["html"]

katex.py:

#!/usr/bin/env python3
import json
import sys

if len(sys.argv) > 1:
    if sys.argv[1] == 'supports':
        # sys.argv[2] is the renderer name
        sys.exit(0)

katex = '\n' + open('./katex-header.html', 'r').read()
context, book = json.load(sys.stdin)

def fix(items):
    for section in items:
        if 'Chapter' in section:
            section['Chapter']['content'] += katex
            fix(section['Chapter']['sub_items'])

fix(book['sections'])
json.dump(book, sys.stdout)

katex-header.html:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
    integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq"
    crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"
    integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz"
    crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"
    integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI"
    crossorigin="anonymous"></script>
<script>
    document.addEventListener("DOMContentLoaded", function () {
        renderMathInElement(document.body, {
            delimiters: [
                { left: "$$", right: "$$", display: true },
                { left: "\\(", right: "\\)", display: false },
                { left: "$", right: "$", display: false },
                { left: "\\[", right: "\\]", display: true }
            ]
        });
    });
</script>

recmo avatar Apr 10 '20 01:04 recmo

I have what I think is a nice approach implemented in https://github.com/tavianator/tavianator.com

Inline LaTeX is delimited by `$\LaTeX$`, and display mode math is

```math
\LaTeX
```

Using code regions for this is nice because you don't have to duplicate any backslashes. A custom head.hbs is enough to render everything client side. I'm working on a custom preprocessor to pre-render everything server side. The main problem right now is it's super slow to shell out to katex every time.

Here's what it looks like: https://tavianator.com/2014/ellipsoid_bounding_boxes.html

tavianator avatar Jul 27 '20 19:07 tavianator

I implemented a Rust pre-processor to render Katex equations at compile-time, you can find the project here.

Usage

Install the crate

cargo install mdbook-katex

Add the preprocessor to your book.toml

[preprocessor.katex]

Use $ and $$ delimiters within your .md files.

# Chapter 1

Here is an inline example, $ \pi(\theta) $, 

An equation:

$$ \nabla f(x) \in \mathbb{R}^n $$

And a regular \$ symbol.

Works fine for me, however I'd love to get some feedback!

Edit: Macros are also supported, see the project page for details.

lzanini avatar Nov 18 '20 13:11 lzanini

@lzanini Just skimmed the code but is there a way to escape a $ so it shows up literally?

tavianator avatar Nov 18 '20 20:11 tavianator

@tavianator Not right now, but it shouldn't be too hard to ignore a \$. Let me give it a try and I'll let you know when it's done.

Edit: Done :)

lzanini avatar Nov 18 '20 20:11 lzanini

Hi, I get an error trying to install katex error: failed to run custom build command for libquickjs-sys v0.9.0` does anyone have a way to fix this?

TeomanEgeSelcuk avatar May 12 '22 02:05 TeomanEgeSelcuk

thread 'main' panicked at 'Could not apply patches: Error { kind: NotFound, message: "program not found" }', C:\Users\Edge\.cargo\registry\src\github.com-1ecc6299db9ec823\libquickjs-sys-0.9.0\build.rs:133:14

TeomanEgeSelcuk avatar May 12 '22 02:05 TeomanEgeSelcuk

@lzanini's Katex preprocessor seems to be idle (No stable release for a year nor activity in issues/ pull requests by owner). Does anyone want to help?

SichangHe avatar Aug 17 '22 09:08 SichangHe

@Edgehere, I have recently looked at the problem you encountered. Currently, I don't have a good solution and have compromised the Windows build. You can get an uncompromised mdbook-katex on WSL, though, I believe.

SichangHe avatar Dec 15 '22 11:12 SichangHe

@Edgehere, I have recently looked at the problem you encountered. Currently, I don't have a good solution and have compromised the Windows build. You can get an uncompromised mdbook-katex on WSL, though, I believe.

This issue should be gone because of https://github.com/lzanini/mdbook-katex/issues/67.

SichangHe avatar Feb 24 '23 11:02 SichangHe