tlienart / Franklin.jl

(yet another) static site generator. Simple, customisable, fast, maths with KaTeX, code evaluation, optional pre-rendering, in Julia.
https://franklinjl.org
MIT License
954 stars 112 forks source link

How can `@OUTPUT` be hidden from the final code block? #853

Open jkrumbiegel opened 3 years ago

jkrumbiegel commented 3 years ago

I use joinpath(@OUTPUT, filename) to save files in the correct relative location for each code block. But I don't want readers to see this, the example should just use filename because the @OUTPUT macro is specific to Franklin, and I can already see the confused issues where this macro comes from.

I don't currently see a hook where I could edit the displayed text after execution. Is there another way? I can only think of a) a really hacky solution trying to fake something with # hide lines, or b) doing some postprocessing in the global finish hook.

tlienart commented 3 years ago

ah you want to modify the code that gets shown... hmmm. In my opinion it's simpler to just # hide the save file line since for the users it would just show in the REPL or whatever.

I'd recommend not doing this but what you can do is to #hideall the code block, recuperate the file that gets written in the __site/assets/.../code/*.jl modify it and write the html corresponding to a code block around that modified output. So something like

function lx_my_code(...)
    code = read(path, String)
    # do the modification
    return """~~~
        <pre><code class="...">
           $code
        </code></pre>~~~"""
end
jkrumbiegel commented 3 years ago

I can't hide the line in this case, as record for video files has to be called with a closure, and can't just be handled implicitly. Reading the code from the file again sounds a bit weird but maybe that's the way to go.

tlienart commented 3 years ago

well I'm suggesting hacks because you're exploring paths that no user before you asked about 😄 once there's a clear idea of what could be done etc, these things can be baked in as features.

One thing that would solve both this question and your other one would be to add code blocks to the page variables along with their result, and then you can recuperate that in functions that you code and do whatever you please with them.

jkrumbiegel commented 3 years ago

It seems I should learn how to use these page variables effectively. I had only seen static ones so far, like @def somevar, but you're saying they're useful for tracking any kind of state about page builds, even across sites, right?

tlienart commented 3 years ago

right, so the stuff that's fully exposed to the user is

The internals that you can reliably use on top of that is set_var!(context, varname, value) the context is either

there's also Franklin.ALL_PAGE_VARS which keeps the mapping { path => dictofpagevars } i.e. all the local vars dictionaries.

In a code block inside a page page.md you could for instance have something like

this is markdown
```!
# hideall
myvar = 5.3
Franklin.set_var!(Franklin.LOCAL_VARS, "myvar", myvar)

This is useful in the sense that it allows you to export objects generated from `page.md` and load them in another context. So for instance if you have another page `otherpage.md` you can do 

````markdown
```!
println(pagevar("page.md", "myvar"))

In your case using this should allow you to export a list of objects that you can process somewhere else, toy example below

## Toy example

### on page.md

foo

@def all_plots = Any[]

using PyPlot
f = figure(figsize=(8, 6))
p = plot(rand(5), rand(5))
savefig(joinpath(@OUTPUT, "f1.png"))
push!(locvar(:all_plots), p);

\fig{f1.png}

using PyPlot
f = figure(figsize=(10, 12))
p = plot(rand(5), rand(5), lw=2.5, marker="x")
savefig(joinpath(@OUTPUT, "f2.png"))
push!(locvar(:all_plots), p);

\fig{f2.png}


### on otherpage.md

bar

all_plots = pagevar("page.md", :all_plots)
for p in all_plots
    println(p[1].get_marker())
end


### Result (page.md)

<img width="736" alt="Screenshot 2021-07-23 at 10 26 56" src="https://user-images.githubusercontent.com/10897531/126756232-1100e081-b7e8-4111-9a61-1d7c476be209.png">

### Result (otherpage.md)

<img width="472" alt="Screenshot 2021-07-23 at 10 27 31" src="https://user-images.githubusercontent.com/10897531/126756292-107bd32e-40ab-4594-a6f7-4918d9ff8594.png">

---

Of course this is a pretty dumb and contrived example but I'm hoping it'll show you how you could use these variables in your project
tlienart commented 3 years ago

seems like you've managed to make this work, would you mind linking to the implementation here and closing the issue? thanks!