Similar to Bookdown, this package wraps around Pandoc. For websites, this package allows for:
If you don’t need to generate PDFs, then Franklin.jl is probably a better choice. To create single pages and PDFs containing code blocks, see Weave.jl.
One of the main differences with Franklin.jl, Weave.jl and knitr (Bookdown) is that this package completely decouples the computations from the building of the output. The benefit of this is that you can spawn two separate processes, namely the one to serve your webpages:
$ julia --project -e 'using Books; serve()'
Watching ./pandoc/favicon.png
Watching ./src/plots.jl
[...]
✓ LiveServer listening on http://localhost:8001/ ...
(use CTRL+C to shut down)
and the one where you do the computations for your package:
$ julia --project -ie 'using Books'
julia> gen()
[...]
Updating html
This way, the website remains responsive when the computations are running. Thanks to LiveServer.jl and Pandoc, updating the page after changing text or code takes less than a second. Also, because the serve
process does relatively few things, it almost never crashes.
As another benefit, the decoupling allows you to have more flexibility in when you want to run what code. In combination with Revise.jl, you can quickly update your code and see the updated output.
Another reason why this package looks different than other packages is because this package has been aimed at a REPL workflow. Via the REPL, the package evaluates the code blocks inside Main
by default. This provides easy access to the variables.
Finally, a big difference with this package and other packages is that you decide yourself what you want to show for a code block. For example, in R
```{r, results='hide'}
print("Hello, world!")
```
shows the code and not the output. Instead, in Books, you would write
```jl
s = """print("Hello, world!")"""
sc(s)
```
which is displayed as
print("Hello, world!")
Here, sc
is one of the convenience methods exported by Books.jl. Although this approach is more verbose in some cases, it is also much more flexible. In essence, you can come up with your own pre- or post-processing logic. For example, lets write
```jl
code = """
df = DataFrame(a=[1, 2], b=[3, 4])
Options(df, caption="A table.", label=nothing)
"""
repeat(sco(code), 4)
```
which shows the code and output (sco
) 4 times:
df = DataFrame(a=[1, 2], b=[3, 4])
Options(df, caption="A table.", label=nothing)
a | b |
---|---|
1 | 3 |
2 | 4 |
df = DataFrame(a=[1, 2], b=[3, 4])
Options(df, caption="A table.", label=nothing)
a | b |
---|---|
1 | 3 |
2 | 4 |
df = DataFrame(a=[1, 2], b=[3, 4])
Options(df, caption="A table.", label=nothing)
a | b |
---|---|
1 | 3 |
2 | 4 |
df = DataFrame(a=[1, 2], b=[3, 4])
Options(df, caption="A table.", label=nothing)
a | b |
---|---|
1 | 3 |
2 | 4 |