mirror of https://github.com/mpastell/Weave.jl
Merge pull request #319 from JunoLab/avi/weavedoc
remove weird default constructor for `WeaveDoc`pull/313/head
commit
a526cb8f15
|
@ -3,6 +3,9 @@ import Highlights
|
|||
using Mustache
|
||||
using Requires
|
||||
|
||||
|
||||
const WEAVE_OPTION_NAME = "options" # TODO: rename to "weave_options"
|
||||
|
||||
function __init__()
|
||||
@require Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Base.include(
|
||||
Main,
|
||||
|
@ -123,7 +126,7 @@ function weave(
|
|||
doc.doctype = doctype
|
||||
|
||||
# Read args from document header, overrides command line args
|
||||
if haskey(doc.header, "options")
|
||||
if haskey(doc.header, WEAVE_OPTION_NAME)
|
||||
(
|
||||
doctype,
|
||||
informat,
|
||||
|
@ -248,7 +251,7 @@ function notebook(
|
|||
end
|
||||
|
||||
@info "Running nbconvert"
|
||||
out = read(
|
||||
return out = read(
|
||||
`$jupyter_path nbconvert --ExecutePreprocessor.timeout=$timeout --to notebook --execute $outfile $nbconvert_options --output $outfile`,
|
||||
String,
|
||||
)
|
||||
|
|
|
@ -107,7 +107,7 @@ function header_args(
|
|||
pandoc_options,
|
||||
latex_cmd,
|
||||
)
|
||||
args = get(doc.header, "options", Dict())
|
||||
args = get(doc.header, WEAVE_OPTION_NAME, Dict())
|
||||
doctype = get(args, "doctype", doc.doctype)
|
||||
args = combine_args(args, doctype)
|
||||
informat = get(args, "informat", :auto)
|
||||
|
@ -145,16 +145,3 @@ function header_args(
|
|||
latex_cmd,
|
||||
)
|
||||
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 (val = get(doc.header["options"], string(key), nothing)) !== nothing
|
||||
doc.chunk_defaults[key] = val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -131,7 +131,7 @@ function strip_header!(docchunk::DocChunk, doctype)
|
|||
else
|
||||
# only strips Weave headers
|
||||
header = YAML.load(m[:header])
|
||||
delete!(header, "options")
|
||||
delete!(header, WEAVE_OPTION_NAME)
|
||||
if isempty(header)
|
||||
lstrip(replace(content, HEADER_REGEX => ""))
|
||||
else
|
||||
|
|
|
@ -2,20 +2,48 @@ using JSON, YAML
|
|||
|
||||
|
||||
"""
|
||||
read_doc(source::AbstractString, format = :auto) -> WeaveDoc
|
||||
read_doc(source, format = :auto)
|
||||
|
||||
Read the input document from `source` and parse it into [`WeaveDoc`](@ref).
|
||||
"""
|
||||
function read_doc(source::AbstractString, format = :auto)
|
||||
function read_doc(source, format = :auto)
|
||||
document = replace(read(source, String), "\r\n" => "\n") # fix line ending
|
||||
|
||||
format === :auto && (format = detect_informat(source))
|
||||
chunks = parse_doc(document, format)
|
||||
header = parse_header(first(chunks))
|
||||
doc = WeaveDoc(source, chunks, header)
|
||||
haskey(header, "options") && header_chunk_defaults!(doc) # TODO: rename `options` => `weave_options`
|
||||
return WeaveDoc(source, chunks)
|
||||
end
|
||||
|
||||
return doc
|
||||
function WeaveDoc(source, chunks)
|
||||
path, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
|
||||
header = parse_header(first(chunks))
|
||||
# get chunk defaults from header and update
|
||||
chunk_defaults = deepcopy(rcParams[:chunk_defaults])
|
||||
if haskey(header, WEAVE_OPTION_NAME)
|
||||
for key in keys(chunk_defaults)
|
||||
if (val = get(header[WEAVE_OPTION_NAME], string(key), nothing)) !== nothing
|
||||
chunk_defaults[key] = val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return WeaveDoc(
|
||||
source,
|
||||
basename,
|
||||
path,
|
||||
chunks,
|
||||
"",
|
||||
nothing,
|
||||
"",
|
||||
"",
|
||||
header,
|
||||
"",
|
||||
"",
|
||||
Highlights.Themes.DefaultTheme,
|
||||
"",
|
||||
chunk_defaults,
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
|
@ -32,7 +60,7 @@ function detect_informat(source::AbstractString)
|
|||
return "noweb"
|
||||
end
|
||||
|
||||
function parse_doc(document, format)
|
||||
function parse_doc(document, format)::Vector{WeaveChunk}
|
||||
return if format == "markdown"
|
||||
parse_markdown(document)
|
||||
elseif format == "noweb"
|
||||
|
|
20
src/types.jl
20
src/types.jl
|
@ -17,26 +17,6 @@ mutable struct WeaveDoc
|
|||
highlight_theme::Type{<:Highlights.AbstractTheme}
|
||||
fig_path::AbstractString
|
||||
chunk_defaults::Dict{Symbol,Any}
|
||||
function WeaveDoc(source, chunks, header)
|
||||
path, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
new(
|
||||
source,
|
||||
basename,
|
||||
path,
|
||||
chunks,
|
||||
"",
|
||||
nothing,
|
||||
"",
|
||||
"",
|
||||
header,
|
||||
"",
|
||||
"",
|
||||
Highlights.Themes.DefaultTheme,
|
||||
"",
|
||||
deepcopy(rcParams[:chunk_defaults]),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
struct ChunkOutput
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
s1= """
|
||||
|
||||
```julia
|
||||
using NonExisting
|
||||
```
|
||||
|
||||
```julia
|
||||
x =
|
||||
```
|
||||
|
||||
|
||||
```julia;term=true
|
||||
plot(x)
|
||||
y = 10
|
||||
print(y
|
||||
```
|
||||
|
||||
"""
|
||||
|
||||
p1 = Weave.parse_markdown(s1)
|
||||
doc = Weave.WeaveDoc("dummy1.jmd", p1, Dict())
|
||||
doc1 = run_doc(doc, doctype = "pandoc")
|
||||
|
||||
@test doc1.chunks[1].output == "Error: ArgumentError: Package NonExisting not found in current path:\n- Run `import Pkg; Pkg.add(\"NonExisting\")` to install the NonExisting package.\n\n"
|
||||
@test doc1.chunks[2].output == "Error: syntax: incomplete: premature end of input\n"
|
||||
@test doc1.chunks[3].output == "\njulia> plot(x)\nError: UndefVarError: plot not defined\n\njulia> y = 10\n10\n\njulia> print(y\nError: syntax: incomplete: premature end of input\n"
|
||||
|
||||
@test_throws ArgumentError run_doc(doc, doctype = "pandoc", throw_errors = true)
|
||||
|
||||
doc = Weave.WeaveDoc("dummy1.jmd", p1, Dict())
|
||||
doc3 = run_doc(doc, doctype = "md2html")
|
||||
@test doc3.chunks[1].rich_output == "<pre class=\"julia-error\">\nERROR: ArgumentError: Package NonExisting not found in current path:\n- Run `import Pkg; Pkg.add("NonExisting")` to install the NonExisting package.\n\n</pre>\n"
|
||||
@test doc3.chunks[2].rich_output == "<pre class=\"julia-error\">\nERROR: syntax: incomplete: premature end of input\n</pre>\n"
|
||||
@test doc3.chunks[3].output == "\njulia> plot(x)\nError: UndefVarError: plot not defined\n\njulia> y = 10\n10\n\njulia> print(y\nError: syntax: incomplete: premature end of input\n"
|
||||
@test doc3.chunks[3].rich_output == ""
|
|
@ -127,24 +127,21 @@ pformat.formatdict[:keep_unicode] = true
|
|||
f = Weave.format_chunk(dchunk, pformat.formatdict, pformat)
|
||||
@test f == "\\section{Test chunk}\nα\n\n"
|
||||
|
||||
function doc_from_string(str)
|
||||
parsed = Weave.parse_markdown(str)
|
||||
header = Weave.parse_header(parsed[1])
|
||||
Weave.WeaveDoc("",parsed,header)
|
||||
end
|
||||
|
||||
doc_content = """
|
||||
str = """
|
||||
```julia
|
||||
α = 10
|
||||
```
|
||||
"""
|
||||
|
||||
parsed = doc_from_string(doc_content)
|
||||
ldoc = run_doc(parsed, doctype = "md2tex")
|
||||
@test occursin(Weave.uc2tex("α"),Weave.format(ldoc))
|
||||
@test !occursin("α",Weave.format(ldoc))
|
||||
let
|
||||
doc = run_doc(mock_doc(str), doctype = "md2tex")
|
||||
@test occursin(Weave.uc2tex("α"), Weave.format(doc))
|
||||
@test !occursin("α", Weave.format(doc))
|
||||
end
|
||||
|
||||
parsed = doc_from_string(doc_content)
|
||||
ldoc = run_doc(parsed, doctype = "md2tex",latex_keep_unicode=true)
|
||||
@test occursin("α",Weave.format(ldoc))
|
||||
@test !occursin(Weave.uc2tex("α"),Weave.format(ldoc))
|
||||
let
|
||||
doc = run_doc(mock_doc(str), doctype = "md2tex",latex_keep_unicode = true)
|
||||
@test occursin("α", Weave.format(doc))
|
||||
@test !occursin(Weave.uc2tex("α"), Weave.format(doc))
|
||||
end
|
||||
|
|
|
@ -6,16 +6,15 @@ using Test
|
|||
# TODO: add test for header processsing
|
||||
# TODO: add test for `include_weave`
|
||||
|
||||
# constructs `WeaveDoc` from `String`
|
||||
mock_doc(str, chunk_parser = Weave.parse_markdown) = Weave.WeaveDoc("dummy", chunk_parser(str))
|
||||
|
||||
|
||||
@testset "Weave" begin
|
||||
@testset "Chunk options" begin
|
||||
include("chunk_options.jl")
|
||||
end
|
||||
|
||||
@testset "Error handling " begin
|
||||
include("errors_test.jl")
|
||||
end
|
||||
|
||||
@testset "module evaluation" begin
|
||||
include("test_module_evaluation.jl")
|
||||
end
|
||||
|
@ -24,6 +23,10 @@ using Test
|
|||
include("test_header.jl")
|
||||
end
|
||||
|
||||
@testset "error rendering" begin
|
||||
include("test_error_rendering.jl")
|
||||
end
|
||||
|
||||
@testset "Conversions" begin
|
||||
include("convert_test.jl")
|
||||
end
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
function get_err_str(ex)
|
||||
try
|
||||
eval(ex)
|
||||
catch err
|
||||
return sprint(showerror, err)
|
||||
end
|
||||
end
|
||||
get_err_str(str::AbstractString) = get_err_str(Meta.parse(str; raise = false))
|
||||
|
||||
err_stmt1 = "using NonExisting"
|
||||
err_stmt2 = "x = "
|
||||
err_stmt3 = """
|
||||
plot(x)
|
||||
y = 10
|
||||
f(y
|
||||
"""
|
||||
|
||||
str = """
|
||||
```julia
|
||||
$err_stmt1
|
||||
```
|
||||
|
||||
```julia
|
||||
$err_stmt2
|
||||
```
|
||||
|
||||
```julia; term=true
|
||||
$err_stmt3
|
||||
```
|
||||
"""
|
||||
|
||||
err_str1 = get_err_str(err_stmt1)
|
||||
err_str2 = get_err_str(err_stmt2)
|
||||
err_str3_1 = get_err_str("plot(x)")
|
||||
err_str3_2 = get_err_str("f(y")
|
||||
|
||||
|
||||
let doc = run_doc(mock_doc(str), doctype = "pandoc")
|
||||
get_output(i) = doc.chunks[i].output
|
||||
|
||||
@test occursin(err_str1, get_output(1))
|
||||
@test occursin(err_str2, get_output(2))
|
||||
@test occursin(err_str3_1, get_output(3))
|
||||
@test occursin(err_str3_2, get_output(3))
|
||||
end
|
||||
|
||||
@test_throws ArgumentError run_doc(mock_doc(str), doctype = "pandoc", throw_errors = true)
|
||||
|
||||
# TODO: test error rendering in `rich_output`
|
|
@ -1,4 +1,4 @@
|
|||
using YAML
|
||||
using Weave.YAML
|
||||
|
||||
# TODO:
|
||||
# - header stripping
|
||||
|
@ -19,7 +19,7 @@ options:
|
|||
---
|
||||
""")
|
||||
|
||||
let args = header["options"]
|
||||
let args = header[Weave.WEAVE_OPTION_NAME]
|
||||
@test Weave.combine_args(args, "md2html") == Dict("fig_ext" => ".png", "out_path" => "html/")
|
||||
@test Weave.combine_args(args, "github") == Dict("fig_ext" => ".png", "out_path" => "md/")
|
||||
@test Weave.combine_args(args, "pandoc") == Dict("fig_ext" => ".png", "out_path" => "reports")
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
@testset "evaluation module" begin
|
||||
function mock_output(document, mod = nothing)
|
||||
parsed = Weave.parse_markdown(document)
|
||||
doc = Weave.WeaveDoc("dummy.jmd", parsed, Dict())
|
||||
result_doc = run_doc(doc, mod = mod)
|
||||
@test isdefined(result_doc.chunks[1], :output)
|
||||
function mock_output(str, mod = nothing)
|
||||
result_doc = run_doc(mock_doc(str), mod = mod)
|
||||
return result_doc.chunks[1].output
|
||||
end
|
||||
|
||||
document = """
|
||||
str = """
|
||||
```julia
|
||||
@__MODULE__
|
||||
```
|
||||
"""
|
||||
|
||||
# in sandbox
|
||||
@test occursin(r"\#+WeaveSandBox[\#\d]+", mock_output(document))
|
||||
@test occursin(r"\#+WeaveSandBox[\#\d]+", mock_output(str))
|
||||
|
||||
# in Main
|
||||
@test strip(mock_output(document, Main)) == "Main"
|
||||
@test strip(mock_output(str, Main)) == "Main"
|
||||
end
|
||||
|
||||
@testset "clear_module!" begin
|
||||
|
|
Loading…
Reference in New Issue