Changed chunk options to follow Knitr's naming

* Implemented dpi and fig_witdth and fig_height for Gadfly and Winston
pull/17/head
Matti Pastell 2014-12-04 21:54:56 +02:00
parent 60b29e751e
commit e20025315d
8 changed files with 142 additions and 66 deletions

6
.gitignore vendored
View File

@ -1,8 +1,12 @@
test.jl test.jl
examples/*/*.png examples/figures/
examples/*.md examples/*.md
examples/*.pdf
examples/*.html examples/*.html
tmp/ tmp/
.idea .idea
*.*~ *.*~
*.aux
*.log
*.out

View File

@ -33,7 +33,7 @@ p = plot(t, sinc(t))
You can also include a plot with caption and hide the code: You can also include a plot with caption and hide the code:
<<echo=false; caption="Random walk."; label="random">>= <<echo=false; caption="Random walk."; label="random"; fig_width=8; fig_height=4>>=
p = plot(cumsum(randn(1000, 1))) p = plot(cumsum(randn(1000, 1)))
xlabel("x") xlabel("x")
ylabel("sinc(x)") ylabel("sinc(x)")

Binary file not shown.

View File

@ -1,6 +1,5 @@
module JuliaReport module JuliaReport
using Compat using Compat
import Base: display, writemime
#Contains report global properties #Contains report global properties
type Report <: Display type Report <: Display
@ -10,15 +9,13 @@ type Report <: Display
basename::String basename::String
formatdict formatdict
pending_code::String pending_code::String
figdir::String
executed::Array
cur_result::String cur_result::String
fignum::Int fignum::Int
figures::Array figures::Array
cur_chunk::Dict cur_chunk::Dict
function Report() function Report()
new("", false, "", "", Any[], "", "", Any[], "", 1, Any[], @compat Dict{Symbol, Any}()) new("", false, "", "", Any[], "", "", 1, Any[], @compat Dict{Symbol, Any}())
end end
end end
@ -29,7 +26,7 @@ const supported_mime_types =
[MIME"image/png", [MIME"image/png",
MIME"text/plain"] MIME"text/plain"]
function display(doc::Report, data) function Base.display(doc::Report, data)
for m in supported_mime_types for m in supported_mime_types
if mimewritable(m(), data) if mimewritable(m(), data)
display(doc, m(), data) display(doc, m(), data)
@ -48,23 +45,25 @@ module ReportSandBox
end end
function weave(source ; doctype = "pandoc", plotlib="PyPlot", informat="noweb", figdir = "figures", figformat = nothing) function weave(source ; doctype = "pandoc", plotlib="PyPlot", informat="noweb", fig_path = "figures", fig_ext = nothing)
cwd, fname = splitdir(abspath(source)) cwd, fname = splitdir(abspath(source))
basename = splitext(fname)[1] basename = splitext(fname)[1]
formatdict = formats[doctype].formatdict formatdict = formats[doctype].formatdict
figformat == nothing || (formatdict[:figfmt] = figformat) fig_ext == nothing || (rcParams[:chunk_defaults][:fig_ext] = fig_ext)
#report = Report(source, false, cwd, basename, formatdict, "", figdir) #report = Report(source, false, cwd, basename, formatdict, "", figdir)
report.source = source report.source = source
report.cwd = cwd report.cwd = cwd
report.basename = basename report.basename = basename
report.figdir = figdir rcParams[:chunk_defaults][:fig_path] = fig_path
report.formatdict = formatdict report.formatdict = formatdict
if plotlib == nothing if plotlib == nothing
rcParams[:chunk][:defaultoptions][:fig] = false rcParams[:chunk_defaults][:fig] = false
else else
l_plotlib = lowercase(plotlib) l_plotlib = lowercase(plotlib)
if l_plotlib == "winston" if l_plotlib == "winston"
@ -76,6 +75,10 @@ function weave(source ; doctype = "pandoc", plotlib="PyPlot", informat="noweb",
elseif l_plotlib == "gadfly" elseif l_plotlib == "gadfly"
eval(parse("""include(Pkg.dir("JuliaReport","src","gadfly.jl"))""")) eval(parse("""include(Pkg.dir("JuliaReport","src","gadfly.jl"))"""))
rcParams[:plotlib] = "Gadfly" rcParams[:plotlib] = "Gadfly"
if rcParams[:chunk_defaults][:fig_ext] != ".png"
rcParams[:chunk_defaults][:fig_ext] = ".png"
warn("Saving figures as .png with Gadfly")
end
end end
end end
@ -152,19 +155,19 @@ function run(parsed)
if chunk[:type] == "code" if chunk[:type] == "code"
#print(chunk["content"]) #print(chunk["content"])
info("Weaving chunk $(chunk[:number]) from line $(chunk[:start_line])") info("Weaving chunk $(chunk[:number]) from line $(chunk[:start_line])")
defaults = copy(rcParams[:chunk][:defaultoptions]) defaults = copy(rcParams[:chunk_defaults])
options = copy(chunk[:options]) options = copy(chunk[:options])
try try
options = merge(rcParams[:chunk][:defaultoptions], options) options = merge(rcParams[:chunk_defaults], options)
catch catch
options = rcParams[:chunk][:defaultoptions] options = rcParams[:chunk_defaults]
warn("Invalid format for chunk options line: $(chunk[:start_line])") warn("Invalid format for chunk options line: $(chunk[:start_line])")
end end
merge!(chunk, options) merge!(chunk, options)
delete!(chunk, :options) delete!(chunk, :options)
chunk[:evaluate] || (chunk[:result] = ""; continue) #Do nothing if eval is false chunk[:eval] || (chunk[:result] = ""; continue) #Do nothing if eval is false
report.fignum = 1 report.fignum = 1
report.cur_result = "" report.cur_result = ""
@ -197,15 +200,14 @@ end
function savefigs_pyplot(chunk) function savefigs_pyplot(chunk)
fignames = String[] fignames = String[]
ext = report.formatdict[:figfmt] ext = report.formatdict[:fig_ext]
figpath = joinpath(report.cwd, report.figdir) figpath = joinpath(report.cwd, chunk[:fig_path])
isdir(figpath) || mkdir(figpath) isdir(figpath) || mkdir(figpath)
chunkid = (chunk[:name] == nothing) ? chunk[:number] : chunk[:name] chunkid = (chunk[:name] == nothing) ? chunk[:number] : chunk[:name]
#Iterate over all open figures, save them and store names #Iterate over all open figures, save them and store names
for fig = plt.get_fignums() for fig = plt.get_fignums()
full_name = joinpath(report.cwd, report.figdir, "$(report.basename)_$(chunkid)_$fig$ext") full_name, rel_name = get_figname(report, chunk, fignum=fig)
rel_name = "$(report.figdir)/$(report.basename)_$(chunkid)_$fig$ext" #Relative path is used in output savefig(full_name, dpi=chunk[:dpi])
savefig(full_name)
push!(fignames, rel_name) push!(fignames, rel_name)
plt.draw() plt.draw()
plt.close() plt.close()
@ -215,22 +217,20 @@ end
function display(report::Report, m::MIME"text/plain", data) function Base.display(report::Report, m::MIME"text/plain", data)
s = reprmime(m, data) s = reprmime(m, data)
report.cur_result *= s report.cur_result *= s
push!(report.executed, s)
end end
function get_figname(report::Report, chunk) function get_figname(report::Report, chunk; fignum = nothing)
figpath = joinpath(report.cwd, report.figdir) figpath = joinpath(report.cwd, chunk[:fig_path])
isdir(figpath) || mkdir(figpath) isdir(figpath) || mkdir(figpath)
ext = report.formatdict[:figfmt] ext = chunk[:fig_ext]
fig = report.fignum fignum == nothing && (fignum = report.fignum)
chunk = report.cur_chunk
chunkid = (chunk[:name] == nothing) ? chunk[:number] : chunk[:name]
full_name = joinpath(report.cwd, report.figdir, "$(report.basename)_$(chunkid)_$fig$ext")
rel_name = "$(report.figdir)/$(report.basename)_$(chunkid)_$fig$ext" #Relative path is used in output
chunkid = (chunk[:name] == nothing) ? chunk[:number] : chunk[:name]
full_name = joinpath(report.cwd, chunk[:fig_path], "$(report.basename)_$(chunkid)_$(fignum)$ext")
rel_name = "$(chunk[:fig_path])/$(report.basename)_$(chunkid)_$(fignum)$ext" #Relative path is used in output
return full_name, rel_name return full_name, rel_name
end end

View File

@ -1,25 +1,70 @@
const rcParams = const rcParams =
@compat Dict{Symbol,Any}(:figdir=> "figures", @compat Dict{Symbol,Any}(
:plotlib => "PyPlot", :plotlib => "PyPlot",
:storeresults=> false, :storeresults => false,
:cachedir=> "cache", :chunk_defaults => Dict{Symbol,Any}(:echo=> true,
:chunk=> :results=> "markup",
Dict{Symbol,Any}(:defaultoptions=>
Dict{Symbol,Any}(:echo=> true,
:results=> "verbatim",
:fig=> true, :fig=> true,
:include=> true, :include=> true,
:evaluate=> true, :eval => true,
:caption=> false, :fig_cap=> false,
:fig_width => 8, #Size in inches
:fig_height => 6,
:fig_path=> "figures",
:out_width=> nothing, #Defined separately for each format
:out_height=> nothing,
:fig_ext => ".png",
:dpi => 200,
:term=> false, :term=> false,
:name=> nothing, :name=> nothing,
:wrap=> true, :wrap=> true,
:f_pos=> "htpb", :fig_pos=> nothing,
:f_size=> (8, 6), :fig_env=> nothing,
:f_env=> nothing,
:f_spines=> true,
:complete=> true,
:engine=> "julia", :engine=> "julia",
:option_string=> "") :option_string=> "")
) )
)
# Working towards Knitr compatible options, implemented options are added to defaultoptions dictionary above
# and work in progress stays here, options from https://github.com/yihui/knitr/blob/master/R/defaults.R
# If you need a particular options, consider implementing it and making a pull request.
#tidy = FALSE,
#tidy.opts = NULL,
#collapse = FALSE
#prompt = FALSE
#highlight = TRUE
#strip.white = TRUE
#size = 'normalsize'
#background = '#F7F7F7',
#cache = FALSE
#cache.path = 'cache/'
#cache.vars = NULL
#cache.lazy = TRUE,
#dependson = NULL
#autodep = FALSE,
#fig.keep = 'high'
#fig.show = 'asis'
#fig.align = 'default'
#dev = NULL
#dev.args = NULL
#fig.ext = NULL
#fig.scap = NULL
#fig.lp = 'fig:'
#fig.subcap = NULL,
#out.extra = NULL
#fig.retina = 1,
#external = TRUE
#sanitize = FALSE
#interval = 1
#aniopts = 'controls,loop',
#warning = TRUE
#error = TRUE
#message = TRUE,
#render = NULL,
#ref.label = NULL
#child = NULL
#split = FALSE
#purl = TRUE

View File

@ -5,15 +5,27 @@ function format(executed, doctype)
formatted = String[] formatted = String[]
docformat = formats[doctype] docformat = formats[doctype]
#@show docformat #@show docformat
#Complete format dictionaries with defaults
formatdict = docformat.formatdict formatdict = docformat.formatdict
get!(formatdict, :termstart, formatdict[:codestart]) get!(formatdict, :termstart, formatdict[:codestart])
get!(formatdict, :termend, formatdict[:codeend]) get!(formatdict, :termend, formatdict[:codeend])
get!(formatdict, :out_width, nothing)
get!(formatdict, :out_height, nothing)
get!(formatdict, :fig_pos, nothing)
get!(formatdict, :fig_env, nothing)
for chunk in copy(executed) for chunk in copy(executed)
if chunk[:type] == "doc" if chunk[:type] == "doc"
push!(formatted, chunk[:content]) push!(formatted, chunk[:content])
else else
#Fill undefined options with format specific defaults
chunk[:out_width] == nothing && (chunk[:out_width] = docformat.formatdict[:out_width])
chunk[:fig_env] == nothing && (chunk[:fig_env] = docformat.formatdict[:fig_env])
chunk[:fig_pos] == nothing && (chunk[:fig_pos] = docformat.formatdict[:fig_pos])
#Format code #Format code
result = format_codechunk(chunk, formatdict) result = format_codechunk(chunk, formatdict)
@ -34,7 +46,7 @@ end
function format_codechunk(chunk, formatdict) function format_codechunk(chunk, formatdict)
if !chunk[:evaluate] if !chunk[:eval]
if chunk[:echo] if chunk[:echo]
result = "$(formatdict[:codestart])$(chunk[:content])$(formatdict[:codeend])" result = "$(formatdict[:codestart])$(chunk[:content])$(formatdict[:codeend])"
return result return result
@ -59,10 +71,10 @@ function format_codechunk(chunk, formatdict)
if (strip(chunk[:result])!= "") && (chunk[:results] != "hidden") if (strip(chunk[:result])!= "") && (chunk[:results] != "hidden")
#@show chunk #@show chunk
if chunk[:results] != "verbatim" if chunk[:results] != "markup"
haskey(formatdict, :indent) && (chunk[:result] = indent(chunk[:result])) haskey(formatdict, :indent) && (chunk[:result] = indent(chunk[:result]))
result *= "$(chunk[:result])" result *= "$(chunk[:result])"
elseif chunk[:results] == "verbatim" elseif chunk[:results] == "markup"
result *= "$(formatdict[:outputstart])$(chunk[:result])\n$(formatdict[:outputend])\n" result *= "$(formatdict[:outputstart])$(chunk[:result])\n$(formatdict[:outputend])\n"
end end
end end
@ -98,9 +110,11 @@ const tex = Tex(@compat Dict{Symbol,Any}(:codestart => "\\begin{juliacode}",
:codeend => "\\end{juliacode}", :codeend => "\\end{juliacode}",
:outputstart => "\\begin{juliaout}", :outputstart => "\\begin{juliaout}",
:outputend => "\\end{juliaout}", :outputend => "\\end{juliaout}",
:figfmt => ".pdf", :fig_ext => ".pdf",
:extension =>"tex", :extension =>"tex",
:width => "\\linewidth", :out_width=> "\\linewidth",
:fig_env=> "figure",
:fig_pos => "htpb",
:doctype => "tex" :doctype => "tex"
)) ))
@ -110,9 +124,11 @@ const texminted = Tex(@compat Dict{Symbol,Any}(:codestart => "\\begin{minted}[ma
:outputend => "\\end{minted}", :outputend => "\\end{minted}",
:termstart=> "\\begin{minted}[fontsize=\\footnotesize, xleftmargin=0.5em, mathescape]{julia}", :termstart=> "\\begin{minted}[fontsize=\\footnotesize, xleftmargin=0.5em, mathescape]{julia}",
:termend => "\\end{minted}", :termend => "\\end{minted}",
:figfmt => ".pdf", :fig_ext => ".pdf",
:extension =>"tex", :extension =>"tex",
:width => "\\linewidth", :out_width => "\\linewidth",
:fig_env=> "figure",
:fig_pos => "htpb",
:doctype => "texminted" :doctype => "texminted"
)) ))
@ -124,19 +140,20 @@ const pandoc = Pandoc(@compat Dict{Symbol,Any}(:codestart => "~~~~{.julia}",
:codeend=>"~~~~~~~~~~~~~\n\n", :codeend=>"~~~~~~~~~~~~~\n\n",
:outputstart=>"~~~~{.julia}", :outputstart=>"~~~~{.julia}",
:outputend=>"~~~~~~~~~~~~~\n\n", :outputend=>"~~~~~~~~~~~~~\n\n",
:figfmt=>".png", :fig_ext=>".png",
:extension=>"md", :extension=>"md",
:width=>"15 cm",
:doctype=>"pandoc" :doctype=>"pandoc"
)) ))
function formatfigures(chunk, docformat::Tex) function formatfigures(chunk, docformat::Tex)
fignames = chunk[:figure] fignames = chunk[:figure]
caption = chunk[:caption] caption = chunk[:fig_cap]
width = get!(chunk, :width, docformat.formatdict[:width]) width = chunk[:out_width]
f_pos = chunk[:f_pos]
f_env = chunk[:f_env]
f_pos = chunk[:fig_pos]
f_env = chunk[:fig_env]
result = "" result = ""
figstring = "" figstring = ""
@ -144,6 +161,7 @@ function formatfigures(chunk, docformat::Tex)
result *= """\\begin{$f_env}\n""" result *= """\\begin{$f_env}\n"""
end end
for fig = fignames for fig = fignames
figstring *= "\\includegraphics[width= $width]{$fig}\n" figstring *= "\\includegraphics[width= $width]{$fig}\n"
end end
@ -172,8 +190,7 @@ end
function formatfigures(chunk, docformat::Pandoc) function formatfigures(chunk, docformat::Pandoc)
fignames = chunk[:figure] fignames = chunk[:figure]
caption = chunk[:caption] caption = chunk[:fig_cap]
width = get!(chunk, :width, docformat.formatdict[:width])
result = "" result = ""
figstring = "" figstring = ""

View File

@ -3,8 +3,14 @@ using Gadfly
Gadfly.set_default_plot_format(:png) Gadfly.set_default_plot_format(:png)
#Captures figures #Captures figures
function display(report::Report, m::MIME"image/png", data) function Base.display(report::Report, m::MIME"image/png", p::Plot)
chunk = report.cur_chunk chunk = report.cur_chunk
if chunk[:fig_ext] != ".png"
chunk[:fig_ext]
warn("Saving figures as .png with Gadfly")
end
full_name, rel_name = get_figname(report, chunk) full_name, rel_name = get_figname(report, chunk)
docformat = formats[report.formatdict[:doctype]] docformat = formats[report.formatdict[:doctype]]
@ -21,7 +27,11 @@ function display(report::Report, m::MIME"image/png", data)
end end
report.fignum += 1 report.fignum += 1
out = open(full_name, "w")
writemime(out, m, data) #TODO other formats
close(out) r = chunk[:dpi]/96 #Relative to Gadfly default 96dpi
draw(PNG(full_name, chunk[:fig_width]inch*r, chunk[:fig_height]inch*r ), p)
#out = open(full_name, "w")
#writemime(out, m, data)
#close(out)
end end

View File

@ -1,6 +1,6 @@
using Winston using Winston
function display(report::Report, m::MIME"image/png", data) function Base.display(report::Report, m::MIME"image/png", data)
chunk = report.cur_chunk chunk = report.cur_chunk
full_name, rel_name = get_figname(report, chunk) full_name, rel_name = get_figname(report, chunk)
@ -19,7 +19,7 @@ function display(report::Report, m::MIME"image/png", data)
end end
#TODO get width and height from chunk options, after implementing Knitr compatible options #TODO get width and height from chunk options, after implementing Knitr compatible options
savefig(data, full_name, width=2000, height=800) savefig(data, full_name, width=chunk[:fig_width]*chunk[:dpi], height=chunk[:fig_height]*chunk[:dpi])
report.fignum += 1 report.fignum += 1
#out = open(full_name, "w") #out = open(full_name, "w")
#writemime(out, m, data) #writemime(out, m, data)