ExampleJuggler.ExampleJuggler
— ModuleExampleJuggler
ExampleJuggler.jl
This package also could be called "DocumenterAndTestExampleHandler.jl". It helps to maintain comprehensive complete (i.e. ready to download and run) code examples in Documenter.jl documentation.
Code examples could be in plain Julia scripts, Julia scripts containing modules or pluto notebooks and serve three purposes:
- Ready to be run by users
- Part of CI tests
- Well integrated into documenter based documentation (via Literate.jl, PlutoStaticHTML.jl or PlutoSliderServer.jl)
Maintaining a list of examples leads to considerable boilerplate ("example juggling" - that is why the name ...) in test/runtest.jl
and docs/make.jl
. This package helps to hide this boilerplate behind its API.
Breaking changes
- v2.0.0: Moved all direct and indirect dependencies on Pluto into extensions. Correspondingly, one needs to explicitely import Pluto, PlutoStaticHTML or PlutoSliderServer. They are not anymore direct dependencies of ExampleJuggler.
CI Tests
With this package, test/runtests.jl
can look as follows(please see test/runtests.jl
of this package for a more comprehensive setting):
using Test
using ExampleJuggler
import Pluto
ExampleJuggler.verbose!(true)
example_dir = joinpath(@__DIR__, "..", "examples")
modules = ["ExampleModule.jl"]
notebooks = ["PlutoTemplate.jl", "ExamplePluto.jl"]
scripts = ["testscript.jl", "PlutoTemplate.jl", "ExamplePluto.jl"]
# This needs `import Pluto`
@testset "pluto notebooks" begin
@testplutonotebooks(example_dir, notebooks)
end
@testset "module examples" begin
@testmodules(example_dir, modules, a=2)
end
# This tests Pluto notebooks as scripts and doesn't need Pluto
@testset "scripts + notebooks" begin
@testscripts(example_dir, scripts)
end
Documenter build
With this package, docs/make.jl
can look as follows (please see docs/make.jl
of this package for a more comprehensive setting):
using Documenter, ExampleJuggler, CairoMakie
import PlutoStaticHTML
DocMeta.setdocmeta!(ExampleJuggler, :DocTestSetup, :(using ExampleJuggler); recursive = true)
example_dir = joinpath(@__DIR__, "..", "examples")
modules = ["ExampleModule.jl"]
notebooks = ["PlutoTemplate.jl"
"Example with Graphics" => "ExamplePluto.jl"]
cleanexamples()
module_examples = @docmodules(example_dir, example_modules, Plotter=CairoMakie)
# This needs to load PlutoStaticHTML
html_examples = @docplutonotebooks(example_dir, notebooks)
makedocs(; sitename = "ExampleJuggler.jl",
modules = [ExampleJuggler],
format = Documenter.HTML(; size_threshold_ignore = last.(html_examples),
mathengine = MathJax3()),
authors = "J. Fuhrmann",
repo = "https://github.com/j-fu/ExampleJuggler.jl",
pages = [
"api.md",
"Modules" => module_examples,
"Notebooks" => html_examples,
])
cleanexamples()
deploydocs(; repo = "github.com/j-fu/ExampleJuggler.jl.git", devbranch = "main")
end
In particular, graphics generation for module and script examples is supported.
ExampleJuggler.cleanexamples
— Methodcleanexamples()
Clean intermediate files from example documentation.
ExampleJuggler.docmodules
— Method docmodules(example_dir, example_modules; kwargs...)
Generate markdown files for use with documenter from list of Julia code examples in example_dir
via Literate.jl in form of modules.
Keyword arguments:
use_module_titles
: use titles from module input files
See ExampleModule.jl for an example.
ExampleJuggler.docplutonotebooks
— Methoddocplutonotebooks(example_dir, notebooks, kwargs...)
Parameters:
notebooks
: vector of pathnames or pairs of pathnames and strings pointing to notebooks to be tested.
Keyword arguments:
pluto_project
: if notnothing
, this is passed viaENV["PLUTO_PROJECT"]
to the notebooks with the possibility to activate it. By default it has the value ofBase.active_project()
which in practice is the environmentruntests.jl
is running in. As a consequence, if this default is kept, it is necessary to have all package dependencies of the notebooks in the package environment.iframe
: boolean (default: false).- If
true
, html files are produced from the notebooks via PlutoSliderServer.jl, similar to Pluto's html export. For documenter, a markdown page is created which contains statements to show the notebook html in an iframe. The advantage of this method is that active javascript content is shown. The disadvantage is weak integration into documenter. Prerequisite isimport PlutoSliderServer
indocs/make.jl
. - If false, Documenter markdown files are ceated via PlutoStaticHTML.jl. These integrate well with Documenter, but are (as of now) unable to show active javascript content. Graphics is best prepared with CairoMakie. Prerequisite is
import PlutoStaticHTML
indocs/make.jl
.
- If
distributed
: Use parallel evaluation wheniframe==false
source_prefix
: Path prefix to the notebooks on github (for generating download links) Default: "https://github.com/j-fu/ExampleJuggler.jl/blob/main/examples".iframe_height
: Height of the iframe generated. Default: "500px".
Return value: Vector of pairs of pathnames and strings pointing to generated markdown files for use in Documenter.makedocs()
ExampleJuggler.docplutosliderserver
— Functiondocplutosliderserver(example_dir, notebooks; pluto_project, source_prefix, iframe_height, force)
Document notebooks via PlutoSliderServer.jl Implemented in extension ExampleJugglerPlutoSliderServerExt
.
ExampleJuggler.docplutostatichtml
— Functiondocplutostatichtml(example_dir, notebooks; pluto_project)
Document notebooks via PlutoStaticHTML.jl. Implemented in extension ExampleJugglerPlutoStaticHTMLExt
.
ExampleJuggler.example_md_dir
— Method example_md_dir(subdir)
Return full path to the subdirectory of docs/src where the markdown files should be placed which later will be scanned by Documenter. Creates the directory if it doesn't already exist.
ExampleJuggler.mock_x
— Methodmock_x(; n, f)
Generate n-Vector X
and return X, f.(X)
for some function f;
ExampleJuggler.mock_xt
— Methodmock_xt(; n, m, f)
Generate n-Vector `X`, m-Vector `T` and return `X,T,[f(x,t) for x ∈ X, t∈T]` for some function f;
ExampleJuggler.replace_atat
— Methodreplace_atat(input)
Replace "@@" marker with "@". Used for postprocessing the output of Literate.markdown
in ExampleJuggler.docmodules
.
ExampleJuggler.replace_source_url
— Methodreplace_source_url(input, source_url)
Replace "@SOURCE_URL" marker with url of source. Used for preprocessing the input of Literate.markdown
in ExampleJuggler.docmodules
.
ExampleJuggler.startroot!
— Methodstartroot!(dir)
Assume dir
is the directory from which make.jl
has been invoked (normally, package root or the docs
subdirectory). Used in example_md_dir
.
ExampleJuggler.testplutonotebook
— Functiontestplutonotebook(notebookname; pluto_project = nothing)
Test pluto notebook in a Pluto session. Core of testplutonotebooks
. Implemented in extension ExampleJugglerPlutoExt
.
ExampleJuggler.testplutonotebooks
— Method testplutonotebooks(example_dir, notebooks; kwargs...)
Test pluto notebooks as notebooks in a pluto session which means that the notebook code is run in an extra process. Implemented in an extension triggered by using Pluto
.
The method tracks Test.@test
statements in notebook cells via testing errors of failed cells. The method does not invoke eventual runteststs()
methods in the notebooks.
Parameters:
example_dir
: subdirectory with examplesnotebooks
: vector of pathnames of notebooks to be tested.
Keyword arguments:
pluto_project
: if notnothing
, this is passed viaENV["PLUTO_PROJECT"]
to the notebooks with the possibility to activate it. By default it has the value ofBase.active_project()
which in practice is the environmentruntests.jl
is running in. As a consequence, if this default is kept, it is necessary to have all package dependencies of the notebooks in the package environment.
ExampleJuggler.verbose!
— Methodverbose(true_or_false)
Set verbosity
ExampleJuggler.@docmodules
— Macro@docmodules(example_dir, modules, kwargs...)
Generate markdown files and plots for use with documenter from list of Julia modules. Wrapper macro for docmodules
.
ExampleJuggler.@docplutonotebooks
— Macro@docplutonotebooks(example_dir, notebooklist, kwargs...)
Macro wrapper for docplutonotebooks
. Just for aestethic reasons, as other parts of the API have to be macros.
ExampleJuggler.@docscripts
— Macro@docscripts(example_dir, modules, kwargs...)
Generate markdown files and plots for use with documenter from list of Julia modules. Wrapper macro for docmodules
.
ExampleJuggler.@plotmodule
— Macro@plotmodule(modules, kwargs...)
Include module into context of calling module and execute generateplots(;kwargs...)
if it exists.
ExampleJuggler.@plotmodules
— Macro@plotmodules(modules, kwargs...)
Plot several scripts defining modules via @plotmodule
.
ExampleJuggler.@testmodule
— Macro@testmodule
Include script defining a module in the context of the calling module and call the runtests
method if it is defined in this module, passing kwargs...
.
ExampleJuggler.@testmodules
— Macro@testmodules(example_dir,modules, kwargs...)
Test several scripts defining modules via @testmodule
.
ExampleJuggler.@testplutonotebooks
— Macro @testplutonotebooks(example_dir,notebooks, kwargs...)
Macro wrapper for testplutonotebooks
. Just for aestethic reasons, as other parts of the API have to be macros.
ExampleJuggler.@testscript
— Macrotestscript(script)
Wrap script (or Pluto notebook seen as script) into a custom module and evaluate it in the context of the calling module. If the script contains a function runtests
, call it. It is assumed that the script uses Test.@test
to test correctness.
ExampleJuggler.@testscripts
— Macro@testscripts(example_dir, scripts)
Run scripts in the context of the calling module via @testscript