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

Quarto Rendering #222

Open
arnold-c opened this issue Jun 13, 2022 · 8 comments
Open

Quarto Rendering #222

arnold-c opened this issue Jun 13, 2022 · 8 comments

Comments

@arnold-c
Copy link

I was wondering if it is possible to render Latex equations in Quarto (.qmd) files? MWE below.

Using ParameterizedFunctions, Latexify

sir_ode = @ode_def SIRModel begin
    dS = -β*S*I
    dI = β*S*I-γ*I
    dR = γ*I
    end β γ

latexify(sir_ode)

Output in the notebook (i.e. doesn't render the equation):

L"\begin{align}
\frac{dS(t)}{dt} =&  - \beta I\left( t \right) S\left( t \right) \\
\frac{dI(t)}{dt} =&  - \gamma I\left( t \right) + \beta I\left( t \right) S\left( t \right) \\
\frac{dR(t)}{dt} =& \gamma I\left( t \right)
\end{align}
"

Changing to latexify() |> render produces:

latexify(sir_ode) |> render

An error occurred while executing the following cell:
------------------
latexify(sir_ode) |> Latexify.render
------------------

MethodError: no method matching show(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("juliavscode/html")}, ::String)
Closest candidates are:
  show(::IO, ::MIME{Symbol("text/csv")}, ::Any) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/DelimitedFiles/src/DelimitedFiles.jl:829
  show(::IO, ::MIME{Symbol("text/plain")}, ::AbstractString; limit) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/strings/io.jl:196
  show(::IO, ::MIME{Symbol("text/plain")}, ::Any) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/multimedia.jl:47
  ...

Stacktrace:
  [1] limitstringmime(mime::MIME{Symbol("juliavscode/html")}, x::String)
    @ IJulia ~/.julia/packages/IJulia/AQu2H/src/inline.jl:50
  [2] display(d::IJulia.InlineDisplay, M::MIME{Symbol("juliavscode/html")}, x::String)
    @ IJulia ~/.julia/packages/IJulia/AQu2H/src/inline.jl:81
  [3] display(m::MIME{Symbol("juliavscode/html")}, x::Any)
    @ Base.Multimedia ./multimedia.jl:342
  [4] #render#105
    @ ~/.julia/packages/Latexify/wO7r4/src/utils.jl:111 [inlined]
  [5] render(s::LaTeXStrings.LaTeXString, mime::MIME{Symbol("juliavscode/html")})
    @ Latexify ~/.julia/packages/Latexify/wO7r4/src/utils.jl:111
  [6] render(s::LaTeXStrings.LaTeXString; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Latexify ~/.julia/packages/Latexify/wO7r4/src/utils.jl:69
  [7] render
    @ ~/.julia/packages/Latexify/wO7r4/src/utils.jl:69 [inlined]
  [8] |>(x::LaTeXStrings.LaTeXString, f::typeof(Latexify.render))
    @ Base ./operators.jl:966
  [9] top-level scope
    @ In[5]:1
 [10] eval
    @ ./boot.jl:373 [inlined]
 [11] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:1196
LoadError: MethodError: no method matching show(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("juliavscode/html")}, ::String)
Closest candidates are:
  show(::IO, ::MIME{Symbol("text/csv")}, ::Any) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/DelimitedFiles/src/DelimitedFiles.jl:829
  show(::IO, ::MIME{Symbol("text/plain")}, ::AbstractString; limit) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/strings/io.jl:196
  show(::IO, ::MIME{Symbol("text/plain")}, ::Any) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/multimedia.jl:47
  ...

Apologies if this is more of a Quarto question, but figured it might also be due to my inexperience with Latexify and I might just be missing something obvious.

@gustaphe
Copy link
Collaborator

I don't know anything about Quarto, first time hearing of it, but I could maybe shed some light on what is needed here.

When you latexify, you create a LaTeXStrings.LaTeXString. It's this object that needs some good show method for Quarto. But LaTeXString is essentially just a container for a string, so any decision on how to show it lies on the Quarto side.

One thing I like to do in Pluto is Markdown.parse("Length: $(@latexrun l=35/4)"). This might also work out of the box in Quarto.

