Rustdoc LaTeX math - #3958
Conversation
917ba2d to
8ccd7c7
Compare
51ec581 to
2ccb14b
Compare
Co-authored-by: Jacob Lifshay <programmerjake@gmail.com>
Co-authored-by: Urgau <3616612+Urgau@users.noreply.github.com>
|
Will be honest, I've been kind of apprehensive about a proposal to add LaTeX syntax to rustdoc since while I do want it, a lot of the existing options, like KaTeX, seemed suboptimal. This pretty much fixes all of those concerns and makes me genuinely excited for this, since it renders at build time as MathML instead of being a CSS mess rendered on page load. So, while there are a few minor things to work out, I'd like to really thank you for working on this and am looking forward to when it can finally be made official. |
| /// | ||
| /// \begin{equation} | ||
| /// \sum_{i=start}^{end}{f(i)} | ||
| /// \end{equation} |
There was a problem hiding this comment.
I don't think we should support it. We are primarily writing Markdown, not LaTeX after all. Bare \begin{foo}/\end{foo} can just be placed inside $$ ... $$.
Computes sum from `start` to `end` of the given function. $$ \begin{equation} \sum_{i=\mathtt{start}}^{\mathtt{end}}{f(i)} \end{equation} $$Computes sum from
starttoendof the given function.
$$ \begin{equation} \sum_{i=\mathtt{start}}^{\mathtt{end}}{f(i)} \end{equation} $$
There was a problem hiding this comment.
This isn't super abnormal considering how CommonMark handles block-level HTML, actually. I think it's a neat shortcut to make doc comments slightly shorter, since they are part of the code, after all.
That said, it is not explicitly required here.
| #![doc(math_syntax( | ||
| // usage: $\floor{x}$ | ||
| floor=r##"\delim{\lfloor}{#1}{\rfloor}"##, |
There was a problem hiding this comment.
Could include! be made to work within this macro? It could be nice to keep shared definitions in a separate file. (Fine as a future possibility).
There was a problem hiding this comment.
so like #![doc(math_syntax(include!("my_syntax.txt")))]? or did you mean #![doc(math_syntax(foo = include!("foo.txt"), bar = include!("bar.txt")))]
There was a problem hiding this comment.
The first one is what I was thinking of, so you could have one file defining custom commands and reuse it for multiple crates in a workspace. (With some symlinking if they're published).
There was a problem hiding this comment.
this should be possible by making math_syntax eagerly expanded, like doc = already is.
| ### Avoiding Hyrum's Law | ||
|
|
||
| There are a lot of \commands in [math-core][], and some of them are known buggy, | ||
| meaning they don't match LaTeX itself. | ||
| We don't want authors to rely on those bugs, either accidentally | ||
| or in a workaround. | ||
|
|
||
| Normally, we might "phase in" new commands by making them unstable first, | ||
| letting more risk-tolerant authors try it out, | ||
| then make it available to everyone else. | ||
| But math-core doesn't have an API for that. |
There was a problem hiding this comment.
This makes it sound a bit like some slash commands will be feature gated?
I'm not sure if that's a hoop worth jumping through; I expect that many people writing equations can deal with some level of instability in output for lesser-used features. All math rendering libraries change the way things look as they add features or fix inconsistencies, and browser support for MathML still has places to improve.
Instead, it seems sufficient to say that:
- We try to make sure the rendered output is reasonably close to what LaTeX does
- Output that deviates from what LaTeX does may change
- Output that closely matches LaTeX is unlikely to change
Then if anything, we could keep a list of slash commands that are known to not render completely correctly.
There was a problem hiding this comment.
I haven't decided whether slash commands should be feature gated or not. That's why it's under the "unanswered questions" section.
| A detailed comparison between our syntax and KaTeX's can be found | ||
| [here](https://tmke8.github.io/math-core/comparison.html). | ||
|
|
||
| You can add custom \commands by supplying key=value pairs to the math syntax attribute: |
There was a problem hiding this comment.
I would like to propose that we defer the custom commands syntax here, and just support what ships with stock math-core. This means we don't have to deal with scoping issues, and it means we could add more functions ourselves in the future (e.g. upgrade to a version of math-core that implements a larger subset of LaTeX) without worrying about conflict with user-defined functions.
There was a problem hiding this comment.
I chose this arm of the trade-off triangle (punt on inheritance, have per-item doc(math_syntax), or support custom commands; pick two) because the katex.js hack supports custom commands and when I ran a Crater run with math-core, I found crates1 that use that feature.
Since my primary goal here was to get existing crates to switch off the katex,js hack onto this new feature, I prioritized feature parity.
Footnotes
There was a problem hiding this comment.
@notriddle That is helpful to know. But looking over the list, it seems like most of them are one-offs. I wonder to what extent most crates would be willing to switch even without that feature?
I do think people will want the ability to use this in macros. Which means we're either going to have to punt on custom commands, or carefully define inheritance. The latter is possible but seems like substantial additional complexity (making it much more a "language" than a predefined set of supported markup).
There was a problem hiding this comment.
General vibe: I like the approach this takes. I think it takes our stability guarantees into account, and I think we could manage to support it long-term.
I think the worst-case failure mode of this is that we decide we have to go back to showing the raw LaTeX syntax rather than rendering it, or that people go back to using external tools like KaTeX; that's not a terrible failure mode.
I also think that if, in the future, we wanted to support some other syntax, this wouldn't stop us from doing so. We have the edition mechanism, and we could also support opt-ins for those different possibilities. I added a mention in the alternatives section for typst, for instance, along with detailed reasons why we shouldn't support typst in the near future.
I left a couple of inline comments that arise from the same underlying thought: I think we should defer custom command support, for a few different reasons. (Feel free to respond to that on the thread of those inline comments, rather than here.)
Other than that, this looks good to me, and I'd be happy to see it implemented and shipped. ❤️
Co-authored-by: Josh Triplett <josh@joshtriplett.org>
|
|
||
| ### Verbosity or breakage as side effect | ||
|
|
||
| From the perspective of 99% of doc authors who didn't want to write a math span in the first place, |
There was a problem hiding this comment.
From the perspective of 99% of doc authors
Is this an actual statistic or a conjecture?
There was a problem hiding this comment.
It's conjecture. There aren't very many crates that use the katex hack, but that could be caused by the a11y problems and poor devex. What we care about is the number of crates that would use this feature if it were built in, and we can't know that.
I suspect that few crates would use this feature even if it were built in, because most crater runs I've run turn up a bunch of crates where the author wrote plain text without accounting for Markdown's quirks. When I ran a crater run to find problems caused by adding LaTeX math support, I found a lot of crates that had $ signs in code that wasn't escaped. When I did the crater run to update pulldown-cmark, I found a bunch of "Questionable" code that was broken with both versions, because they had unescaped ASCII art.
As a gut check, I just ran cargo lintcheck on the top 200 crates with a custom lint to measure feature usage. This isn't measuring the same thing as crater, but it's still interesting:
| number of crates | feature |
|---|---|
| 10 (5%) | footnotes |
| 21 (10%) | tables |
| 46 (23%) | HTML |
| 143 (71%) | lists (bullet or numbered) |
| 176 (88%) | links |
There was a problem hiding this comment.
Thanks for clarifying.
What we care about is the number of crates that would use this feature if it were built in, and we can't know that.
FWIW, at my workplace, we haven't bothered making math syntax render nicely specifically because of the feature not existing in vanilla rustdoc. We'd fix that as soon as the feature became available, and any backwards incompatibilities due to the dollar signs would just be shrugged off as well worth it.
Reverting the rustdoc-LaTeX wiring added in 167367d. The machinery (custom katex.html header, Cargo.toml rustdoc-args, $...$ in docstrings) ended up costing more than it bought: - No per-package scoping for `--html-in-header` means local `cargo doc` can't render math without breaking on dep crates, and the workarounds (cargo aliases, --no-deps) push the burden onto users who shouldn't have to know. - Adopting mathru's "docs.rs only" pattern leaves local users staring at raw $...$, which isn't a good answer either. - rustdoc itself is moving toward first-class math support (rust-lang/rfcs#3958); waiting for that beats maintaining a brittle CDN-dependent shim. Removed: docs/katex.html, the rustdoc-args metadata in Cargo.toml, and the $...$ delimiters in src/lib.rs (reverted to ASCII / Unicode-subscript math, matching the rest of the docstrings). Markdown LaTeX in README.md and INTERNALS.md stays — GitHub renders that natively with no per-crate plumbing required. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
|
|
||
| To enable `$\TeX$` math syntax in rustdoc, add this line to your crate root. | ||
|
|
||
| #![doc(syntax="+tex_math_dollars")] |
There was a problem hiding this comment.
As far as I know, this syntax is unique. Why not going for the "usual" enable()/disable()?
There was a problem hiding this comment.
It's not that unique, even in the Rust world, it's used by -C target-feature=+avx2,-sse4.1, but it sure is new and unique for an attribute.
#[doc(syntax(enable(tex_math_dollars)))] and #[doc(syntax(disable(tex_math_dollars)))] seems fine to me.
There was a problem hiding this comment.
That sure is a lot of parenthesis, but sure.
There was a problem hiding this comment.
Yeah, it's a lot of parentheses, but I agree it's better to use a more standard syntax rather than have to deal with parsing pluses and minuses.
|
@rfcbot concern attribute syntax |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
@rfcbot resolve attribute syntax |
|
It's been a few weeks, gentle ping @Manishearth @camelid @lolbinarycat for checkboxes/concerns |
|
Whoops, thought I had already signed off |
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
|
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. |
|
Thanks everyone! This has passed FCP. (Merging...) Tracking issue in now rust-lang/rust#162365. Subscribe to track the progress. |
View all comments
Add support for$\LaTeX$ math formula syntax to Rustdoc.
Important
Since RFCs involve many conversations at once that can be difficult to follow, please use review comment threads on the text changes instead of direct comments on the RFC.
If you don't have a particular section of the RFC to comment on, you can click on the "Comment on this file" button on the top-right corner of the diff, to the right of the "Viewed" checkbox. This will create a separate thread even if others have commented on the file too.
Rendered