First version

pull/1/head
Matti Pastell 2014-11-24 23:10:48 +00:00
parent bcff343feb
commit 2d58c8eb61
3 changed files with 203 additions and 2 deletions

View File

@ -1,3 +1,32 @@
# JuliaReport
[![Build Status](https://travis-ci.org/mpastell/JuliaReport.jl.svg?branch=master)](https://travis-ci.org/mpastell/JuliaReport.jl)
JuliaReport is a scientific report generator/literate programming tool
for Julia. It is based on [Pweave](http://mpastell.com/pweave) and
resembles Knitr and Sweave. Actually JuliaReport relies on Pweave for
document parsing and formatting.
**Current features**
* Pweave Noweb or script syntax for documents.
* Execute code as terminal or "script" chunks.
* Capture PyPlot figures.
* All Pweave output formats supported. Including, Latex, Markdown, Sphinx etc.
**Not implemented**
* Inline code
* Caching
## Usage
Run from julia:
using JuliaReport
weave("examples/julia_sample.mdw")

40
examples/julia_sample.mdw Normal file
View File

@ -0,0 +1,40 @@
# Introducion to JuliaReport
This a sample [Julia](http://julialang.org/) noweb document that can
be executed using JuliaReport. Output from code chunks and PyPlot
plots will be included in the weaved document. You also need to install Pweave from Github in order to use JuliaReport.
This documented can be turned into Pandoc markdown with captured
result from Julia prompt.
~~~~{.julia}
using JuliaReport
weave("examples/julia_sample.mdw")
~~~~
## Terminal chunk
<<term=True>>=
x = 1:10
d = {"juliareport" => "testing"}
y = [2, 4 ,8]
@
## Capturing figures
The figures and code can be included in the output.
<<>>=
using PyPlot
t = linspace(0, 2*pi, 100)
plot(t, sinc(t))
xlabel("x")
ylabel("sinc(x)")
@
You can also include a plot with caption and hide the code:
<<echo=False, caption="Random walk.", label="random">>=
plot(cumsum(randn(1000, 1)))
@

View File

@ -1,5 +1,137 @@
module JuliaReport
using PyCall
using PyPlot
# package code goes here
#Parsing and formatting uses Pweave
@pyimport pweave
end # module
#Contains report global properties
#Similar to pweave.PwebProcessor
type Report
source::String
documentationmode::Bool
cwd::String
basename::String
formatdict
pending_code::String
figdir::String
end
global report = Report("", false, "", "", {}, "", "")
function listformats()
pweave.listformats()
end
function weave(source ; doctype = "pandoc", informat="noweb", figdir = "figures", figformat = nothing)
pweave.rcParams["chunk"]["defaultoptions"]["engine"] = "julia"
doc = pweave.Pweb(source, doctype, shell="julia")
doc[:setreader](informat)
doc[:parse]()
#Julia version of doc.run()
cwd, fname = splitdir(abspath(source))
basename = splitext(fname)[1]
formatdict = doc[:formatter][:getformatdict]()
figformat == nothing || (formatdict["figfmt"] = figformat)
#println(formatdict["figfmt"])
global report = Report(source, false, cwd, basename, formatdict, "", figdir)
#Formatting with pweave
doc[:executed] = run(PyVector(doc["parsed"]))
doc[:isexecuted] = true
doc[:format]()
doc[:write]()
end
function run_block(code_str)
oldSTDOUT = STDOUT
#If there is nothing to read code will hang
println()
rw, wr = redirect_stdout()
include_string(code_str)
redirect_stdout(oldSTDOUT)
close(wr)
result = readall(rw)
close(rw)
return string("\n", result)
end
function run_term(code_str)
oldSTDOUT = STDOUT
#If there is nothing to read code will hang
println()
rw, wr = redirect_stdout()
#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)
println(string("\njulia> ", rstrip(code_str[oldpos:(pos-1)])))
s = eval(code)
s == nothing || (smime = reprmime(MIME("text/plain"), s)) #display(s)
println(smime)
end
redirect_stdout(oldSTDOUT)
close(wr)
result = readall(rw)
close(rw)
return string(result)
end
function run(parsed)
i = 1
for chunk = copy(parsed)
if chunk["type"] == "code"
#print(chunk["content"])
info("""Weaving chunk $(chunk["number"]) from line $(chunk["start_line"])""")
defaults = copy(pweave.rcParams["chunk"]["defaultoptions"])
merge!(defaults, chunk["options"])
merge!(chunk, defaults)
chunk["evaluate"] || (chunk["result"] = ""; continue) #Do nothing if eval is false
if chunk["term"]
chunk["result"] = run_term(chunk["content"])
else
chunk["result"] = run_block(chunk["content"])
end
chunk["fig"] && (chunk["figure"] = savefigs(chunk))
end
parsed[i] = copy(chunk)
i += 1
end
return parsed
end
function savefigs(chunk)
fignames = String[]
ext = report.formatdict["figfmt"]
figpath = joinpath(report.cwd, report.figdir)
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)
push!(fignames, rel_name)
plt.draw()
plt.close()
end
return fignames
end
export weave
end