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

Add LaTeX support to Rustdoc #34261

Closed
alilleybrinker opened this issue Jun 13, 2016 · 17 comments
Closed

Add LaTeX support to Rustdoc #34261

alilleybrinker opened this issue Jun 13, 2016 · 17 comments

Comments

@alilleybrinker
Copy link
Contributor

This has been discussed before (#17390 and #16300), but it's been a while since then, and may be worth discussing.

There are a number of options for implementing LaTeX in the browser. I believe KaTeX remains the most efficient option, and is probably the one we should go with, but if I'm wrong or if people have strong feelings in support of another option we can try something else.

I am happy to make this happen if it's something people want.

@hanna-kruppe
Copy link
Contributor

Is there a common markdown extension syntax for Latex expressions? Hopefully we won't stay on hoedown forever (cf. #33771) and the surface syntax should remain the same when replacing hoedown.

@ghost
Copy link

ghost commented Oct 13, 2016

@AndrewBrinker Curious why you closed this?

Speaking broadly, if Rust wants to be a major systems language, supporting linear algebra/signal processing applications is on the table. It already does that pretty well as a language construct, but it's exceedingly incongruous in this day and age that the docs don't.

Speaking specifically, I want to document this digital filter library I just made properly.

So I think there's a real use case here 😉

@alilleybrinker
Copy link
Contributor Author

Oh, I didn't mean to close this!

@masonium
Copy link

masonium commented Nov 4, 2016

Just to put in 👍 on addressing this issue.

I'm currently working on a linear algebra library, and documentation without LaTeX is pretty painful.

I would definitely be willing to take this on in rustdoc, though this would be my first foray into the rust codebase itself.

@Mark-Simulacrum
Copy link
Member

I am going to close this. This is a fairly large feature request, and in my opinion needs an RFC or at least some discussion on internals.rust-lang.org. Please open a thread there if you're actively interested!

@ThrashAbaddon
Copy link

Is there an RFC for this?

@robinmoussu
Copy link

I would also be interested to know if there is an RFC about this.

@MingweiSamuel
Copy link
Contributor

MingweiSamuel commented Feb 16, 2022

You could implement this with a macro which renders the latex expression then converts it into a data url image.

#[doc = render_latex!(r#"\frac{1}{x}"#)]

For more see rust-lang/cargo#8905 (comment)

@Andlon
Copy link

Andlon commented Feb 17, 2022

You could implement this with a macro which renders the latex expression then converts it into a data url image.

#[doc = render_latex!(r#"\frac{1}{x}"#)]

For more see rust-lang/cargo#8905 (comment)

While this is an interesting idea, it doesn't work well in practice, for several reasons:

  • TeX is often inline, meaning that LaTeX expressions like $\alpha$ appears inline with the text. This suggests that we cannot really completely decouple the TeX rendering from the text rendering, because they need to have compatible size and styling.
  • it makes writing TeX awkward and adds friction compared to using something like $x$ inline in text.
    • Note: conceivably a proc macro could process all doc comments and replace e.g. $x$ with TeX expressions: however, this doesn't work for inner doc comments (//!) since proc macros cannot access those.
  • It makes it awkward to define global macros for re-use of TeX expressions.

There are workarounds for all of the above points. For example, in fenris I inject KaTeX into Rustdoc using --html-in-header (similar to known methods) and --html-before-content, which also works docs.rs (apologies for the incomplete content, fenris is a work in progress, but the docs heavily rely upon KaTeX for making sense at all). Aside: A recent version of rustdoc made some CSS changes that mess with the KaTeX rendering, hence there are some unwanted scrollbars. I haven't had the time to debug this yet.

The --html-in-header option basically injects KaTeX into the Rustdoc documentation, like in the linked Stackoverflow post. What's more interesting then is the use of --html-before-content. The HTML file for this looks like this:

$$ \gdef\pd#1#2{\frac{\partial #1}{\partial #2}}
\gdef\d#1{\, \mathrm{d}#1}
\gdef\dx{\d{x}}
\gdef\tr#1{\operatorname{tr} (#1)}
$$

$$
\gdef\norm#1{\left \lVert #1 \right\rVert}
\gdef\seminorm#1{| #1 |}
$$

$$
\gdef\vec#1{\mathbf{\boldsymbol{#1}}}
\gdef\dvec#1{\bar{\vec #1}}
$$

Basically these are TeX macros that I can then use across all of my documentation. Hence I can write e.g. $\vec x$ to properly type set a vector in my preferred way across all of my documentation pages. This is essential as documentation grows, to ensure consistent notation and typesetting.

Finally, to make building docs locally both ergonomic and work correctly with dependencies (the approach in the linked Stackoverflow post doesn't), I use the following build_docs.sh script:

#!/bin/bash

# This script injects a header that lets us write our Rust documentation with TeX formulas rendered by KaTeX.
# This approach only works when providing `cargo doc` with an **absolute path** to the header file, hence
# we obtain the path relative to this script file and build the docs with this header injection.

# From: https://stackoverflow.com/a/246128
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
HEADER_PATH="$SCRIPT_DIR/assets/doc-header.html"
BEFORE_CONTENT_PATH="$SCRIPT_DIR/assets/doc-before-content.html"

# Note: command line arguments are forwarded to the final invocation
RUSTDOCFLAGS="--html-in-header $HEADER_PATH --html-before-content $BEFORE_CONTENT_PATH" cargo doc $@

We can run this script like we otherwise would cargo doc, e.g. ./build_docs.sh -p mypackage --open and it will ensure that all dependencies also get the proper headers injected, making TeX work seamlessly across all dependencies.

Summary

The point of all this is that through a number of workarounds, pretty decent TeX support can currently be attained through the aforementioned KaTeX injection. Procedural macros can not provide an acceptable solution. However, the injection approach is brittle:

  • it currently works on docs.rs, but in the future they may reject running Javascript altogether. I sincerely hope they will consider whitelisting KaTeX in some way, however. I cannot stress enough how important KaTeX is for documenting math-heavy science software!
  • changes to rustdoc CSS might lead to render problems for the KaTeX, such as added scrollbars which happened recently.
  • the approach requires quite a bit of setup and friction for authors who want to use KaTeX in their docs.

Some kind of more official support would go a long way in supporting the documentation efforts for scientific crates. And for this we need to start working on an RFC, as indicated earlier in this issue.

EDIT: A procedural macro could perhaps also take as input something like a TeX file containing macro definitions to inject into all generated TeX, but the other caveats still apply.

@tarcieri
Copy link
Contributor

Cryptography is another problem domain that would benefit from LaTeX in rustdoc.

We presently use Unicode characters instead, but the result is limited, difficult to compose, still oddly formatted, and on the whole leaves quite a bit to be desired.

@clarfonthey
Copy link
Contributor

I definitely would be in favour of there being some mechanism to embed compiled LaTeX typesetting instead of relying on runtime-level parsing. Right now, there is a crate for this that uses an embedded JS runtime to compile KaTeX: https://github.com/xu-cheng/katex-rs

If this isn't something that's provided natively, it would be nice if there were some way to add custom markup to rustdoc via some form of extensions or proc macros, since I find the #[doc = macro!()] solution substantially less easy to use if you have a lot of equations in a single comment. Plus, I like referencing the variables using the same typesetting, and so adding an entirely separate line to do something like #[doc = katex!("x")] would be extreme overkill.

@tgross35
Copy link
Contributor

tgross35 commented May 19, 2022

Found this discussion regarding KaTeX https://internals.rust-lang.org/t/the-rustdoc-redux/5542 but it seems to have stalled, and KaTeX wasn't even the main purpose. I guess the floor there is open for a new discussion?

@MingweiSamuel

This comment was marked as resolved.

@tgross35
Copy link
Contributor

That seems to be the wrong link?

@MingweiSamuel whoops thanks for the catch, edited it

@tgross35
Copy link
Contributor

Talk about timing - just announced today that GH markdown will support TeX (via MathJax) https://github.blog/2022-05-19-math-support-in-markdown/

@tgross35
Copy link
Contributor

Can anyone advise - is this issue blocked by pulldown-cmark adding support? Their issue on the subject is located here, but I am unsure whether or not this is a direct blocker for rustdoc.

@lmorais-dev
Copy link

Any updates on this?

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

No branches or pull requests