Fix: Documents run code in separate SandBoxes. Each document is executed in separate sandbox module instead of redefining the same one. Fixes warnings and occasional segfaults.

pull/29/head
Matti Pastell 2015-01-07 12:20:48 +02:00
parent 91914d675a
commit ee262e81a4
7 changed files with 59 additions and 18 deletions

View File

@ -3,6 +3,7 @@
### Changes in master
* Each document is executed in separate sandbox module instead of redefining the same one. Fixes warnings and occasional segfaults.
* New chunk option: `line_width`.
* Bug fix in wrapping output lines.
* Internal changes

View File

@ -2,3 +2,4 @@ julia 0.3
Compat
ArgParse
Docile
JSON

View File

@ -61,6 +61,7 @@ function tangle(source ; out_path=:doc, informat="noweb")
doc = read_doc(source, informat)
cwd = get_cwd(doc, out_path)
outname = "$(cwd)/$(doc.basename).jl"
open(outname, "w") do io
for chunk in doc.chunks
@ -70,7 +71,7 @@ function tangle(source ; out_path=:doc, informat="noweb")
end
end
info("Writing to file $(basename).jl")
info("Writing to file $(doc.basename).jl")
end
@doc md"""
@ -93,11 +94,13 @@ weave(source ; doctype = "pandoc", plotlib="Gadfly",
**Note:** Run Weave from terminal and not using IJulia, Juno or ESS, they tend to mess with capturing output.
""" ->
function weave(source ; doctype = "pandoc", plotlib="Gadfly",
informat="noweb", out_path=:doc, fig_path = "figures", fig_ext = nothing)
informat="noweb", out_path=:doc, fig_path = "figures", fig_ext = nothing,
cache_path = "cache")
doc = read_doc(source, informat) #Reader toimii, muuten kesken...
doc = run(doc, doctype = doctype, plotlib=plotlib,
informat = informat, out_path=out_path, fig_path = fig_path, fig_ext = fig_ext)
informat = informat, out_path=out_path,
fig_path = fig_path, fig_ext = fig_ext, cache_path = cache_path)
formatted = format(doc)
outname = "$(doc.cwd)/$(doc.basename).$(doc.format.formatdict[:extension])"

10
src/cache.jl Normal file
View File

@ -0,0 +1,10 @@
import JSON
function cache(doc::WeaveDoc, cache_path)
end
#Todo caching of data, can get the contents of module using:
#names(ReportSandBox, all=true)

View File

@ -1,6 +1,8 @@
const rcParams =
@compat Dict{Symbol,Any}(:plotlib => "PyPlot",
:storeresults => false,
:doc_number => 0,
:chunk_defaults =>
Dict{Symbol,Any}(
:echo=> true,

View File

@ -1,12 +1,18 @@
function run(doc::WeaveDoc; doctype = "pandoc", plotlib="Gadfly", informat="noweb", out_path=:doc, fig_path = "figures", fig_ext = nothing)
function run(doc::WeaveDoc; doctype = "pandoc", plotlib="Gadfly", informat="noweb",
out_path=:doc, fig_path = "figures", fig_ext = nothing, cache_path = "cache")
doc.cwd = get_cwd(doc, out_path)
doc.format = formats[doctype]
set_rc_params(doc.format.formatdict, fig_path, fig_ext)
#Clear sandbox for each document
#Raises a warning, couldn't find a "cleaner"
#way to do it.
eval(parse("module ReportSandBox\nend"))
#New sandbox for each document
sandbox = "ReportSandBox$(rcParams[:doc_number])"
eval(parse("module $sandbox\nend"))
SandBox = eval(parse(sandbox))
rcParams[:doc_number] += 1
init_plotting(plotlib)
report = Report(doc.cwd, doc.basename, doc.format.formatdict)
@ -14,16 +20,18 @@ function run(doc::WeaveDoc; doctype = "pandoc", plotlib="Gadfly", informat="nowe
executed = Any[]
for chunk in copy(doc.chunks)
result_chunk = eval_chunk(chunk, report::Report)
result_chunk = eval_chunk(chunk, report, SandBox)
push!(executed, result_chunk)
end
popdisplay(report)
#Clear variables from used sandbox
clear_sandbox(SandBox)
doc.chunks = executed
return doc
end
function run_block(code_str, report::Report)
function run_block(code_str, report::Report, SandBox::Module)
oldSTDOUT = STDOUT
result = ""
@ -37,7 +45,7 @@ function run_block(code_str, report::Report)
while pos < n
oldpos = pos
code, pos = parse(code_str, pos)
s = eval(ReportSandBox, code)
s = eval(SandBox, code)
if rcParams[:plotlib] == "Gadfly"
s != nothing && display(s)
end
@ -53,7 +61,7 @@ function run_block(code_str, report::Report)
return string("\n", result)
end
function run_term(code_str, report::Report)
function run_term(code_str, report::Report, SandBox::Module)
prompt = "\njulia> "
codestart = "\n\n"*report.formatdict[:codestart]
@ -72,14 +80,14 @@ function run_term(code_str, report::Report)
prompts = string(prompt, rstrip(code_str[oldpos:(pos-1)]), "\n")
report.cur_result *= prompts
report.term_state = :text
s = eval(ReportSandBox, code)
s = eval(SandBox, code)
s != nothing && display(s)
end
return string(report.cur_result)
end
function eval_chunk(chunk::CodeChunk, report::Report)
function eval_chunk(chunk::CodeChunk, report::Report, SandBox::Module)
info("Weaving chunk $(chunk.number) from line $(chunk.start_line)")
defaults = copy(rcParams[:chunk_defaults])
options = copy(chunk.options)
@ -110,10 +118,10 @@ function eval_chunk(chunk::CodeChunk, report::Report)
end
if chunk.options[:term]
chunk.output = run_term(chunk.content, report::Report)
chunk.output = run_term(chunk.content, report, SandBox)
chunk.options[:term_state] = report.term_state
else
chunk.output = run_block(chunk.content, report::Report)
chunk.output = run_block(chunk.content, report, SandBox)
end
if rcParams[:plotlib] == "PyPlot"
@ -124,10 +132,20 @@ function eval_chunk(chunk::CodeChunk, report::Report)
chunk
end
function eval_chunk(chunk::DocChunk, report::Report)
function eval_chunk(chunk::DocChunk, report::Report, SandBox)
chunk
end
#Set all variables to nothing
function clear_sandbox(SandBox::Module)
for name = names(SandBox, true)
if name != :eval && name != names(SandBox)[1]
eval(SandBox, parse(string(string(name), "=nothing")))
end
end
end
function get_figname(report::Report, chunk; fignum = nothing)
figpath = joinpath(report.cwd, chunk.options[:fig_path])
isdir(figpath) || mkdir(figpath)

View File

@ -3,10 +3,16 @@ using Base.Test
# Running Changin plotlib in tests segfault, unless they are run
# using separate processes.
run(`julia --code-coverage=user -e 'include("winston_formats.jl")'`)
#run(`julia --code-coverage=user -e 'include("winston_formats.jl")'`)
#run(`julia --code-coverage=user -e 'include("pyplot_formats.jl")'`)
info("Test: Chunk options")
include("chunk_options.jl")
info("Testing: Weaving with Winston")
include("winston_formats.jl")
info("Test: Weaving with Gadfly")
include("gadfly_formats.jl")
weave("documents/gadfly_markdown_test.jmd", doctype="github",plotlib="gadfly", informat="markdown")