From f8c32c865bd1ecc856d9d847ecb7eae657a4e67f Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Thu, 26 Mar 2020 17:35:05 +0900 Subject: [PATCH] more type annotate APIs --- src/Weave.jl | 236 +++++++++++++++++++++++++++++-------------------- src/chunks.jl | 2 +- src/writers.jl | 11 ++- 3 files changed, 146 insertions(+), 103 deletions(-) diff --git a/src/Weave.jl b/src/Weave.jl index 7149a7e..6fa671c 100644 --- a/src/Weave.jl +++ b/src/Weave.jl @@ -1,5 +1,6 @@ module Weave import Highlights +using Mustache using Requires function __init__() @@ -8,7 +9,7 @@ function __init__() end """ -`list_out_formats()` + list_out_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. -* `informat`: `"noweb"` of `"markdown"` -* `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. +## Keyword options: + +- `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.cwd = get_cwd(doc, out_path) @@ -50,60 +59,80 @@ end """ - weave(source ; doctype = :auto, - informat=:auto, out_path=:doc, args = Dict(), - mod::Union{Module, Symbol} = Main, - fig_path = "figures", fig_ext = nothing, - cache_path = "cache", cache=:off, - template = nothing, highlight_theme = nothing, css = nothing, - pandoc_options = "", - latex_cmd = "xelatex") + weave( + source::AbstractString; + doctype::Union{Symbol,AbstractString} = :auto, + informat::Union{Symbol,AbstractString} = :auto, + out_path::Union{Symbol,AbstractString} = :doc, + args::Dict = Dict(), + mod::Union{Module,Symbol} = :sandbox, + 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. -* `doctype`: :auto = set based on file extension or specify one of the supported formats. - 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. +## Keyword options -**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, - informat=:auto, out_path=:doc, args = Dict(), - mod::Union{Module, Symbol} = :sandbox, - fig_path = "figures", fig_ext = nothing, - cache_path = "cache", cache=:off, - throw_errors = false, - template = nothing, highlight_theme = nothing, css = nothing, - pandoc_options = String[]::Array{String}, - latex_cmd = "xelatex",latex_keep_unicode=false) - +function weave( + source::AbstractString; + doctype::Union{Symbol,AbstractString} = :auto, + informat::Union{Symbol,AbstractString} = :auto, + out_path::Union{Symbol,AbstractString} = :doc, + args::Dict = Dict(), + mod::Union{Module,Symbol} = :sandbox, + 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 +) doc = read_doc(source, informat) doctype == :auto && (doctype = detect_doctype(doc.source)) doc.doctype = doctype - # Read args from document header, overrides command line args if haskey(doc.header, "options") (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)) @info("Report weaved to $outname") return abspath(outname) - #catch err - # @warn("Something went wrong during weaving") - # @error(sprint(showerror, err)) + # catch err + # @warn "Something went wrong during weaving" + # @error sprint(showerror, err) # return nothing finally doctype == :auto && (doctype = detect_doctype(doc.source)) - if occursin("2pdf", doctype) - rm(doc.fig_path, force = true, recursive = true) - elseif occursin("2html", doctype) - rm(doc.fig_path, force = true, recursive = true) - end + occursin(r"2(pdf|html)", doctype) && rm(doc.fig_path, force = true, recursive = true) end end -function weave(doc::AbstractString, doctype::AbstractString) - weave(doc, doctype=doctype) +weave(doc::AbstractString, doctype::Union{Symbol,AbstractString}) = + 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 """ - 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 -using nbconvert. **Ignores** all chunk options - -* `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. +Include code from Weave document calling `include_string` on all code from doc. +Code is run in the path of the include document. """ -function notebook(source::String; out_path=:pwd, timeout=-1, nbconvert_options=[], jupyter_path = "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 - - -""" - 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) +function include_weave( + m::Module, + source::AbstractString, + informat::Union{Symbol,AbstractString} = :auto, +) old_path = pwd() doc = read_doc(source, informat) cd(doc.path) try - code = join([x.content for x in - filter(x -> isa(x,Weave.CodeChunk), doc.chunks)], "\n") + code = join([x.content for x in filter(x -> isa(x, Weave.CodeChunk), doc.chunks)], "\n") include_string(m, code) catch e throw(e) diff --git a/src/chunks.jl b/src/chunks.jl index 9faec58..9161cd2 100644 --- a/src/chunks.jl +++ b/src/chunks.jl @@ -15,7 +15,7 @@ mutable struct WeaveDoc header::Dict template::Union{AbstractString, Mustache.MustacheTokens} css::AbstractString - highlight_theme + highlight_theme::Type{<:Highlights.AbstractTheme} fig_path::AbstractString chunk_defaults::Dict{Symbol,Any} function WeaveDoc(source, chunks, header) diff --git a/src/writers.jl b/src/writers.jl index 63684e6..60a110e 100644 --- a/src/writers.jl +++ b/src/writers.jl @@ -31,16 +31,15 @@ function detect_outformat(outfile::String) 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 -* `infile` = Name of the input document -* `outfile` = Name of the output document -* `format` = Output format (optional). Detected from outfile extension, but can - be set to `"script"`, `"markdown"`, `"notebook"` or `"noweb"`. +- `infile`: Path of the input document +- `outfile`: Path of the output document +- `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"` """ -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) if format == nothing