mirror of https://github.com/mpastell/Weave.jl
more type annotate APIs
parent
529edaf94e
commit
f8c32c865b
236
src/Weave.jl
236
src/Weave.jl
|
@ -1,5 +1,6 @@
|
||||||
module Weave
|
module Weave
|
||||||
import Highlights
|
import Highlights
|
||||||
|
using Mustache
|
||||||
using Requires
|
using Requires
|
||||||
|
|
||||||
function __init__()
|
function __init__()
|
||||||
|
@ -8,7 +9,7 @@ function __init__()
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
`list_out_formats()`
|
list_out_formats()
|
||||||
|
|
||||||
List supported output formats
|
List supported output formats
|
||||||
"""
|
"""
|
||||||
|
@ -20,15 +21,23 @@ end
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
`tangle(source ; out_path=:doc, informat="noweb")`
|
tangle(source; out_path=:doc, informat=:auto)
|
||||||
|
|
||||||
Tangle source code from input document to .jl file.
|
Tangle source code from input document to .jl file.
|
||||||
|
|
||||||
* `informat`: `"noweb"` of `"markdown"`
|
## Keyword options:
|
||||||
* `out_path`: Path where the output is generated. Can be: `:doc`: Path of the source document, `:pwd`: Julia working directory, `"somepath"`, directory name as a string e.g `"/home/mpastell/weaveout"`
|
|
||||||
or filename as string e.g. ~/outpath/outfile.jl.
|
- `informat = :auto`: Input document format. `:auto` will set it automatically based on file extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||||
|
- `out_path = :doc`: Path where the output is generated can be either of:
|
||||||
|
* `:doc`: Path of the source document (default)
|
||||||
|
* `:pwd`: Julia working directory
|
||||||
|
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||||
"""
|
"""
|
||||||
function tangle(source ; out_path=:doc, informat=:auto)
|
function tangle(
|
||||||
|
source;
|
||||||
|
out_path::Union{Symbol,AbstractString} = :doc,
|
||||||
|
informat::Union{Symbol,AbstractString} = :auto
|
||||||
|
)
|
||||||
doc = read_doc(source, informat)
|
doc = read_doc(source, informat)
|
||||||
doc.cwd = get_cwd(doc, out_path)
|
doc.cwd = get_cwd(doc, out_path)
|
||||||
|
|
||||||
|
@ -50,60 +59,80 @@ end
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
weave(source ; doctype = :auto,
|
weave(
|
||||||
informat=:auto, out_path=:doc, args = Dict(),
|
source::AbstractString;
|
||||||
mod::Union{Module, Symbol} = Main,
|
doctype::Union{Symbol,AbstractString} = :auto,
|
||||||
fig_path = "figures", fig_ext = nothing,
|
informat::Union{Symbol,AbstractString} = :auto,
|
||||||
cache_path = "cache", cache=:off,
|
out_path::Union{Symbol,AbstractString} = :doc,
|
||||||
template = nothing, highlight_theme = nothing, css = nothing,
|
args::Dict = Dict(),
|
||||||
pandoc_options = "",
|
mod::Union{Module,Symbol} = :sandbox,
|
||||||
latex_cmd = "xelatex")
|
fig_path::AbstractString = "figures",
|
||||||
|
fig_ext::Union{Nothing,AbstractString} = nothing,
|
||||||
|
cache_path::AbstractString = "cache",
|
||||||
|
cache::Symbol = :off,
|
||||||
|
throw_errors::Bool = false,
|
||||||
|
template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing,
|
||||||
|
highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing,
|
||||||
|
css::Union{Nothing,AbstractString} = nothing,
|
||||||
|
pandoc_options::Vector{<:AbstractString} = String[],
|
||||||
|
latex_cmd::AbstractString = "xelatex",
|
||||||
|
latex_keep_unicode::Bool = false
|
||||||
|
)
|
||||||
|
|
||||||
Weave an input document to output file.
|
Weave an input document to output file.
|
||||||
|
|
||||||
* `doctype`: :auto = set based on file extension or specify one of the supported formats.
|
## Keyword options
|
||||||
See `list_out_formats()`
|
|
||||||
* `informat`: :auto = set based on file extension or set to `"noweb"`, `"markdown"` or `script`
|
|
||||||
* `out_path`: Path where the output is generated. Can be: `:doc`: Path of the source document, `:pwd`:
|
|
||||||
Julia working directory, `"somepath"`: output directory as a String e.g `"/home/mpastell/weaveout"` or filename as
|
|
||||||
string e.g. ~/outpath/outfile.tex.
|
|
||||||
* `args`: dictionary of arguments to pass to document. Available as WEAVE_ARGS
|
|
||||||
* `mod`: Module where Weave `eval`s code. Defaults to `:sandbox`
|
|
||||||
to create new sandbox module, you can also pass a module e.g. `Main`.
|
|
||||||
* `fig_path`: where figures will be generated, relative to out_path
|
|
||||||
* `fig_ext`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`.
|
|
||||||
* `cache_path`: where of cached output will be saved.
|
|
||||||
* `cache`: controls caching of code: `:off` = no caching, `:all` = cache everything,
|
|
||||||
`:user` = cache based on chunk options, `:refresh`, run all code chunks and save new cache.
|
|
||||||
* `throw_errors`: if `false` errors are included in output document and the whole document is
|
|
||||||
executed. if `true` errors are thrown when they occur.
|
|
||||||
* `template`: Template (file path) or MustacheTokens for md2html or md2tex formats.
|
|
||||||
* `highlight_theme`: Theme (Highlights.AbstractTheme) for used syntax highlighting
|
|
||||||
* `css`: CSS (file path) used for md2html format
|
|
||||||
* `pandoc_options`: String array of options to pass to pandoc for `pandoc2html` and
|
|
||||||
`pandoc2pdf` formats e.g. ["--toc", "-N"]
|
|
||||||
* `latex_cmd`: the command used to make pdf from .tex
|
|
||||||
* `latex_keep_unicode`: if set to true (default is false), do not convert unicode characters to their
|
|
||||||
respective latex representation. This is especially useful if a font and tex-engine with support for unicode
|
|
||||||
characters are used.
|
|
||||||
|
|
||||||
**Note:** Run Weave from terminal and not using IJulia, Juno or ESS, they tend to mess with capturing output.
|
- `doctype = :auto`: Output document format. `:auto` will set it automatically based on file extension. You can also manually specify it; see [`list_out_formats()`](@ref) for the supported formats
|
||||||
|
- `informat = :auto`: Input document format. `:auto` will set it automatically based on file extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||||
|
- `out_path = :doc`: Path where the output is generated can be either of:
|
||||||
|
* `:doc`: Path of the source document (default)
|
||||||
|
* `:pwd`: Julia working directory
|
||||||
|
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||||
|
- `args = Dict()`: Arguments to be passed to the weaved document; will be available as `WEAVE_ARGS` in the document
|
||||||
|
- `mod = :sandbox`: Module where Weave `eval`s code. Defaults to `:sandbox` to create new sandbox module. You also can also pass a `Module` e.g. `Main`
|
||||||
|
- `fig_path = "figures"`: Where figures will be generated, relative to `out_path`
|
||||||
|
- `fig_ext = nothing`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`
|
||||||
|
- `cache_path = "cache"`: Where of cached output will be saved
|
||||||
|
- `cache = :off`: Controls caching of code:
|
||||||
|
* `:off` means no caching (default)
|
||||||
|
* `:all` caches everything
|
||||||
|
* `:user` caches based on chunk options
|
||||||
|
* `:refresh` runs all code chunks and save new cache
|
||||||
|
- `throw_errors = false`: If `false` errors are included in output document and the whole document is executed. If `true` errors are thrown when they occur
|
||||||
|
- `template = nothing`: Template (file path) or `Mustache.MustacheTokens`s for `md2html` or `md2tex` formats
|
||||||
|
- `highlight_theme = nothing`: Theme used for syntax highlighting (defaults to `Highlights.Themes.DefaultTheme`)
|
||||||
|
- `css = nothing`: Path of a CSS file used for md2html format
|
||||||
|
- `pandoc_options = String[]`: `String`s of options to pass to pandoc for `pandoc2html` and `pandoc2pdf` formats, e.g. `["--toc", "-N"]`
|
||||||
|
- `latex_cmd = "xelatex"`: The command used to make PDF file from .tex
|
||||||
|
- `latex_keep_unicode = false`: If `true`, do not convert unicode characters to their respective latex representation. This is especially useful if a font and tex-engine with support for unicode characters are used
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
Run Weave from terminal and try to avoid weaving from IJulia or ESS; they tend to mess with capturing output.
|
||||||
"""
|
"""
|
||||||
function weave(source ; doctype = :auto,
|
function weave(
|
||||||
informat=:auto, out_path=:doc, args = Dict(),
|
source::AbstractString;
|
||||||
mod::Union{Module, Symbol} = :sandbox,
|
doctype::Union{Symbol,AbstractString} = :auto,
|
||||||
fig_path = "figures", fig_ext = nothing,
|
informat::Union{Symbol,AbstractString} = :auto,
|
||||||
cache_path = "cache", cache=:off,
|
out_path::Union{Symbol,AbstractString} = :doc,
|
||||||
throw_errors = false,
|
args::Dict = Dict(),
|
||||||
template = nothing, highlight_theme = nothing, css = nothing,
|
mod::Union{Module,Symbol} = :sandbox,
|
||||||
pandoc_options = String[]::Array{String},
|
fig_path::AbstractString = "figures",
|
||||||
latex_cmd = "xelatex",latex_keep_unicode=false)
|
fig_ext::Union{Nothing,AbstractString} = nothing,
|
||||||
|
cache_path::AbstractString = "cache",
|
||||||
|
cache::Symbol = :off,
|
||||||
|
throw_errors::Bool = false,
|
||||||
|
template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing,
|
||||||
|
highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing,
|
||||||
|
css::Union{Nothing,AbstractString} = nothing,
|
||||||
|
pandoc_options::Vector{<:AbstractString} = String[],
|
||||||
|
latex_cmd::AbstractString = "xelatex",
|
||||||
|
latex_keep_unicode::Bool = false
|
||||||
|
)
|
||||||
doc = read_doc(source, informat)
|
doc = read_doc(source, informat)
|
||||||
doctype == :auto && (doctype = detect_doctype(doc.source))
|
doctype == :auto && (doctype = detect_doctype(doc.source))
|
||||||
doc.doctype = doctype
|
doc.doctype = doctype
|
||||||
|
|
||||||
|
|
||||||
# Read args from document header, overrides command line args
|
# Read args from document header, overrides command line args
|
||||||
if haskey(doc.header, "options")
|
if haskey(doc.header, "options")
|
||||||
(doctype, informat, out_path, args, mod, fig_path, fig_ext,
|
(doctype, informat, out_path, args, mod, fig_path, fig_ext,
|
||||||
|
@ -155,66 +184,81 @@ function weave(source ; doctype = :auto,
|
||||||
doc.cwd == pwd() && (outname = basename(outname))
|
doc.cwd == pwd() && (outname = basename(outname))
|
||||||
@info("Report weaved to $outname")
|
@info("Report weaved to $outname")
|
||||||
return abspath(outname)
|
return abspath(outname)
|
||||||
#catch err
|
# catch err
|
||||||
# @warn("Something went wrong during weaving")
|
# @warn "Something went wrong during weaving"
|
||||||
# @error(sprint(showerror, err))
|
# @error sprint(showerror, err)
|
||||||
# return nothing
|
# return nothing
|
||||||
finally
|
finally
|
||||||
doctype == :auto && (doctype = detect_doctype(doc.source))
|
doctype == :auto && (doctype = detect_doctype(doc.source))
|
||||||
if occursin("2pdf", doctype)
|
occursin(r"2(pdf|html)", doctype) && rm(doc.fig_path, force = true, recursive = true)
|
||||||
rm(doc.fig_path, force = true, recursive = true)
|
|
||||||
elseif occursin("2html", doctype)
|
|
||||||
rm(doc.fig_path, force = true, recursive = true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function weave(doc::AbstractString, doctype::AbstractString)
|
weave(doc::AbstractString, doctype::Union{Symbol,AbstractString}) =
|
||||||
weave(doc, doctype=doctype)
|
weave(doc; doctype = doctype)
|
||||||
|
|
||||||
|
"""
|
||||||
|
notebook(
|
||||||
|
source::AbstractString;
|
||||||
|
out_path::Union{Symbol,AbstractString} = :pwd,
|
||||||
|
timeout = -1,
|
||||||
|
nbconvert_options::AbstractString = "",
|
||||||
|
jupyter_path::AbstractString = "jupyter",
|
||||||
|
)
|
||||||
|
|
||||||
|
Convert Weave document `source` to Jupyter notebook and execute the code using `nbconvert`.
|
||||||
|
**Ignores** all chunk options.
|
||||||
|
|
||||||
|
## Keyword options
|
||||||
|
|
||||||
|
- `out_path = :pwd`: Path where the output is generated can be either of:
|
||||||
|
* `:doc`: Path of the source document
|
||||||
|
* `:pwd`: Julia working directory (default)
|
||||||
|
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||||
|
- `timeout = -1`: nbconvert cell timeout in seconds. Defaults to `-1` (no timeout)
|
||||||
|
- `nbconvert_options = ""`: `String` of additional options to pass to nbconvert, such as `"--allow-errors"`
|
||||||
|
- `jupyter_path = "jupyter"`: Path/command for the Jupyter you want to use. Defaults to "jupyter," which runs whatever is linked/alias to that
|
||||||
|
"""
|
||||||
|
function notebook(
|
||||||
|
source::AbstractString;
|
||||||
|
out_path::Union{Symbol,AbstractString} = :pwd,
|
||||||
|
timeout = -1,
|
||||||
|
nbconvert_options::AbstractString = "",
|
||||||
|
jupyter_path::AbstractString = "jupyter",
|
||||||
|
)
|
||||||
|
doc = read_doc(source)
|
||||||
|
converted = convert_doc(doc, NotebookOutput())
|
||||||
|
doc.cwd = get_cwd(doc, out_path)
|
||||||
|
outfile = get_outname(out_path, doc, ext = "ipynb")
|
||||||
|
|
||||||
|
open(outfile, "w") do f
|
||||||
|
write(f, converted)
|
||||||
|
end
|
||||||
|
|
||||||
|
@info("Running nbconvert")
|
||||||
|
out = read(
|
||||||
|
`$jupyter_path nbconvert --ExecutePreprocessor.timeout=$timeout --to notebook --execute $outfile $nbconvert_options --output $outfile`,
|
||||||
|
String,
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
notebook(source::String; out_path=:pwd, timeout=-1, nbconvert_options="", jupyter_path = "jupyter")
|
include_weave(source::AbstractString, informat::Union{Symbol,AbstractString} = :auto)
|
||||||
|
include_weave(m::Module, source::AbstractString, informat::Union{Symbol,AbstractString} = :auto)
|
||||||
|
|
||||||
Convert Weave document `source` to Jupyter notebook and execute the code
|
Include code from Weave document calling `include_string` on all code from doc.
|
||||||
using nbconvert. **Ignores** all chunk options
|
Code is run in the path of the include document.
|
||||||
|
|
||||||
* `out_path`: Path where the output is generated. Can be: `:doc`: Path of the source document,
|
|
||||||
`:pwd`: Julia working directory, `"somepath"`: Path as a
|
|
||||||
String e.g `"/home/mpastell/weaveout"`
|
|
||||||
* `timeout`: nbconvert cell timeout in seconds. Defaults to -1 (no timeout)
|
|
||||||
* `nbconvert_options`: string of additional options to pass to nbconvert, such as `--allow-errors`
|
|
||||||
* `jupyter_path`: Path/command for the Jupyter you want to use. Defaults to "jupyter," which runs whatever is linked/alias to that.
|
|
||||||
"""
|
"""
|
||||||
function notebook(source::String; out_path=:pwd, timeout=-1, nbconvert_options=[], jupyter_path = "jupyter")
|
function include_weave(
|
||||||
doc = read_doc(source)
|
m::Module,
|
||||||
converted = convert_doc(doc, NotebookOutput())
|
source::AbstractString,
|
||||||
doc.cwd = get_cwd(doc, out_path)
|
informat::Union{Symbol,AbstractString} = :auto,
|
||||||
outfile = get_outname(out_path, doc, ext="ipynb")
|
)
|
||||||
|
|
||||||
open(outfile, "w") do f
|
|
||||||
write(f, converted)
|
|
||||||
end
|
|
||||||
|
|
||||||
@info("Running nbconvert")
|
|
||||||
out = read(`$jupyter_path nbconvert --ExecutePreprocessor.timeout=$timeout --to notebook --execute $outfile $nbconvert_options --output $outfile`, String)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
include_weave(doc, informat=:auto)
|
|
||||||
include_weave(m::Module, doc, informat=:auto)
|
|
||||||
|
|
||||||
Include code from Weave document calling `include_string` on
|
|
||||||
all code from doc. Code is run in the path of the include document.
|
|
||||||
"""
|
|
||||||
function include_weave(m::Module, source, informat=:auto)
|
|
||||||
old_path = pwd()
|
old_path = pwd()
|
||||||
doc = read_doc(source, informat)
|
doc = read_doc(source, informat)
|
||||||
cd(doc.path)
|
cd(doc.path)
|
||||||
try
|
try
|
||||||
code = join([x.content for x in
|
code = join([x.content for x in filter(x -> isa(x, Weave.CodeChunk), doc.chunks)], "\n")
|
||||||
filter(x -> isa(x,Weave.CodeChunk), doc.chunks)], "\n")
|
|
||||||
include_string(m, code)
|
include_string(m, code)
|
||||||
catch e
|
catch e
|
||||||
throw(e)
|
throw(e)
|
||||||
|
|
|
@ -15,7 +15,7 @@ mutable struct WeaveDoc
|
||||||
header::Dict
|
header::Dict
|
||||||
template::Union{AbstractString, Mustache.MustacheTokens}
|
template::Union{AbstractString, Mustache.MustacheTokens}
|
||||||
css::AbstractString
|
css::AbstractString
|
||||||
highlight_theme
|
highlight_theme::Type{<:Highlights.AbstractTheme}
|
||||||
fig_path::AbstractString
|
fig_path::AbstractString
|
||||||
chunk_defaults::Dict{Symbol,Any}
|
chunk_defaults::Dict{Symbol,Any}
|
||||||
function WeaveDoc(source, chunks, header)
|
function WeaveDoc(source, chunks, header)
|
||||||
|
|
|
@ -31,16 +31,15 @@ function detect_outformat(outfile::String)
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
`convert_doc(infile::AbstractString, outfile::AbstractString; format = nothing)`
|
convert_doc(infile::AbstractString, outfile::AbstractString; format::Union{Nothing,AbstractString} = nothing)
|
||||||
|
|
||||||
Convert Weave documents between different formats
|
Convert Weave documents between different formats
|
||||||
|
|
||||||
* `infile` = Name of the input document
|
- `infile`: Path of the input document
|
||||||
* `outfile` = Name of the output document
|
- `outfile`: Path of the output document
|
||||||
* `format` = Output format (optional). Detected from outfile extension, but can
|
- `format = nothing`: Output document format (optional). It will be detected automatically from the `outfile` extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
|
||||||
be set to `"script"`, `"markdown"`, `"notebook"` or `"noweb"`.
|
|
||||||
"""
|
"""
|
||||||
function convert_doc(infile::AbstractString, outfile::AbstractString; format = nothing)
|
function convert_doc(infile::AbstractString, outfile::AbstractString; format::Union{Nothing,AbstractString} = nothing)
|
||||||
doc = read_doc(infile)
|
doc = read_doc(infile)
|
||||||
|
|
||||||
if format == nothing
|
if format == nothing
|
||||||
|
|
Loading…
Reference in New Issue