MichaelHatherly / CommonMark.jl

A CommonMark-compliant Markdown parser for Julia.
Other
84 stars 11 forks source link

Interpolation extension. #16

Closed MichaelHatherly closed 3 years ago

MichaelHatherly commented 3 years ago

@jlewis91 here's some initial work on interpolation syntax to get you going if you're planning to look into #14 and #15. This is just a first pass without much in the way of testing it out, but I figured I'd drop some breadcrumbs for you since it's definitely a pretty subtle area of the parsing machinery to try to understand, hope it helps. Feel free to branch off of here if you do look into it, or I'll eventually get around to finishing up this branch sometime in the future...

jeremiahpslewis commented 3 years ago

@MichaelHatherly Nice, this looks awesome, I'll try dropping this into a few notebooks, play around with it, and then aim to swing back this coming weekend and flesh out the tests. :)

MichaelHatherly commented 3 years ago

As a very simple testing out of this in relation to Pluto usage with a little bit of @var_str magic to trick Pluto into inspecting @cm_str properly we have variable bindings that update correctly when using PlutoUI components.

2021-03-01_17-03

MichaelHatherly commented 3 years ago

Just going to @fonsp here to keep him in the loop.

jeremiahpslewis commented 3 years ago

Note: latex math mode seems to be broken in the current iteration of the macro:

Note: Math parsing currently turned off in macro

Screen Shot 2021-03-01 at 18 39 17

See below for math parsing patch:

MichaelHatherly commented 3 years ago

MathRule isn't a default extension for Parser so needs to be enable!d in the @cm_str macro. The default Parser just follows the CM spec, anything else that is wanted syntax-wise needs enabling. The @cm_str macro should probably enable everything that @md_str allows.

diff --git a/src/extensions/interpolation.jl b/src/extensions/interpolation.jl
index 5b464cf..cf9bf32 100644
--- a/src/extensions/interpolation.jl
+++ b/src/extensions/interpolation.jl
@@ -43,6 +43,7 @@ macro cm_str(str)
     ji = JuliaInterpolation([])
     parser = Parser()
     enable!(parser, ji)
+    enable!(parser, MathRule())
     ast = parser(str)
     quote
         # Evaluate the parsed expressions that we just captured into the
fonsp commented 3 years ago

Ah math isn't working because Pluto does one special thing for Markdown: https://github.com/fonsp/Pluto.jl/blob/7b1041b7c76bcd7f6ba0db528501f62535f3ac6b/src/runner/PlutoRunner.jl#L439-L455

The md_str hack is well found (but you might run into problems with the tricky interpolation rules), eventually we want to solve the more general problem, https://github.com/fonsp/Pluto.jl/issues/196

MichaelHatherly commented 3 years ago

I don't think those methods will be getting invoked, the node types for LaTeX aren't the same in CM. It seems to work fine rendering though:

2021-03-02_18-24

The exact HTML being generated here is:

<p>Inline: <span class="math">\(x + 1\)</span>.</p>
<p>Display:</p>
<div class="display-math">\[f(x)\]</div>

The md_str hack is well found (but you might run into problems with the tricky interpolation rules), eventually we want to solve the more general problem, fonsp/Pluto.jl#196

I'm pretty sure I've hit that already since:

2021-03-02_18-25

Above the interpolated a in the first markdown block doesn't update, but the second does, the only difference being that one is in a blockquote and the other happens to be in an unnested paragraph as well as the blockquote. I think the go back to the odd behaviour of MD.jl's interpolation is those cases: ie not resolving to the value of an interpolated expression if it happens to be nested in blockquote/admonition/footnote def.

MichaelHatherly commented 3 years ago

This is what the macro expands to btw:

quote
    #= /home/mike/.julia/dev/CommonMark/src/extensions/interpolation.jl:53 =#
    (Base.RefValue{Any}(#undef))[] = a
    #= /home/mike/.julia/dev/CommonMark/src/extensions/interpolation.jl:54 =#
    Node(CommonMark.Document)
end

and

quote
    #= /home/mike/.julia/dev/CommonMark/src/extensions/interpolation.jl:53 =#
    (Base.RefValue{Any}(#undef))[] = a
    (Base.RefValue{Any}(#undef))[] = a
    #= /home/mike/.julia/dev/CommonMark/src/extensions/interpolation.jl:54 =#
    Node(CommonMark.Document)
end

I would have assumed that Pluto would be able to work out what's going on there and perform the updates correctly.

MichaelHatherly commented 3 years ago

0.8.0 will include this and should be tagged shortly: https://github.com/JuliaRegistries/General/pull/31668.