@arnold-c
Copy link
Author

Thanks @gustaphe. Quarto is effectively a language-agnostic upgraded version of Rmarkdown (https://quarto.org/docs/computations/julia.html).

Unfortunately Markdown.parse() seems to strip backspaces, which means that multi-line equations don't render correctly. Using the SIR example above:

latexify(sir_ode) |> Latexify.display
L"\begin{align}
\frac{dS(t)}{dt} =&  - \beta I\left( t \right) S\left( t \right) \\
\frac{dI(t)}{dt} =&  - \gamma I\left( t \right) + \beta I\left( t \right) S\left( t \right) \\
\frac{dR(t)}{dt} =& \gamma I\left( t \right)
\end{align}
"
latexify(sir_ode) |> Markdown.parse        # or Markdown.parse("$(@latexrun $(sir_ode))")
  \begin{align} \frac{dS(t)}{dt} =& - \beta I\left( t \right) S\left( t \right) \ \frac{dI(t)}{dt} =& - \gamma I\left( t \right) + \beta I\left( t \right) S\left( t
  \right) \ \frac{dR(t)}{dt} =& \gamma I\left( t \right) \end{align}

Screen Shot 2022-06-14 at 21 26 31

Any thoughts, or is this now best to open up on Quarto?

@gustaphe
Copy link
Collaborator

gustaphe commented Jun 15, 2022

Latexify just generates the tex source, which in this case is correct. Whether it's rendered right is indeed a question for Quarto.

However, I'm a bit uncertain if the align environment is a good fit for any Markdown specification. Perhaps we should have a :sequential environment to generate

L"
$$
\frac{dS(t)}{dt} = - \beta I\left( t \right) S\left( t \right) \\
$$
$$
\frac{dI(t)}{dt} = - \gamma I\left( t \right) + \beta I\left( t \right) S\left( t \right) \\
$$
$$
\frac{dR(t)}{dt} = \gamma I\left( t \right)
$$
"

Does @korsbo have an opinion?

@korsbo
Copy link
Owner

korsbo commented Jun 15, 2022

Yeah, markdown can sometimes be a pain. There is however an double_linebreak=true option that'll double up on the \\ so that when markdown parses it it all comes out right.

Markdown.parse(latexify([1,2],[2,3], double_linebreak=true))

@arnold-c
Copy link
Author

Thank you @korsbo for the suggestion, though I'm afraid it didn't seem to change the output.

julia> Markdown.parse(latexify(sir_ode, double_linebreak=true))
  \begin{align} \frac{dS(t)}{dt} =& - \beta I\left( t \right) S\left( t \right) \ \frac{dI(t)}{dt} =& - \gamma I\left( t \right) + \beta I\left( t \right) S\left( t
  \right) \ \frac{dR(t)}{dt} =& \gamma I\left( t \right) \end{align}

@korsbo
Copy link
Owner

korsbo commented Jun 16, 2022

hmm. I'm guessing that there are two bugs. One would be in the latexify recipes of Symbolics.jl. I suspect that the supplied kwarg is not passed on properly. The other is in the Markdown standard library. I really can't see why it would make sense to parse "\\\\" down to "\".

the immediate hack-fix might be to just double down on all "\\" before parsing.

Markdown.parse(replace(latexify(sir_ode), "\\"^2=>"\\"^4)

I have not checked that it renders but the output looks like valid Markdown to me.

Fixing the presumed bugs in Symbolics and Markdown requires some digging - something I can't promise I'll get to anytime soon.

@arnold-c
Copy link
Author

Thanks for that - it seems to render as expected. And not a problem RE Symbolics/Markdown. Thanks for looking into it!

@cderv
Copy link

cderv commented Jul 20, 2023

👋 Quarto team here.

I am curious of what the .ipynb example is here. Can you share one @arnold-c ?

Quarto does execute the .ipynb file and then will use the cell output in a .md output used to convert to LaTeX with Pandoc.

I would like to know what you tried and see what would make it works. If Latexify outputs valid LaTeX code for a LaTeX rendering then it should work correctly with Quarto. But maybe there is some non expected interaction or we don't get the output right from Jupyter cell rendering.

Happy to help here.

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

4 participants