Franklin.jl
Franklin.jl copied to clipboard
[Feature Request] Executed REPL block
Request
Transferred discussion from slack thread: it would be great to have a feature for code output analogous to to Documenter's @repl
blocks, where something like
```@repl
foo = 1
foo + 2
```
is rendered like
```julia-repl
julia> foo = 1
1
julia> foo + 2
3
```
Proposal
As suggested by @tlienart on slack
well we already have
```! 1+1 ```
to mean "run it, show the code + show the output here" i.e.: julia code block with <1+1> and output code block with <2> We could identically have
```> 1+1 ```
to mean "run it + show the code+output in REPL style" i.e.: julia-repl code block with
julia> 1+1 2
which I think would be great, presuming we can do multi-line blocks, and connect blocks, eg
```>:foo
bar = 1
println(bar)
```
some explanation text
```>:foo
bar + 2
```
renders as
```julia-repl
julia> bar = 1
1
julia> println(bar + 1)
2
```
some explanation text
```julia-repl
julia> bar + 2
3
```
Syntax
also please chip in syntax wise, so if it should be
```> or ```? or ```$ or ...
I would expect ```?```
to be a help REPL, and ```$```
to be shell, so I wouldn't use those. Since !
already has precedent, I think >
would make a lot of sense, though ```julia>
would be the most explicit, I think. I also like slightly more explicit, since it will be eventially be easier to edit grammars to enable syntax highlighting for these blocks in markdown files.
I should also say that I'm up for trying out a PR if you're willing to / interested in doing a lot of hand-holding (on figuring out the back end stuff)
always keen to onboard people, I'll have a look either later today or tomorrow to point you to how you could do this, here I probably need to get you started as there's some finicky parser things to adjust though it's not very hard as will be obvious when you see the code.
One note:
which I think would be great, presuming we can do multi-line blocks, and connect blocks, eg
this is already the case, you don't need to name cells the same way, all cells in a page are assumed to be part of the same script so
```>
bar = 5
```
text
```>
bar^2
```
will basically show
```
julia> bar = 5
5
```
text
```
julia> bar^2
25
```
without any additional effort.
Sounds great!
alright, this: https://github.com/tlienart/Franklin.jl/pull/819 should give you a good start.
The main thing that's missing at a high level is something that splits code into individual blocks (things that in the REPL would be preceded by julia>
. We can make the assumption that folks only enter single liners but it's not very general. So e.g.
1+1
if true
print(5)
end
should be split into effectively two code blocks (1+1, (if...))
. I imagine there is such a functionality in either Julia.REPL or some similar module.
I've not tested this and you'd have to add that too.
Feel free to ping me from the PR or from a PR you'd open that's inspired by it and we can gradually figure the bits out :)
btw sorry, the bit you'd have to code in is https://github.com/tlienart/Franklin.jl/pull/819/commits/b902fe8e5374857835d5ed28739b24a5b8d1fa84#diff-1067c55b37e9e4106b24ecf530c6565835f5c83ff0ccca6d77c1a08bc7934342R119-R140
Hey there! This feature would be very useful for our blog post on modern Julia workflows 😍 Any idea how we can help push it past the finish line?
https://github.com/gdalle/ModernJuliaWorkflows
So it seems pkg/help/cmd mode are not straightforward to implement according to @tlienart For future reference, maybe the approach of Replay.jl can help? Not sure how easy it is to adapt, but I think this is the interesting portion of the code, at least for formatting purposes. https://github.com/AtelierArith/Replay.jl/blob/f0a71ba9d126b32cfcdbe8f2272d10147f5f234f/src/Replay.jl#L157-L200
No Replay doesn't really help.
- For
?
it seems thatBase.Docs.doc
should cover a large chunk of use cases (returns a vector of Markdown strings) - For
]
it seems that the basicPkg
commands such asstatus
can be shown to an IOBuffer so that at least the output can be mimicked fairly easily in those cases - For
;
it seems that the following would be ok:
a = tempname()
open(a, "w") do outf
redirect_stdout(outf) do
Base.repl_cmd(`ls`, nothing)
end
end
read(a, String)
so all of these things are doable at least at some basic level where the use cases shown are simple, the formatting of the output might look a bit different but that's probably acceptable and people can suggest improvements over time.
That would be awesome, and I'm happy to help. I tried to take a look at #819 but didn't get far, plus it's probably no longer actual. If you can point me at the parts of the code I need to modify, I can try to tackle one of these cases?
@gdalle I'll try to add the basic stuff to #1035 ; if you'd like to help I think using it and reporting on stuff you'd like / how things could be improved is likely to be most useful. The relevant code that you'd have to look at are:
- the evaluation (in the
resolve_code_block
function, you can see the update in the PR) - the html-ification (in the
html_repl_code
function)
I'll add soon:
- a path for
shell
,pkg
,help
(inresolve_code_block
) - the corresponding
html_shell_code
,html_help_code
,html_pkg_code
what there will be to do afterwards for which your help would be very welcome
- testing, likely adjustments of the formatting of the
html_*
functions so that the output is pretty, possible adjustments to theif shell / if pkg / if help
to encompass more use cases / be more general
Sounds good! I'll subscribe to the PR, whenever it gets updated I'll take it out for a spin :)