mirror of https://github.com/mpastell/Weave.jl
237 lines
8.5 KiB
Julia
237 lines
8.5 KiB
Julia
module Weave
|
|
import Highlights
|
|
using Compat
|
|
using Requires
|
|
|
|
function __init__()
|
|
@require Plots="91a5bcdd-55d7-5caf-9e0b-520d859cae80" Base.include(Main, "plots.jl")
|
|
@require Gadfly="c91e804a-d5a3-530f-b6f0-dfbca275c004" Base.include(Main, "gadfly.jl")
|
|
end
|
|
|
|
"""
|
|
`list_out_formats()`
|
|
|
|
List supported output formats
|
|
"""
|
|
function list_out_formats()
|
|
for format = keys(formats)
|
|
println(string(format,": ", formats[format].description))
|
|
end
|
|
end
|
|
|
|
|
|
"""
|
|
`tangle(source ; out_path=:doc, informat="noweb")`
|
|
|
|
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.
|
|
"""
|
|
function tangle(source ; out_path=:doc, informat=:auto)
|
|
doc = read_doc(source, informat)
|
|
doc.cwd = get_cwd(doc, out_path)
|
|
|
|
outname = get_outname(out_path, doc, ext = "jl")
|
|
|
|
open(outname, "w") do io
|
|
for chunk in doc.chunks
|
|
if typeof(chunk) == CodeChunk
|
|
options = merge(rcParams[:chunk_defaults], chunk.options)
|
|
if options[:tangle]
|
|
write(io, chunk.content*"\n")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
doc.cwd == pwd() && (outname = basename(outname))
|
|
@info("Writing to file $outname")
|
|
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 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) 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
|
|
|
|
**Note:** Run Weave from terminal and not using IJulia, Juno 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")
|
|
|
|
doc = read_doc(source, informat)
|
|
highlight_theme != nothing && (doc.highlight_theme = highlight_theme)
|
|
#theme != nothing && (doc.theme = theme) #Reserved for themes
|
|
css != nothing && (doc.css = css)
|
|
template != nothing && (doc.template = template)
|
|
|
|
WeaveMarkdown.reset_parser()
|
|
if haskey(doc.header, "bibliography")
|
|
WeaveMarkdown.init_parser(joinpath(dirname(source), doc.header["bibliography"]))
|
|
end
|
|
|
|
try
|
|
doc = run(doc, doctype = doctype,
|
|
mod = mod,
|
|
out_path=out_path, args = args,
|
|
fig_path = fig_path, fig_ext = fig_ext, cache_path = cache_path, cache=cache,
|
|
throw_errors = throw_errors)
|
|
formatted = format(doc)
|
|
|
|
outname = get_outname(out_path, doc)
|
|
|
|
open(outname, "w") do io
|
|
write(io, formatted)
|
|
end
|
|
|
|
#Special for that need external programs
|
|
if doc.doctype == "pandoc2html"
|
|
mdname = outname
|
|
outname = get_outname(out_path, doc, ext = "html")
|
|
pandoc2html(formatted, doc, outname, pandoc_options)
|
|
rm(mdname)
|
|
elseif doc.doctype == "pandoc2pdf"
|
|
mdname = outname
|
|
outname = get_outname(out_path, doc, ext = "pdf")
|
|
pandoc2pdf(formatted, doc, outname, pandoc_options)
|
|
rm(mdname)
|
|
elseif doc.doctype == "md2pdf"
|
|
success = run_latex(doc, outname, latex_cmd)
|
|
rm(doc.fig_path, force = true, recursive = true)
|
|
success || return
|
|
outname = get_outname(out_path, doc, ext = "pdf")
|
|
end
|
|
|
|
doc.cwd == pwd() && (outname = basename(outname))
|
|
@info("Report weaved to $outname")
|
|
# catch err
|
|
# @warn("Something went wrong during weaving")
|
|
# println(e)
|
|
finally
|
|
WeaveMarkdown.reset_parser()
|
|
doctype == :auto && (doctype = detect_doctype(doc.source))
|
|
if occursin("pandoc2pdf", doctype) && cache == :off
|
|
rm(doc.fig_path, force = true, recursive = true)
|
|
elseif occursin("2html", doctype)
|
|
rm(doc.fig_path, force = true, recursive = true)
|
|
end
|
|
end
|
|
end
|
|
|
|
function weave(doc::AbstractString, doctype::AbstractString)
|
|
weave(doc, doctype=doctype)
|
|
end
|
|
|
|
"""
|
|
notebook(source::String, out_path=:pwd, timeout=-1, nbconvert_options="")
|
|
|
|
Convert Weave document `source` to Jupyter notebook and execute the code
|
|
using nbconvert. Requires IJulia. **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`
|
|
"""
|
|
function notebook(source::String, out_path=:pwd, timeout=-1, nbconvert_options=[])
|
|
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")
|
|
Base.eval(Main, Meta.parse("import IJulia"))
|
|
out = read(`$(Main.IJulia.JUPYTER) nbconvert --ExecutePreprocessor.timeout=$timeout --to notebook --execute $outfile $nbconvert_options --output $outfile`, String)
|
|
end
|
|
|
|
"""
|
|
include_weave(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(source, informat=: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")
|
|
include_string(code)
|
|
catch e
|
|
cd(old_path)
|
|
throw(e)
|
|
end
|
|
end
|
|
|
|
#Hooks to run before and after chunks, this is form IJulia,
|
|
#but note that Weave hooks take the chunk as input
|
|
const preexecute_hooks = Function[]
|
|
push_preexecute_hook(f::Function) = push!(preexecute_hooks, f)
|
|
pop_preexecute_hook(f::Function) = splice!(preexecute_hooks, findfirst(preexecute_hooks, f))
|
|
|
|
const postexecute_hooks = Function[]
|
|
push_postexecute_hook(f::Function) = push!(postexecute_hooks, f)
|
|
pop_postexecute_hook(f::Function) = splice!(postexecute_hooks, findfirst(postexecute_hooks, f))
|
|
|
|
include("config.jl")
|
|
include("chunks.jl")
|
|
include("WeaveMarkdown/markdown.jl")
|
|
include("display_methods.jl")
|
|
include("readers.jl")
|
|
include("run.jl")
|
|
include("cache.jl")
|
|
include("formatters.jl")
|
|
include("format.jl")
|
|
include("pandoc.jl")
|
|
include("writers.jl")
|
|
|
|
|
|
export weave, list_out_formats, tangle, convert_doc, notebook,
|
|
set_chunk_defaults, get_chunk_defaults, restore_chunk_defaults,
|
|
include_weave
|
|
end
|