From 97fe1a43bdf84b2729ac2fb4a34c438415c0b920 Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Sun, 11 Jan 2015 23:38:58 +0200 Subject: [PATCH] Capturing output now works with new options. Needs new tests and need to clean up obsolete code. Caching is broken --- src/Weave.jl | 13 +---- src/chunks.jl | 18 +++++- src/formatters.jl | 8 +-- src/gadfly.jl | 21 ++++--- src/readers.jl | 1 + src/run.jl | 140 +++++++++++++++++++++++++++++++++++++++++----- src/winston.jl | 16 +----- 7 files changed, 162 insertions(+), 55 deletions(-) diff --git a/src/Weave.jl b/src/Weave.jl index 252e13d..5ba6839 100644 --- a/src/Weave.jl +++ b/src/Weave.jl @@ -116,18 +116,9 @@ end function Base.display(report::Report, m::MIME"text/plain", data) - if report.term_state == :fig #Catch Winston plot command output - report.cur_result *= "\n" * report.formatdict[:codestart] * "\n" - end - s = reprmime(m, data) - haskey(report.formatdict, :indent) && (s = indent(s, report.formatdict[:indent])) - - report.cur_result *= s * "\n" - - if report.term_state == :fig #Catch Winston plot command output - report.cur_result *= "\n" * report.formatdict[:codeend] * "\n" - end + print("\n" * s) + #report.cur_result *= "\n" * s end function weave(doc::String, doctype::String) diff --git a/src/chunks.jl b/src/chunks.jl index 1fa9cc5..bcd7224 100644 --- a/src/chunks.jl +++ b/src/chunks.jl @@ -14,6 +14,12 @@ type WeaveDoc end end +immutable ChunkOutput + code::String + stdout::String + displayed::String + figures::Array{String} +end type CodeChunk content::String @@ -24,8 +30,9 @@ type CodeChunk options::Dict{Symbol, Any} output::String figures::Array{String} + result::Array{ChunkOutput} function CodeChunk(content, number, start_line, option_string, options) - new(content, number, 0, start_line, option_string, options, "", String[]) + new(content, number, 0, start_line, option_string, options, "", String[], ChunkOutput[]) end end @@ -34,3 +41,12 @@ type DocChunk number::Int start_line::Int end + +type TermResult +end + +type ScriptResult +end + +type CollectResult +end diff --git a/src/formatters.jl b/src/formatters.jl index ae38ff2..18876cb 100644 --- a/src/formatters.jl +++ b/src/formatters.jl @@ -66,9 +66,9 @@ function format_chunk(chunk::CodeChunk, formatdict, docformat) end if (strip(chunk.output)!= "") && (chunk.options[:results] != "hidden") - if chunk.options[:results] != "markup" + if chunk.options[:results] != "markup" && chunk.options[:results] != "hold" result *= "$(chunk.output)\n" - elseif chunk.options[:results] == "markup" + else if chunk.options[:wrap] chunk.output = "\n" * wraplines(chunk.output, chunk.options[:line_width]) @@ -95,8 +95,8 @@ end function format_termchunk(chunk, formatdict) if chunk.options[:echo] && chunk.options[:results] != "hidden" - result = "$(formatdict[:termstart])$(chunk.output)\n" - chunk.options[:term_state] == :text && (result*= "$(formatdict[:termend])\n") + result = "$(formatdict[:termstart])$(chunk.output)\n" * "$(formatdict[:termend])\n" + #chunk.options[:term_state] == :text && (result*= "$(formatdict[:termend])\n") else result = "" end diff --git a/src/gadfly.jl b/src/gadfly.jl index c2fda07..3131022 100644 --- a/src/gadfly.jl +++ b/src/gadfly.jl @@ -9,22 +9,21 @@ function Base.display(report::Report, m::MIME"image/png", p::Plot) full_name, rel_name = get_figname(report, chunk) docformat = formats[report.formatdict[:doctype]] - @show "Plotting" #Add to results for term chunks and store otherwise - if chunk.options[:term] - chunk.figures = [rel_name] + #if chunk.options[:term] + # chunk.figures = [rel_name] - if report.term_state == :text - report.cur_result *= "\n" * report.formatdict[:codeend] * "\n" - end + #if report.term_state == :text + # report.cur_result *= "\n" * report.formatdict[:codeend] * "\n" + #end - report.cur_result *= formatfigures(chunk, docformat) - report.term_state = :fig - chunk.figures = String[] - else + #report.cur_result *= formatfigures(chunk, docformat) + #report.term_state = :fig + # chunk.figures = String[] + #else push!(report.figures, rel_name) - end + #end report.fignum += 1 diff --git a/src/readers.jl b/src/readers.jl index 767f571..efd555c 100644 --- a/src/readers.jl +++ b/src/readers.jl @@ -57,6 +57,7 @@ function parse_doc(document::String, format="noweb"::String) end haskey(options, :label) && (options[:name] = options[:label]) haskey(options, :name) || (options[:name] = nothing) + #options = merge(rcParams[:chunk_defaults], options) #@show options chunk = DocChunk(content, docno, start_line) #chunk = @compat Dict{Symbol,Any}(:type => "doc", :content => content, diff --git a/src/run.jl b/src/run.jl index e84f217..a6e3b44 100644 --- a/src/run.jl +++ b/src/run.jl @@ -72,6 +72,7 @@ function Base.run(doc::WeaveDoc; doctype = "pandoc", plotlib="Gadfly", informat= end function run_chunk(chunk::CodeChunk, report::Report, SandBox::Module, cached, cache, idx) + #Defaults, already merged before, this merges format specific things options = merge(rcParams[:chunk_defaults], chunk.options) merge!(chunk.options, options) @@ -92,7 +93,24 @@ function reset_report(report::Report) report.term_state = :text end -using Gadfly #Remember to remove! +function run_code(chunk::CodeChunk, report::Report, SandBox::Module) + expressions = parse_input(chunk.content) + #@show expressions + result_no = 1 + results = ChunkOutput[ ] + + for (str_expr, expr) = expressions + reset_report(report) + (obj, out) = capture_output(expr, SandBox, chunk.options[:term], rcParams[:plotlib]) + displayed = report.cur_result #Not needed? + figures = report.figures #Captured figures + result = ChunkOutput(str_expr, out, displayed, figures) + push!(results, result) + end + return results +end + + function run_block(chunk::CodeChunk, report::Report, SandBox::Module) expressions = parse_input(chunk.content) #@show expressions @@ -102,11 +120,7 @@ function run_block(chunk::CodeChunk, report::Report, SandBox::Module) for (str_expr, expr) = expressions reset_report(report) (obj, out) = capture_output(expr, SandBox) - - - @show typeof(obj) if rcParams[:plotlib] == "Gadfly" && typeof(obj) == Gadfly.Plot - obj != nothing && display(obj) end @@ -116,7 +130,7 @@ function run_block(chunk::CodeChunk, report::Report, SandBox::Module) input *= str_expr else @show input - content = input * str_expr + content = "\n" * input * str_expr rchunk = CodeChunk(content, chunk.number, chunk.start_line, chunk.option_string, copy(chunk.options)) input = "" rchunk.result_no = result_no @@ -129,7 +143,40 @@ function run_block(chunk::CodeChunk, report::Report, SandBox::Module) return result_chunks end -function run_term(code_str, report::Report, SandBox::Module) + +function run_term(chunk::CodeChunk, report::Report, SandBox::Module) + expressions = parse_input(chunk.content) + #@show expressions + result_no = 1 + result_chunks = CodeChunk[ ] + output = "" + prompt = "\njulia> " + for (str_expr, expr) = expressions + reset_report(report) + (obj, out) = capture_output(expr, SandBox) + obj != nothing && display(obj) + displayed = report.cur_result #Catch output to text display + figures = report.figures #Captured figures + + if strip(out) == "" && isempty(figures) && displayed == "" + output *= prompt * str_expr + else + content = prompt * output * str_expr + rchunk = CodeChunk(content, chunk.number, chunk.start_line, chunk.option_string, copy(chunk.options)) + rchunk.output = content * out * displayed + @show rchunk.output + output = "" + rchunk.result_no = result_no + result_no *=1 + rchunk.figures = report.figures + push!(result_chunks, rchunk) + end + end + return result_chunks +end + + +function run_term2(code_str, report::Report, SandBox::Module) prompt = "\njulia> " codestart = "\n\n"*report.formatdict[:codestart] @@ -140,7 +187,7 @@ function run_term(code_str, report::Report, SandBox::Module) parsed = parse_input(code_str) #Emulate terminal n = length(parsed) - pos = 2 #The first character is extra line end + pos = 1 #The first character is extra line end while pos < n oldpos = pos code, pos = parse(code_str, pos) @@ -156,13 +203,18 @@ function run_term(code_str, report::Report, SandBox::Module) return string(report.cur_result) end -function capture_output(expr::Expr, SandBox::Module) +function capture_output(expr::Expr, SandBox::Module, term, plotlib) oldSTDOUT = STDOUT out = nothing obj = nothing rw, wr = redirect_stdout() try obj = eval(SandBox, expr) + if term + obj != nothing && display(obj) + elseif plotlib == "Gadfly" && typeof(obj) == Gadfly.Plot + obj != nothing && display(obj) + end finally redirect_stdout(oldSTDOUT) close(wr) @@ -203,12 +255,13 @@ function eval_chunk(chunk::CodeChunk, report::Report, SandBox::Module) chunk.options[:out_width] = report.formatdict[:out_width] end + chunk.result = run_code(chunk, report, SandBox) if chunk.options[:term] - chunk.output = run_term(chunk.content, report, SandBox) - chunk.options[:term_state] = report.term_state - chunks = [chunk] + chunks = collect_results(chunk, TermResult()) + elseif chunk.options[:results] == "hold" + chunks = collect_results(chunk, CollectResult()) else - chunks = run_block(chunk, report, SandBox) + chunks = collect_results(chunk, ScriptResult()) end #if rcParams[:plotlib] == "PyPlot" @@ -290,3 +343,64 @@ function set_rc_params(formatdict, fig_path, fig_ext) rcParams[:chunk_defaults][:fig_path] = fig_path return nothing end + +function collect_results(chunk::CodeChunk, fmt::ScriptResult) + content = "" + result_no = 1 + result_chunks = CodeChunk[ ] + for r =chunk.result + if strip(r.stdout) == "" && isempty(r.figures) && r.displayed == "" + content *= r.code + else + content = "\n" * content * r.code + rchunk = CodeChunk(content, chunk.number, chunk.start_line, chunk.option_string, copy(chunk.options)) + content = "" + rchunk.result_no = result_no + result_no *=1 + rchunk.figures = r.figures + rchunk.output = r.stdout * r.displayed + push!(result_chunks, rchunk) + end + end + if content != "" + rchunk = CodeChunk(content, chunk.number, chunk.start_line, chunk.option_string, copy(chunk.options)) + push!(result_chunks, rchunk) + end + + return result_chunks +end + +function collect_results(chunk::CodeChunk, fmt::TermResult) + output = "" + result_no = 1 + prompt = "\njulia> " + result_chunks = CodeChunk[ ] + for r =chunk.result + output *= prompt * r.code + output *= r.displayed * r.stdout + if !isempty(r.figures) + rchunk = CodeChunk("", chunk.number, chunk.start_line, chunk.option_string, copy(chunk.options)) + rchunk.output = output + output = "" + rchunk.figures = r.figures + push!(result_chunks, rchunk) + end + end + if output != "" + rchunk = CodeChunk("", chunk.number, chunk.start_line, chunk.option_string, copy(chunk.options)) + rchunk.output = output + push!(result_chunks, rchunk) + end + + return result_chunks +end + +function collect_results(chunk::CodeChunk, fmt::CollectResult) + result_no = 1 + for r =chunk.result + chunk.output *= r.stdout + chunk.figures = [chunk.figures, r.figures] + end + + return [chunk] +end diff --git a/src/winston.jl b/src/winston.jl index 622b76e..5ab59b9 100644 --- a/src/winston.jl +++ b/src/winston.jl @@ -6,21 +6,7 @@ function Base.display(report::Report, m::MIME"image/png", data) full_name, rel_name = get_figname(report, chunk) docformat = formats[report.formatdict[:doctype]] - - #Add to results for term chunks and store otherwise - if chunk.options[:term] - chunk.figures = [rel_name] - - if report.term_state == :text - report.cur_result *= "\n" * report.formatdict[:codeend] * "\n" - end - - report.cur_result *= formatfigures(chunk, docformat) - report.term_state = :fig - chunk.figures = String[] - else - push!(report.figures, rel_name) - end + push!(report.figures, rel_name) vector_fmts = [".pdf", ".svg"]