rust-lang / mdBook

Create book from markdown files. Like Gitbook but implemented in Rust
https://rust-lang.github.io/mdBook/
Mozilla Public License 2.0
17.69k stars 1.61k forks source link

Support Katex #651

Open Timmmm opened 6 years ago

Timmmm commented 6 years ago

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.

clarfonthey commented 6 years ago

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

brendanzab commented 6 years ago

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!

Michael-F-Bryan commented 6 years ago

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:

brendanzab commented 6 years ago

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

Michael-F-Bryan commented 6 years ago

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.

brendanzab commented 6 years ago

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

clarfonthey commented 6 years ago

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.

dkotrada commented 5 years ago

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

jens1o commented 5 years ago

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

leesei commented 5 years ago

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.

shilangyu commented 4 years ago

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

recmo commented 4 years ago

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/katex@0.11.1/dist/katex.min.css"
    integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq"
    crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js"
    integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz"
    crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/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>
tavianator commented 4 years ago

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](https://github.com/tavianator/tavianator.com/blob/main/theme/head.hbs) is enough to render everything client side.  I'm [working on](https://github.com/tavianator/tavianator.com/blob/preproc-katex/preproc/src/main.rs) 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
lzanini commented 3 years ago

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.

tavianator commented 3 years ago

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

lzanini commented 3 years ago

@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 :)

TeomanEgeSelcuk commented 2 years ago

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

TeomanEgeSelcuk commented 2 years ago

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

SichangHe commented 2 years ago

@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 commented 1 year ago

@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 commented 1 year ago

@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.