Allow setting document options in YAML header

pull/202/head
Matti Pastell 2019-03-05 19:36:27 +02:00
parent 52f3a23d28
commit 6082786f92
12 changed files with 74 additions and 62 deletions

2
.gitignore vendored
View File

@ -22,6 +22,8 @@ test/**/chunk_options.jl
doc/build doc/build
doc/site doc/site
stable/ stable/
doc/Manifest.toml
Manifest.toml
tmp/ tmp/
.idea .idea

View File

@ -1,11 +1,16 @@
using Documenter, Weave using Documenter, Weave
cd("doc") start_dir = pwd()
makedocs( modules = Weave, sitename="Weave.jl", makedocs( modules = Weave, sitename="Weave.jl",
pages = ["index.md", "getting_started.md", "usage.md", pages = ["index.md", "getting_started.md", "usage.md",
"publish.md", "chunk_options.md", "notebooks.md", "publish.md", "chunk_options.md", "notebooks.md",
"function_index.md"] "function_index.md"]
) )
cd(@__DIR__)
include("make_examples.jl") include("make_examples.jl")
cd(start_dir)
deploydocs( deploydocs(
repo = "github.com/mpastell/Weave.jl.git", repo = "github.com/mpastell/Weave.jl.git",

View File

@ -4,13 +4,7 @@ I've mostly followed [Knitr](http://yihui.name/knitr/options)'s naming for chunk
Options are separated using ";" and need to be valid Julia expressions. Example: markdown code chunk that saves and displays a 12 cm wide image and hides the source code: Options are separated using ";" and need to be valid Julia expressions. Example: markdown code chunk that saves and displays a 12 cm wide image and hides the source code:
`julia; out_width="12cm"; echo=false`
```julia; out_width="12cm"; echo=false
using Gadfly
x = linspace(0, 2π, 200)
plot(x=x, y = sin(x), Geom.line)
```
Weave currently supports the following chunk options with the following defaults: Weave currently supports the following chunk options with the following defaults:
@ -43,18 +37,16 @@ Weave currently supports the following chunk options with the following defaults
## Set default chunk options ## Set default chunk options
You can set or change the default chunk options for a document either before You can set the default chunk options (and `weave` arguments) for a document using the YAML header `options` field. e.g to set the default `out_width` of all figures you can use:
running weave or inside the weaved document. You can e.g. use a hidden chunk
in the beginning of the source document to set the options:
```julia; echo = false>>= ```yaml
import Weave ---
Weave.set_chunk_defaults(Dict{Symbol, Any}( options:
:out_width => "\\0.5linewidth", out_width : 50%
:results => "tex" ---
)) ```
```
You can also set or change the default chunk options for a document either before weave using the `set_chunk_defaults function`.
```@docs ```@docs
set_chunk_defaults(opts) set_chunk_defaults(opts)

View File

@ -123,10 +123,10 @@ added to output e.g. to include a Plots figure in markdown you can use:
## Setting document options in header ## Setting document options in header
You can use a YAML header in the beginning of the input document delimited with "---" to set the document title, author and date e.g. and default document options. Each of Weave command line arguments can be set in header using `options` field. Below is an example that sets document `out_path` and `doctype` using the header. You can use a YAML header in the beginning of the input document delimited with "---" to set the document title, author and date e.g. and default document options. Each of Weave command line arguments and chunk options can be set in header using `options` field. Below is an example that sets document `out_path` and `doctype` using the header.
``` ```yaml
--- ---
title : Weave example title : Weave example
author : Matti Pastell author : Matti Pastell

View File

@ -38,7 +38,7 @@ function tangle(source ; out_path=:doc, informat=:auto)
open(outname, "w") do io open(outname, "w") do io
for chunk in doc.chunks for chunk in doc.chunks
if typeof(chunk) == CodeChunk if typeof(chunk) == CodeChunk
options = merge(rcParams[:chunk_defaults], chunk.options) options = merge(doc.chunk_defaults, chunk.options)
if options[:tangle] if options[:tangle]
write(io, chunk.content*"\n") write(io, chunk.content*"\n")
end end
@ -105,7 +105,7 @@ function weave(source ; doctype = :auto,
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,
cache_path, cache, throw_errors, template, highlight_theme, css, cache_path, cache, throw_errors, template, highlight_theme, css,
pandoc_options, latex_cmd) = parse_header_options(doc) pandoc_options, latex_cmd) = header_args(doc)
end end
highlight_theme != nothing && (doc.highlight_theme = highlight_theme) highlight_theme != nothing && (doc.highlight_theme = highlight_theme)
@ -148,13 +148,13 @@ 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("pandoc2pdf", doctype) && cache == :off if occursin("2pdf", doctype)
rm(doc.fig_path, force = true, recursive = true) rm(doc.fig_path, force = true, recursive = true)
elseif occursin("2html", doctype) elseif occursin("2html", doctype)
rm(doc.fig_path, force = true, recursive = true) rm(doc.fig_path, force = true, recursive = true)

View File

@ -17,11 +17,12 @@ mutable struct WeaveDoc
css::AbstractString css::AbstractString
highlight_theme highlight_theme
fig_path::AbstractString fig_path::AbstractString
chunk_defaults::Dict{Symbol,Any}
function WeaveDoc(source, chunks, header) function WeaveDoc(source, chunks, header)
path, fname = splitdir(abspath(source)) path, fname = splitdir(abspath(source))
basename = splitext(fname)[1] basename = splitext(fname)[1]
new(source, basename, path, chunks, "", nothing, "", "", header, new(source, basename, path, chunks, "", nothing, "", "", header,
"", "", Highlights.Themes.DefaultTheme, "") "", "", Highlights.Themes.DefaultTheme, "", deepcopy(rcParams[:chunk_defaults]))
end end
end end

View File

@ -40,15 +40,6 @@ const defaultParams =
#This one can be changed at runtime, initially a copy of defaults #This one can be changed at runtime, initially a copy of defaults
const rcParams = deepcopy(defaultParams) const rcParams = deepcopy(defaultParams)
#Parameters set per document
const docParams =Dict{Symbol,Any}(
:fig_path=> nothing,
:fig_ext => nothing,
)
""" """
`set_chunk_defaults(opts::Dict{Symbol, Any})` `set_chunk_defaults(opts::Dict{Symbol, Any})`
@ -82,7 +73,6 @@ Restore Weave.jl default chunk options
""" """
function restore_chunk_defaults() function restore_chunk_defaults()
rcParams[:chunk_defaults] = defaultParams[:chunk_defaults] rcParams[:chunk_defaults] = defaultParams[:chunk_defaults]
merge!(rcParams[:chunk_defaults], docParams)
return nothing return nothing
end end
@ -97,7 +87,6 @@ function combine_args(args, doctype)
common[key] = args[key] common[key] = args[key]
end end
end end
@info specific
haskey(specific, doctype) && merge!(common, specific[doctype]) haskey(specific, doctype) && merge!(common, specific[doctype])
common common
end end
@ -105,11 +94,11 @@ end
getvalue(d::Dict, key , default) = haskey(d, key) ? d[key] : default getvalue(d::Dict, key , default) = haskey(d, key) ? d[key] : default
""" """
`parse_header_options(doc::WeaveDoc)` header_args(doc::WeaveDoc)`
Parse document options from document header Get weave arguments from document header
""" """
function parse_header_options(doc::WeaveDoc) function header_args(doc::WeaveDoc)
args = getvalue(doc.header, "options", Dict()) args = getvalue(doc.header, "options", Dict())
doctype = getvalue(args, "doctype", doc.doctype) doctype = getvalue(args, "doctype", doc.doctype)
args = combine_args(args, doctype) args = combine_args(args, doctype)
@ -132,3 +121,16 @@ function parse_header_options(doc::WeaveDoc)
cache_path, cache, throw_errors, template, highlight_theme, css, cache_path, cache, throw_errors, template, highlight_theme, css,
pandoc_options, latex_cmd) pandoc_options, latex_cmd)
end end
"""
`header_chunk_defaults!(doc::WeaveDoc)`
Get chunk defaults from header and update
"""
function header_chunk_defaults!(doc::WeaveDoc)
for key in keys(doc.chunk_defaults)
if haskey(doc.header["options"], String(key))
doc.chunk_defaults[key] = doc.header["options"][String(key)]
end
end
end

View File

@ -56,6 +56,7 @@ function read_doc(source::AbstractString, format=:auto)
parsed = parse_doc(document, format) parsed = parse_doc(document, format)
header = parse_header(parsed[1]) header = parse_header(parsed[1])
doc = WeaveDoc(source, parsed, header) doc = WeaveDoc(source, parsed, header)
haskey(header, "options") && header_chunk_defaults!(doc)
return doc return doc
end end

View File

@ -47,7 +47,7 @@ function Base.run(doc::WeaveDoc; doctype = :auto,
Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/")) Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/"))
doc.fig_path = fig_path doc.fig_path = fig_path
set_rc_params(doc.format.formatdict, fig_path, fig_ext) set_rc_params(doc, fig_path, fig_ext)
#New sandbox for each document with args exposed #New sandbox for each document with args exposed
if mod == :sandbox if mod == :sandbox
@ -82,7 +82,7 @@ function Base.run(doc::WeaveDoc; doctype = :auto,
chunk = doc.chunks[i] chunk = doc.chunks[i]
if isa(chunk, CodeChunk) if isa(chunk, CodeChunk)
options = merge(rcParams[:chunk_defaults], chunk.options) options = merge(doc.chunk_defaults, chunk.options)
merge!(chunk.options, options) merge!(chunk.options, options)
end end
@ -91,7 +91,7 @@ function Base.run(doc::WeaveDoc; doctype = :auto,
if cached != nothing && (cache == :all || restore) if cached != nothing && (cache == :all || restore)
result_chunks = restore_chunk(chunk, cached) result_chunks = restore_chunk(chunk, cached)
else else
result_chunks = run_chunk(chunk, report, mod) result_chunks = run_chunk(chunk, doc, report, mod)
end end
executed = [executed; result_chunks] executed = [executed; result_chunks]
@ -125,7 +125,7 @@ function detect_doctype(source::AbstractString)
end end
function run_chunk(chunk::CodeChunk, report::Report, SandBox::Module) function run_chunk(chunk::CodeChunk, doc::WeaveDoc, report::Report, SandBox::Module)
@info("Weaving chunk $(chunk.number) from line $(chunk.start_line)") @info("Weaving chunk $(chunk.number) from line $(chunk.start_line)")
result_chunks = eval_chunk(chunk, report, SandBox) result_chunks = eval_chunk(chunk, report, SandBox)
occursin("2html", report.formatdict[:doctype]) && (result_chunks = embed_figures(result_chunks, report.cwd)) occursin("2html", report.formatdict[:doctype]) && (result_chunks = embed_figures(result_chunks, report.cwd))
@ -163,19 +163,19 @@ function img2base64(fig, cwd)
end end
end end
function run_chunk(chunk::DocChunk, report::Report, SandBox::Module) function run_chunk(chunk::DocChunk, doc::WeaveDoc, report::Report, SandBox::Module)
chunk.content = [run_inline(c, report, SandBox) for c in chunk.content] chunk.content = [run_inline(c, doc, report, SandBox) for c in chunk.content]
return chunk return chunk
end end
function run_inline(inline::InlineText, report::Report, SandBox::Module) function run_inline(inline::InlineText, doc::WeaveDoc, report::Report, SandBox::Module)
return inline return inline
end end
function run_inline(inline::InlineCode, report::Report, SandBox::Module) function run_inline(inline::InlineCode, doc::WeaveDoc, report::Report, SandBox::Module)
#Make a temporary CodeChunk for running code. Collect results and don't wrap #Make a temporary CodeChunk for running code. Collect results and don't wrap
chunk = CodeChunk(inline.content, 0, 0, "", Dict(:hold => true, :wrap => false)) chunk = CodeChunk(inline.content, 0, 0, "", Dict(:hold => true, :wrap => false))
options = merge(rcParams[:chunk_defaults], chunk.options) options = merge(doc.chunk_defaults, chunk.options)
merge!(chunk.options, options) merge!(chunk.options, options)
chunks = eval_chunk(chunk, report, SandBox) chunks = eval_chunk(chunk, report, SandBox)
@ -268,7 +268,6 @@ end
function eval_chunk(chunk::CodeChunk, report::Report, SandBox::Module) function eval_chunk(chunk::CodeChunk, report::Report, SandBox::Module)
if !chunk.options[:eval] if !chunk.options[:eval]
chunk.output = "" chunk.output = ""
chunk.options[:fig] = false chunk.options[:fig] = false
@ -375,21 +374,17 @@ function get_outname(out_path::AbstractString, doc::WeaveDoc; ext = nothing)
end end
end end
function set_rc_params(doc::WeaveDoc, fig_path, fig_ext)
function set_rc_params(formatdict, fig_path, fig_ext) formatdict = doc.format.formatdict
if fig_ext == nothing if fig_ext == nothing
rcParams[:chunk_defaults][:fig_ext] = formatdict[:fig_ext] doc.chunk_defaults[:fig_ext] = formatdict[:fig_ext]
docParams[:fig_ext] = formatdict[:fig_ext]
else else
rcParams[:chunk_defaults][:fig_ext] = fig_ext doc.chunk_defaults[:fig_ext] = fig_ext
docParams[:fig_ext] = fig_ext
end end
rcParams[:chunk_defaults][:fig_path] = fig_path doc.chunk_defaults[:fig_path] = fig_path
docParams[:fig_path] = fig_path
return nothing return nothing
end end
function collect_results(chunk::CodeChunk, fmt::ScriptResult) function collect_results(chunk::CodeChunk, fmt::ScriptResult)
content = "" content = ""
result_no = 1 result_no = 1

View File

@ -0,0 +1,12 @@
---
options:
md2html :
out_path : html
echo : false
out_width : 30%
---
```julia
repeat("🐐", 10)
```

View File

@ -89,7 +89,6 @@ testcows = """
🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄""" 🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄"""
wcows = Weave.wrapline(cows) wcows = Weave.wrapline(cows)
println(wcows)
@test wcows == testcows @test wcows == testcows
@test length(split(wcows, "\n")[1]) == 75 @test length(split(wcows, "\n")[1]) == 75

View File

@ -21,3 +21,6 @@ args = header["options"]
"out_path" => "md/") "out_path" => "md/")
@test Weave.combine_args(args, "pandoc") == Dict("fig_ext" => ".png", @test Weave.combine_args(args, "pandoc") == Dict("fig_ext" => ".png",
"out_path" => "reports") "out_path" => "reports")
doc = Weave.read_doc(joinpath(@__DIR__, "documents", "header_test.jmd"))
@test doc.chunk_defaults[:echo] == false
@test doc.chunk_defaults[:out_width] == "30%"