Merge pull request #319 from JunoLab/avi/weavedoc

remove weird default constructor for `WeaveDoc`
pull/313/head
Shuhei Kadowaki 2020-05-09 23:39:03 +09:00 committed by GitHub
commit a526cb8f15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 117 additions and 108 deletions

View File

@ -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,
)

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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 &#96;import Pkg; Pkg.add&#40;&quot;NonExisting&quot;&#41;&#96; 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 == ""

View File

@ -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

View File

@ -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

View File

@ -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`

View File

@ -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")

View File

@ -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