Leverage mitex plugin to render latex equations
Currently Rough Implementation
This pull request extends the show_raw method for LaTexStrings. It would be great if we could leverage mitex to render latex equations into typst. It is a rough implementation, but I wanted to spark a discussion.
Try it out and see what you think
Import Typstry (using this branch) and Handcalcs
julia> using Handcalcs
julia> using Typstry
This command adds mitex package to the preamble
julia> context[:preamble] = TypstString(TypstText(context[:preamble] * TypstString(TypstText("#import \"@preview/mitex:0.2.4\": *\n"))))
TypstString(TypstText("#set page(margin: 1em, height: auto, width: auto, fill: white)\n#set text(16pt, font: \"JuliaMono\")\n#import \"@preview/mitex:0.2.4\": *\n"))
Then try the following:
julia> TypstString(
@handcalcs begin
x = 5
y = 20
z = x^2 + y
end
) |> render;
You should get an output like the following:
I currently opened an issue for the [10pt] being rendered. You can see the issue here: https://github.com/mitex-rs/mitex/issues/191
Otherwise mitex works pretty well. It can even render color:
julia> TypstString(
@handcalcs begin
x = 5
y = 20
z = x^2 + y
end color = :blue
) |> render;
Adding @nathanrboyer to this. I know he wanted typst integration with handcalcs. This may be a potential quick fix once it is cleaned up. The true typst backend to handcalcs could still come later on, but I know that is a much bigger undertaking.
That's really cool! I hadn't known about mitex either. It might be useful to use a context parameter to import mitex automatically such as:
mitex(tc) && print(io, "#import \"@preview/mitex:0.2.4\": mi\n\"")`
The project's current roadmap is:
- Stop conflating a value's format with the
mode - Submit JuliaCon proposals
- Implement
show_typst(::IO, ::TypstContext, ::Expr)
I love the feature you've implemented here and will absolutely merge it, but need to resolve item 1 before implementing new formats. For example, it would be nice to be able to render both a raw text block ``latex ... `` and rendered latex using mitex. However, a consistent but flexible API for choosing between these formats is eluding me. This work is in-progress, challenging to design, and the primary task I'm stuck on. Please let me know if you have thoughts about it.
I'm hoping to complete item 3 prior to JuliaCon, which would clear the way for a Typst backend in Handcalcs.jl :)
Cool! Yeah I like that context parameter idea.
I agree that being able to render raw text block and choosing mitex option would be good.
I find API is always the hardest part for me. I personally like the way Latexify.jl allows for the changing of settings. You can see it here: https://korsbo.github.io/Latexify.jl/stable/#Setting-your-own-defaults. I ended up doing the same for handcalcs. I looked into preferences.jl but it seemed a little more confusing.
I usually find my favorite API by just imagining what I wish it was without any syntax constraints. In this case for me it would be matching Typst 1 to 1 as best as I can. This may not be what you are looking for, but something like this would be cool for building typst documents:
@typst_report begin
"""
#import \"@preview/mitex:0.2.4\": *
= Header 1
This is normal typst markdown
#align(right)[#text(fill:green)[OK]]
See the equation below:
"""
# can comment as normal
@mi(@handcalcs begin
x = 5
y = 20
z = x^2 + y^2
end
)
# mitex is a centered math environment.
@mitex(@handcalcs begin
x = 5
y = 20
z = x^2 + y^2
end
)
# this would simply pass the raw text block (unless settings were changed maybe)
@handcalcs begin
x = 5
y = 20
z = x^2 + y^2
end
# some no render function that does not print
@no_render(
a = 5
)
"""
Can I interpolate *a* here: $$(a). What syntax should it be?
"""
end
This would essentially be the render function that prints each piece. It basically just opens an io and then adds the_expr |> TypstString |> show_typst to each expression.
I personally like the way Latexify.jl allows for the changing of settings. You can see it here: https://korsbo.github.io/Latexify.jl/stable/#Setting-your-own-defaults.
I agree this is good design. The next release will use a TypstContext which can be mutated by the user to specify the default behavior.
The two main contenders in terms of how to select between formats is
- A. Each type has a unique format
- Pros: Simple to think about and document.
- Cons:
- It is ambiguous when to switch between modes. For example, it's pretty clear that a vector should be switched to math mode. However, should
TypstString(1; mode = markup)be formatted as1,#1, or$1$? - In some cases, it is difficult to choose what the default format should be. Ideally, this should be consistent for similar or related types. However, some types have a more specific or semantically rich representation that differs from the rest. For example, a
Vectorshould probably be a mathematical vector but aRangeis both aVectorand corresponds to Typst's code mode range. - Requires implementing more types and having the user perform more type conversions.
- It is ambiguous when to switch between modes. For example, it's pretty clear that a vector should be switched to math mode. However, should
- B. Each type can have multiple formats, specified by a
formatparameter- Pros: Works with preexisting types, is very flexible
- Cons:
- More complicated to implement and document, since formats overlap
- Implementation needs to branch and error for unsupported formats
- Still requires a default format
- Is still ambiguous about switching modes
- More complicated to implement and document, since formats overlap
I've tried out both, which unfortunately took a lot of time. I was initially averse to option A because I wanted to avoid creating a bunch of new types. However, B feels pretty messy and doesn't really solve any of the problems with A. Option A also seems to align with your proposal, where a LaTeXString is a raw text block and whatever is returned by mitex is rendered latex. Do you think option A is a good plan? It's currently implemented locally, but has some remaining work.
In the upcoming support for Expr, I intend to implement @typst to support behavior similar to what your example shows. Each element in the block would printed in Typst format and concatenated. This enables a really cool feature where you can choose whether to transpile Julia function calls to Typst function calls or just render it syntactically. The idea to have something like @no_render is new and good!
This would essentially be the render function that prints each piece. It basically just opens an io and then adds the_expr |> TypstString |> show_typst to each expression.
Missed this the first time, yes exactly!
I think I like the option A idea. I will try to look into it more these next few days/weeks depending on time. This is awesome work so far! This is the main thing I want to figure out right now. That being how everything will work together: quarto, typst, Pluto, Handcalcs, Jupyter, Drwatson, etc.
At work it’s a pain to get things unblocked due to security measures so it has been hard trying to use quarto somewhat which relies on so many executables. I don’t know how I would ensure all users are able to get everything installed and working. Being able to rely on just Julia and Typst for reports would be so nice.
An interactive Pluto file to typst output would pretty amazing from a user standpoint, but we just have to take it one piece at a time.
An interactive Pluto file to typst output
Do you mean rendering a cell or the entire file? Rendering a cell already works in Pluto and Jupyter. It doesn't currently work in Quarto, and I haven't investigated why yet.
Oh my documentation says it works in Quarto, maybe I fixed it. Guess I'll have to check haha
At work it’s a pain to get things unblocked due to security measures so it has been hard trying to use quarto somewhat which relies on so many executables. I don’t know how I would ensure all users are able to get everything installed and working. Being able to rely on just Julia and Typst for reports would be so nice.
That's good work you're putting in, keep it up!
Oh my documentation says it works in Quarto, maybe I fixed it. Guess I'll have to check haha
I haven’t tried your package with it. That is just with Handcalcs/jupyter. It’s just the work hurdles with quarto and relying on the Latex pdf render (currently) that is too difficult currently.
An interactive Pluto file to typst output
Do you mean rendering a cell or the entire file? Rendering a cell already works in Pluto and Jupyter. It doesn't currently work in Quarto, and I haven't investigated why yet.
I can currently create an interactive Pluto file using handcalcs, but our calculations must be printed to pdf. There is currently no Pluto -> quarto(pdf) or Pluto -> typst(pdf) that exists
By the way, I rewrote history in order to release a small v0.5.0. The bigger changes have been moved to the v0.6.0 branch.