mirror of https://github.com/mpastell/Weave.jl
Refactoring to cleaner API. Added WeaveDoc type.
Reading and running chunks now return WeaveDoc's. Cleaned weave function significantly.pull/29/head
parent
e76e823a3d
commit
5d1f5ab4d7
161
src/Weave.jl
161
src/Weave.jl
|
@ -6,21 +6,18 @@ using Docile
|
|||
|
||||
#Contains report global properties
|
||||
type Report <: Display
|
||||
source::String
|
||||
documentationmode::Bool
|
||||
cwd::String
|
||||
basename::String
|
||||
formatdict
|
||||
formatdict::Dict{Symbol,Any}
|
||||
pending_code::String
|
||||
cur_result::String
|
||||
fignum::Int
|
||||
figures::Array
|
||||
figures::Array{String}
|
||||
term_state::Symbol
|
||||
cur_chunk
|
||||
|
||||
|
||||
function Report()
|
||||
new("", false, "", "", Any[], "", "", 1, Any[], :text, @compat Dict{Symbol, Any}() )
|
||||
function Report(cwd, basename, formatdict)
|
||||
new(cwd, basename, formatdict, "", "", 1, String[], :text, nothing)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -63,22 +60,12 @@ tangle(source ; out_path=:doc, informat="noweb")
|
|||
`"somepath"`: Path as a string e.g `"/home/mpastell/weaveout"`
|
||||
"""->
|
||||
function tangle(source ; out_path=:doc, informat="noweb")
|
||||
cwd, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
doc = read_doc(source, informat)
|
||||
cwd = get_cwd(doc, out_path)
|
||||
|
||||
#Set the output directory
|
||||
if out_path == :doc
|
||||
cwd = cwd
|
||||
elseif out_path == :pwd
|
||||
cwd = pwd()
|
||||
else
|
||||
cwd = out_path
|
||||
end
|
||||
|
||||
|
||||
outname = "$(cwd)/$(basename).jl"
|
||||
outname = "$(cwd)/$(doc.basename).jl"
|
||||
open(outname, "w") do io
|
||||
for chunk in read_doc(source, informat)
|
||||
for chunk in doc.chunks
|
||||
if typeof(chunk) == CodeChunk
|
||||
write(io, chunk.content*"\n")
|
||||
end
|
||||
|
@ -107,140 +94,24 @@ 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)
|
||||
function weave(source ; doctype = "pandoc", plotlib="Gadfly",
|
||||
informat="noweb", out_path=:doc, fig_path = "figures", fig_ext = nothing)
|
||||
|
||||
report = Report()
|
||||
cwd, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
formatdict = formats[doctype].formatdict
|
||||
if fig_ext == nothing
|
||||
rcParams[:chunk_defaults][:fig_ext] = formatdict[:fig_ext]
|
||||
else
|
||||
rcParams[:chunk_defaults][:fig_ext] = fig_ext
|
||||
end
|
||||
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)
|
||||
formatted = format(doc)
|
||||
|
||||
#Set the output directory
|
||||
if out_path == :doc
|
||||
report.cwd = cwd
|
||||
elseif out_path == :pwd
|
||||
report.cwd = pwd()
|
||||
else
|
||||
report.cwd = out_path
|
||||
end
|
||||
|
||||
|
||||
|
||||
report.source = source
|
||||
report.basename = basename
|
||||
rcParams[:chunk_defaults][:fig_path] = fig_path
|
||||
report.formatdict = formatdict
|
||||
|
||||
|
||||
if plotlib == nothing
|
||||
rcParams[:chunk_defaults][:fig] = false
|
||||
else
|
||||
l_plotlib = lowercase(plotlib)
|
||||
rcParams[:chunk_defaults][:fig] = true
|
||||
if l_plotlib == "winston"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","winston.jl"))"""))
|
||||
rcParams[:plotlib] = "Winston"
|
||||
elseif l_plotlib == "pyplot"
|
||||
eval(Expr(:using, :PyPlot))
|
||||
rcParams[:plotlib] = "PyPlot"
|
||||
elseif l_plotlib == "gadfly"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","gadfly.jl"))"""))
|
||||
rcParams[:plotlib] = "Gadfly"
|
||||
end
|
||||
end
|
||||
|
||||
pushdisplay(report)
|
||||
parsed = read_doc(source, informat)
|
||||
executed = run(parsed, report)
|
||||
popdisplay(report)
|
||||
formatted = format(executed, doctype)
|
||||
outname = "$(report.cwd)/$(report.basename).$(formatdict[:extension])"
|
||||
outname = "$(doc.cwd)/$(doc.basename).$(doc.format.formatdict[:extension])"
|
||||
open(outname, "w") do io
|
||||
write(io, join(formatted, "\n"))
|
||||
end
|
||||
|
||||
info("Report weaved to $(report.basename).$(formatdict[:extension])")
|
||||
|
||||
info("Report weaved to $(doc.basename).$(doc.format.formatdict[:extension])")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function run_block(code_str, report::Report)
|
||||
oldSTDOUT = STDOUT
|
||||
result = ""
|
||||
|
||||
rw, wr = redirect_stdout()
|
||||
#If there is nothing to read code will hang
|
||||
println()
|
||||
|
||||
try
|
||||
n = length(code_str)
|
||||
pos = 1 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(code_str, pos)
|
||||
s = eval(ReportSandBox, code)
|
||||
if rcParams[:plotlib] == "Gadfly"
|
||||
s != nothing && display(s)
|
||||
end
|
||||
end
|
||||
finally
|
||||
|
||||
redirect_stdout(oldSTDOUT)
|
||||
close(wr)
|
||||
result = readall(rw)
|
||||
close(rw)
|
||||
end
|
||||
|
||||
return string("\n", result)
|
||||
end
|
||||
|
||||
function run_term(code_str, report::Report)
|
||||
prompt = "\njulia> "
|
||||
codestart = "\n\n"*report.formatdict[:codestart]
|
||||
|
||||
if haskey(report.formatdict, :indent)
|
||||
prompt = indent(prompt, report.formatdict[:indent])
|
||||
end
|
||||
|
||||
#Emulate terminal
|
||||
n = length(code_str)
|
||||
pos = 2 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(code_str, pos)
|
||||
|
||||
report.term_state == :fig && (report.cur_result*= codestart)
|
||||
prompts = string(prompt, rstrip(code_str[oldpos:(pos-1)]), "\n")
|
||||
report.cur_result *= prompts
|
||||
report.term_state = :text
|
||||
s = eval(ReportSandBox, code)
|
||||
s != nothing && display(s)
|
||||
end
|
||||
|
||||
return string(report.cur_result)
|
||||
end
|
||||
|
||||
|
||||
function run(parsed, report::Report)
|
||||
#Clear sandbox for each document
|
||||
#Raises a warning, couldn't find a "cleaner"
|
||||
#way to do it.
|
||||
eval(parse("module ReportSandBox\nend"))
|
||||
executed = Any[]
|
||||
for chunk in copy(parsed)
|
||||
result_chunk = eval_chunk(chunk, report::Report)
|
||||
push!(executed, result_chunk)
|
||||
end
|
||||
executed
|
||||
end
|
||||
|
||||
function savefigs(chunk, report::Report)
|
||||
l_plotlib = lowercase(rcParams[:plotlib])
|
||||
if l_plotlib == "pyplot"
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
|
||||
type WeaveDoc
|
||||
source::String
|
||||
basename::String
|
||||
path::String
|
||||
chunks::Array
|
||||
cwd::String
|
||||
format
|
||||
function WeaveDoc(source, chunks)
|
||||
path, fname = splitdir(abspath(source))
|
||||
basename = splitext(fname)[1]
|
||||
new(source, basename, path, chunks, "", nothing)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
type CodeChunk
|
||||
content::String
|
||||
number::Int
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
#Format the executed document
|
||||
function format(executed, doctype)
|
||||
function format(doc::WeaveDoc)
|
||||
formatted = String[]
|
||||
docformat = formats[doctype]
|
||||
docformat = doc.format
|
||||
#@show docformat
|
||||
|
||||
#Complete format dictionaries with defaults
|
||||
|
@ -15,7 +14,7 @@ function format(executed, doctype)
|
|||
get!(formatdict, :fig_env, nothing)
|
||||
|
||||
|
||||
for chunk in copy(executed)
|
||||
for chunk in copy(doc.chunks)
|
||||
result = format_chunk(chunk, formatdict, docformat)
|
||||
push!(formatted, result)
|
||||
end
|
||||
|
|
|
@ -14,14 +14,15 @@ const input_formats = @compat Dict{String, Any}(
|
|||
|
||||
|
||||
@doc "Read and parse input document" ->
|
||||
function read_doc(document::String, format="noweb"::String)
|
||||
document = bytestring(open(document) do io
|
||||
mmap_array(Uint8,(filesize(document),),io)
|
||||
function read_doc(source::String, format="noweb"::String)
|
||||
document = bytestring(open(source) do io
|
||||
mmap_array(Uint8,(filesize(source),),io)
|
||||
end)
|
||||
return parse_doc(document, format)
|
||||
parsed = parse_doc(document, format)
|
||||
doc = WeaveDoc(source, parsed)
|
||||
end
|
||||
|
||||
@doc "Parse document from string" ->
|
||||
@doc "Parse chunks from string" ->
|
||||
function parse_doc(document::String, format="noweb"::String)
|
||||
#doctext = readall(open(document))
|
||||
lines = split(document, "\n")
|
||||
|
|
123
src/run.jl
123
src/run.jl
|
@ -1,3 +1,83 @@
|
|||
function run(doc::WeaveDoc; doctype = "pandoc", plotlib="Gadfly", informat="noweb", out_path=:doc, fig_path = "figures", fig_ext = nothing)
|
||||
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"))
|
||||
|
||||
init_plotting(plotlib)
|
||||
report = Report(doc.cwd, doc.basename, doc.format.formatdict)
|
||||
pushdisplay(report)
|
||||
|
||||
executed = Any[]
|
||||
for chunk in copy(doc.chunks)
|
||||
result_chunk = eval_chunk(chunk, report::Report)
|
||||
push!(executed, result_chunk)
|
||||
end
|
||||
popdisplay(report)
|
||||
|
||||
doc.chunks = executed
|
||||
return doc
|
||||
end
|
||||
|
||||
function run_block(code_str, report::Report)
|
||||
oldSTDOUT = STDOUT
|
||||
result = ""
|
||||
|
||||
rw, wr = redirect_stdout()
|
||||
#If there is nothing to read code will hang
|
||||
println()
|
||||
|
||||
try
|
||||
n = length(code_str)
|
||||
pos = 1 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(code_str, pos)
|
||||
s = eval(ReportSandBox, code)
|
||||
if rcParams[:plotlib] == "Gadfly"
|
||||
s != nothing && display(s)
|
||||
end
|
||||
end
|
||||
finally
|
||||
|
||||
redirect_stdout(oldSTDOUT)
|
||||
close(wr)
|
||||
result = readall(rw)
|
||||
close(rw)
|
||||
end
|
||||
|
||||
return string("\n", result)
|
||||
end
|
||||
|
||||
function run_term(code_str, report::Report)
|
||||
prompt = "\njulia> "
|
||||
codestart = "\n\n"*report.formatdict[:codestart]
|
||||
|
||||
if haskey(report.formatdict, :indent)
|
||||
prompt = indent(prompt, report.formatdict[:indent])
|
||||
end
|
||||
|
||||
#Emulate terminal
|
||||
n = length(code_str)
|
||||
pos = 2 #The first character is extra line end
|
||||
while pos < n
|
||||
oldpos = pos
|
||||
code, pos = parse(code_str, pos)
|
||||
|
||||
report.term_state == :fig && (report.cur_result*= codestart)
|
||||
prompts = string(prompt, rstrip(code_str[oldpos:(pos-1)]), "\n")
|
||||
report.cur_result *= prompts
|
||||
report.term_state = :text
|
||||
s = eval(ReportSandBox, code)
|
||||
s != nothing && display(s)
|
||||
end
|
||||
|
||||
return string(report.cur_result)
|
||||
end
|
||||
|
||||
function eval_chunk(chunk::CodeChunk, report::Report)
|
||||
info("Weaving chunk $(chunk.number) from line $(chunk.start_line)")
|
||||
|
@ -47,3 +127,46 @@ end
|
|||
function eval_chunk(chunk::DocChunk, report::Report)
|
||||
chunk
|
||||
end
|
||||
|
||||
function init_plotting(plotlib)
|
||||
if plotlib == nothing
|
||||
rcParams[:chunk_defaults][:fig] = false
|
||||
else
|
||||
l_plotlib = lowercase(plotlib)
|
||||
rcParams[:chunk_defaults][:fig] = true
|
||||
|
||||
if l_plotlib == "winston"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","winston.jl"))"""))
|
||||
rcParams[:plotlib] = "Winston"
|
||||
elseif l_plotlib == "pyplot"
|
||||
eval(Expr(:using, :PyPlot))
|
||||
rcParams[:plotlib] = "PyPlot"
|
||||
elseif l_plotlib == "gadfly"
|
||||
eval(parse("""include(Pkg.dir("Weave","src","gadfly.jl"))"""))
|
||||
rcParams[:plotlib] = "Gadfly"
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function get_cwd(doc::WeaveDoc, out_path)
|
||||
#Set the output directory
|
||||
if out_path == :doc
|
||||
cwd = doc.path
|
||||
elseif out_path == :pwd
|
||||
cwd = pwd()
|
||||
else
|
||||
cwd = out_path
|
||||
end
|
||||
return cwd
|
||||
end
|
||||
|
||||
function set_rc_params(formatdict, fig_path, fig_ext)
|
||||
if fig_ext == nothing
|
||||
rcParams[:chunk_defaults][:fig_ext] = formatdict[:fig_ext]
|
||||
else
|
||||
rcParams[:chunk_defaults][:fig_ext] = fig_ext
|
||||
end
|
||||
rcParams[:chunk_defaults][:fig_path] = fig_path
|
||||
return nothing
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue