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
examples/*/*.png
examples/figures/
examples/*.md
examples/*.pdf
examples/*.html
tmp/
.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:
<<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)))
xlabel("x")
ylabel("sinc(x)")

Binary file not shown.

View File

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

View File

@ -1,25 +1,70 @@
const rcParams =
@compat Dict{Symbol,Any}(:figdir=> "figures",
@compat Dict{Symbol,Any}(
:plotlib => "PyPlot",
:storeresults=> false,
:cachedir=> "cache",
:chunk=>
Dict{Symbol,Any}(:defaultoptions=>
Dict{Symbol,Any}(:echo=> true,
:results=> "verbatim",
:storeresults => false,
:chunk_defaults => Dict{Symbol,Any}(:echo=> true,
:results=> "markup",
:fig=> true,
:include=> true,
:evaluate=> true,
:caption=> false,
:eval => true,
: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,
:name=> nothing,
:wrap=> true,
:f_pos=> "htpb",
:f_size=> (8, 6),
:f_env=> nothing,
:f_spines=> true,
:complete=> true,
:fig_pos=> nothing,
:fig_env=> nothing,
:engine=> "julia",
: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[]
docformat = formats[doctype]
#@show docformat
#Complete format dictionaries with defaults
formatdict = docformat.formatdict
get!(formatdict, :termstart, formatdict[:codestart])
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)
if chunk[:type] == "doc"
push!(formatted, chunk[:content])
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
result = format_codechunk(chunk, formatdict)
@ -34,7 +46,7 @@ end
function format_codechunk(chunk, formatdict)
if !chunk[:evaluate]
if !chunk[:eval]
if chunk[:echo]
result = "$(formatdict[:codestart])$(chunk[:content])$(formatdict[:codeend])"
return result
@ -59,10 +71,10 @@ function format_codechunk(chunk, formatdict)
if (strip(chunk[:result])!= "") && (chunk[:results] != "hidden")
#@show chunk
if chunk[:results] != "verbatim"
if chunk[:results] != "markup"
haskey(formatdict, :indent) && (chunk[:result] = indent(chunk[:result]))
result *= "$(chunk[:result])"
elseif chunk[:results] == "verbatim"
elseif chunk[:results] == "markup"
result *= "$(formatdict[:outputstart])$(chunk[:result])\n$(formatdict[:outputend])\n"
end
end
@ -98,9 +110,11 @@ const tex = Tex(@compat Dict{Symbol,Any}(:codestart => "\\begin{juliacode}",
:codeend => "\\end{juliacode}",
:outputstart => "\\begin{juliaout}",
:outputend => "\\end{juliaout}",
:figfmt => ".pdf",
:fig_ext => ".pdf",
:extension =>"tex",
:width => "\\linewidth",
:out_width=> "\\linewidth",
:fig_env=> "figure",
:fig_pos => "htpb",
:doctype => "tex"
))
@ -110,9 +124,11 @@ const texminted = Tex(@compat Dict{Symbol,Any}(:codestart => "\\begin{minted}[ma
:outputend => "\\end{minted}",
:termstart=> "\\begin{minted}[fontsize=\\footnotesize, xleftmargin=0.5em, mathescape]{julia}",
:termend => "\\end{minted}",
:figfmt => ".pdf",
:fig_ext => ".pdf",
:extension =>"tex",
:width => "\\linewidth",
:out_width => "\\linewidth",
:fig_env=> "figure",
:fig_pos => "htpb",
:doctype => "texminted"
))
@ -124,19 +140,20 @@ const pandoc = Pandoc(@compat Dict{Symbol,Any}(:codestart => "~~~~{.julia}",
:codeend=>"~~~~~~~~~~~~~\n\n",
:outputstart=>"~~~~{.julia}",
:outputend=>"~~~~~~~~~~~~~\n\n",
:figfmt=>".png",
:fig_ext=>".png",
:extension=>"md",
:width=>"15 cm",
:doctype=>"pandoc"
))
function formatfigures(chunk, docformat::Tex)
fignames = chunk[:figure]
caption = chunk[:caption]
width = get!(chunk, :width, docformat.formatdict[:width])
f_pos = chunk[:f_pos]
f_env = chunk[:f_env]
caption = chunk[:fig_cap]
width = chunk[:out_width]
f_pos = chunk[:fig_pos]
f_env = chunk[:fig_env]
result = ""
figstring = ""
@ -144,6 +161,7 @@ function formatfigures(chunk, docformat::Tex)
result *= """\\begin{$f_env}\n"""
end
for fig = fignames
figstring *= "\\includegraphics[width= $width]{$fig}\n"
end
@ -172,8 +190,7 @@ end
function formatfigures(chunk, docformat::Pandoc)
fignames = chunk[:figure]
caption = chunk[:caption]
width = get!(chunk, :width, docformat.formatdict[:width])
caption = chunk[:fig_cap]
result = ""
figstring = ""

View File

@ -3,8 +3,14 @@ using Gadfly
Gadfly.set_default_plot_format(:png)
#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
if chunk[:fig_ext] != ".png"
chunk[:fig_ext]
warn("Saving figures as .png with Gadfly")
end
full_name, rel_name = get_figname(report, chunk)
docformat = formats[report.formatdict[:doctype]]
@ -21,7 +27,11 @@ function display(report::Report, m::MIME"image/png", data)
end
report.fignum += 1
out = open(full_name, "w")
writemime(out, m, data)
close(out)
#TODO other formats
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

View File

@ -1,6 +1,6 @@
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
full_name, rel_name = get_figname(report, chunk)
@ -19,7 +19,7 @@ function display(report::Report, m::MIME"image/png", data)
end
#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
#out = open(full_name, "w")
#writemime(out, m, data)