-
Notifications
You must be signed in to change notification settings - Fork 1k
feat(markdown): add support for math rendering with typst and katex #2791
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
base: next
Are you sure you want to change the base?
Conversation
bad4e13
to
5d8d725
Compare
I don't really know how to get rid of these |
This PR adds math rendering on the "server-side" with typst, while keeping the katex option open for latex. A The output SVGs generated by typst can also be minified via the svgo CLI. This is kind of a hacky implementation because it relies on the CLI but it does the job. Newly added configuration parameters: math = "typst" # Defaults to "none", one of "typst", "katex"
math_svgo = true # Optimize the SVGs generated by the math renderer
math_svgo_config = "svgo.config.mjs" # Optional, Path to the svgo config
math_css = "styles/typst-embed.css" # path to the CSS file to inject inside the SVGs generated CI is failing because The size of the binary also drastically increases because of typst's ecosystem ( |
This is great work! One possible place to improve: the current implementation outputs SVG for equations. It might be better to use MathML to make sites smaller and more accessible. |
Thanks a lot :D Typst doesn't yet support HTML or MathML output (see typst/typst#5512) The basic katex implementation however already outputs HTML I think. I don't use LaTeX that much so if anyone is up to help with this, I'd be glad. |
I think it might be possible to write a backend visitor to output MathML (cf https://github.com/wcshds/typst-math-to-mathml-converter). This would be a lot easier than what the Typst team is building, since we don't have to handle everything else, but the downside is that we're then implementing a possibly buggy different spec from what Typst does. As a stopgap for accessibility, we might also just include the math source as alt text for the generated SVGs. |
This indeed sounds a bit risky, including the original source in the alt should be enough for now. I will tinker a bit with the library you linked to try out mathml rendering, I also stumbled accross this one: |
2cad380
to
d276f92
Compare
d276f92
to
4d37093
Compare
I have tried out a bit the library you linked, here's the result I get: I am using For reference, here's the result with SVG rendering: |
4d37093
to
df62c23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks great! i've left a few comments but i've been toying locally for a few days and i'm very happy.
+1 for svg+mathml too. it's always what i gravitate to and it always works well. one day soon mathml will be widespread and complete enough that it will become a viable primary target, but for now, svg rendering is the only consistent option.
on that note, did you ever consider mathjax? the latex support is a little better than katex these days.
V: Serialize + for<'de> Deserialize<'de>, | ||
{ | ||
cache_file: PathBuf, | ||
cache: DashMap<K, V>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not totally sure whether it matters at the kind of scale/concurrency zola operates on, but you might find papaya a better fit for a concurrent hash map. this (biased) blogpost by the author totally convinced me.
components/markdown/src/markdown.rs
Outdated
@@ -564,7 +597,7 @@ pub fn markdown_to_html( | |||
cmark::CodeBlockKind::Fenced(fence_info) => FenceSettings::new(fence_info), | |||
_ => FenceSettings::new(""), | |||
}; | |||
let (block, begin) = match CodeBlock::new(fence, context.config, path) { | |||
let (block, begin) = match CodeBlock::new(&fence, context.config, path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performance wise, though it's somewhat (but not totally) moot, you might want to clone fence.language
beforehand so you don't have to pay the larger cost of cloning inside CodeBlock::new
.
components/markdown/src/markdown.rs
Outdated
accumulated_block.clear(); | ||
let inner = &accumulated_block; | ||
match code_block_language.as_deref() { | ||
Some("typ") => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason katex isn't supported here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't use latex/katex that much, but I think there's no concept of "raw" rendering in katex. From what I understood, it's only made for math rendering, whereas typst can render whole documents. the "raw" mode was initially intended for rendering graphs/tables. Let me know if katex supports such things!
Update:
[markdown.math]
engine = "typst" # typst, katex, or none
svgo = true # true, false, or "path"
css = "styles/typst-embed.css" # optional
addon = "helpers.typ" # optional We can also simplfy specify: [markdown]
math = "typst" Which is equivalent to [markdown]
math = {
engine = "typst"
}
[markdown]
cache = true # true, false or "path" By default the caches are now stored in
## Wonderful test
This is markdown content.
```typ
= Hello, World!
This is a raw typst document: $y^2 = x^3 + a x + b$
```
PS: Thank you so much for your feedback soqdb 😄 |
I wouldn't bother with the |
@soqb after benchmarking papaya and dashmap, it looks like the difference for our scale is very very small... |
I tried this PR, and used |
css attribute was for css injected inside the svg (typst). For KaTeX, there is nothing injected. Maybe I should update the documentation for this. |
IMPORTANT: Please do not create a Pull Request adding a new feature without discussing it first.
The place to discuss new features is the forum: https://zola.discourse.group/
If you want to add a new feature, please open a thread there first in the feature requests section.
Sanity check:
Code changes
(Delete or ignore this section for documentation changes)
next
branch?If the change is a new feature or adding to/changing an existing one: