Merge branch 'master' into texpipeline

texpipeline
Shuhei Kadowaki 2020-06-14 13:36:18 +09:00
commit 5ae1fd5cf1
59 changed files with 262 additions and 1044 deletions

67
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,67 @@
# TODO: build docs via github-actions
name: CI
on:
push:
branches:
- master
pull_request:
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.allow-failure }}
strategy:
fail-fast: false # don't stop CI even when one of them fails
matrix:
version:
- '1.4'
os:
- ubuntu-latest
- macOS-latest
# - windows-latest # TODO: test on Windows
arch:
- x64
- x86
allow-failure: [false]
include:
# this is so verbose... any other way to simplify this ?
- version: 'nightly'
os: ubuntu-latest
arch: x64
allow-failure: true
- version: 'nightly'
os: ubuntu-latest
arch: x86
allow-failure: true
- version: 'nightly'
os: macOS-latest
arch: x64
allow-failure: true
# - version: 'nightly'
# os: windows-latest
# arch: x64
# allow-failure: true
# - version: 'nightly'
# os: windows-latest
# arch: x86
# allow-failure: true
exclude:
- os: macOS-latest
arch: x86
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/julia-buildpkg@latest
- uses: julia-actions/julia-runtest@latest
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
file: ./lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}

9
.gitignore vendored
View File

@ -1,6 +1,5 @@
Manifest.toml
src/*.cov
test.jl
examples/figures/ examples/figures/
examples/*.md examples/*.md
examples/*.pdf examples/*.pdf
@ -22,15 +21,9 @@ test/**/*.ipynb
doc/build doc/build
doc/site doc/site
stable/
doc/Manifest.toml
Manifest.toml
tmp/
.idea .idea
*.*~ *.*~
*.aux *.aux
*.log *.log
*.out *.out
\#*\#
.juliahistory

View File

@ -1,19 +1,6 @@
language: julia language: julia
julia:
- 1 # current stable
- nightly
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia --check-bounds=yes -e 'using Pkg; Pkg.build()'
- xvfb-run julia -e 'using Pkg; Pkg.test("Weave", coverage=true)'
after_success:
- julia -e 'using Pkg; cd(Pkg.dir("Weave")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
jobs: jobs:
allow_failures:
- julia: nightly
include: include:
- stage: "Documentation" - stage: "Documentation"
julia: 1 julia: 1

View File

@ -26,13 +26,10 @@ YAML = "0.3, 0.4"
julia = "1.2" julia = "1.2"
[extras] [extras]
Cairo = "159f3aea-2a34-519c-b102-8c37f9878175"
Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Gadfly = "c91e804a-d5a3-530f-b6f0-dfbca275c004" Gadfly = "c91e804a-d5a3-530f-b6f0-dfbca275c004"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[targets] [targets]
test = ["Cairo", "Conda", "DataFrames", "Gadfly", "IJulia", "Plots", "Test"] test = ["DataFrames", "Test"]

View File

@ -1,12 +1,12 @@
# Weave # Weave
[![Build Status](https://travis-ci.org/JunoLab/Weave.jl.svg?branch=master)](https://travis-ci.org/JunoLab/Weave.jl) ![CI](https://github.com/JunoLab/Weave.jl/workflows/CI/badge.svg)
[![codecov](https://codecov.io/gh/JunoLab/Weave.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JunoLab/Weave.jl)
[![](https://img.shields.io/badge/docs-stable-blue.svg)](http://weavejl.mpastell.com/stable/) [![](https://img.shields.io/badge/docs-stable-blue.svg)](http://weavejl.mpastell.com/stable/)
[![](https://img.shields.io/badge/docs-dev-blue.svg)](http://weavejl.mpastell.com/dev/) [![](https://img.shields.io/badge/docs-dev-blue.svg)](http://weavejl.mpastell.com/dev/)
[![](http://joss.theoj.org/papers/10.21105/joss.00204/status.svg)](http://dx.doi.org/10.21105/joss.00204) [![](http://joss.theoj.org/papers/10.21105/joss.00204/status.svg)](http://dx.doi.org/10.21105/joss.00204)
Weave is a scientific report generator/literate programming tool Weave is a scientific report generator/literate programming tool for the [Julia programming language](https://julialang.org/).
for Julia.
It resembles It resembles
[Pweave](http://mpastell.com/pweave), [Pweave](http://mpastell.com/pweave),
[knitr](https://yihui.org/knitr/), [knitr](https://yihui.org/knitr/),

View File

@ -33,6 +33,7 @@ we've mostly followed [RMarkdown's namings](http://yihui.name/knitr/options), bu
### Evaluation ### Evaluation
- `eval = true`: Evaluate the code chunk. If `false` the chunk wont be executed. - `eval = true`: Evaluate the code chunk. If `false` the chunk wont be executed.
- `error = true`: If `true` [`weave`](@ref) won't stop on errors and rather they will be included in output document. If `false`, [`weave`](@ref) will halt on any of un-caught errors.
- `cache = false`: Cache results, depending on `cache` parameter on [`weave`](@ref) function. - `cache = false`: Cache results, depending on `cache` parameter on [`weave`](@ref) function.
- `tangle = true`: Set tangle to `false` to exclude chunk from tangled code. - `tangle = true`: Set tangle to `false` to exclude chunk from tangled code.

View File

@ -41,8 +41,8 @@ e.g.: `weave("FIR_design_plots.jl", template = "custom.tpl"`.
As starting point, you can use the existing templates: As starting point, you can use the existing templates:
- HTML (`md2html`): [`md2html.tpl`](https://github.com/mpastell/Weave.jl/blob/master/templates/md2html.tpl) - HTML (`md2html`): [`md2html.tpl`](https://github.com/JunoLab/Weave.jl/blob/master/templates/md2html.tpl)
- LaTex (`md2pdf`): [`md2pdf.tpl`](https://github.com/mpastell/Weave.jl/blob/master/templates/md2pdf.tpl) - LaTex (`md2pdf`): [`md2pdf.tpl`](https://github.com/JunoLab/Weave.jl/blob/master/templates/md2pdf.tpl)
Templates are rendered using [Mustache.jl](https://github.com/jverzani/Mustache.jl). Templates are rendered using [Mustache.jl](https://github.com/jverzani/Mustache.jl).

View File

@ -152,8 +152,8 @@ Weave will remove the first empty space from each line of documentation.
!!! tip !!! tip
- Here are sample documents: - Here are sample documents:
+ [markdown format](https://github.com/mpastell/Weave.jl/blob/master/examples/FIR_design.jmd) + [markdown format](https://github.com/JunoLab/Weave.jl/blob/master/examples/FIR_design.jmd)
+ [script format](https://github.com/mpastell/Weave.jl/blob/master/examples/FIR_design.jl) + [script format](https://github.com/JunoLab/Weave.jl/blob/master/examples/FIR_design.jl)
- [Details about chunk options](@ref chunk-options) - [Details about chunk options](@ref chunk-options)

View File

@ -7,7 +7,7 @@
#' # Introduction #' # Introduction
#' This an example of a julia script that can be published using #' This an example of a julia script that can be published using
#' [Weave](http://mpastell.github.io/Weave.jl/latest/usage/). #' [Weave](http://weavejl.mpastell.com/dev/usage/).
#' The script can be executed normally using Julia #' The script can be executed normally using Julia
#' or published to HTML or pdf with Weave. #' or published to HTML or pdf with Weave.
#' Text is written in markdown in lines starting with "`#'` " and code #' Text is written in markdown in lines starting with "`#'` " and code

View File

@ -9,7 +9,7 @@ date: 21th April 2016
This an example of a julia script that can be published using This an example of a julia script that can be published using
[Weave](http://mpastell.github.io/Weave.jl/latest/usage/). [Weave](http://weavejl.mpastell.com/dev/usage/).
The script can be executed normally using Julia The script can be executed normally using Julia
or published to HTML or pdf with Weave. or published to HTML or pdf with Weave.
Text is written in markdown in lines starting with "`#'` " and code Text is written in markdown in lines starting with "`#'` " and code

View File

@ -7,7 +7,7 @@
#' # Introduction #' # Introduction
#' This an example of a julia script that can be published using #' This an example of a julia script that can be published using
#' [Weave](http://mpastell.github.io/Weave.jl/latest/usage/). #' [Weave](http://weavejl.mpastell.com/dev/usage/).
#' The script can be executed normally using Julia #' The script can be executed normally using Julia
#' or published to HTML or pdf with Weave. #' or published to HTML or pdf with Weave.
#' Text is written in markdown in lines starting with "`#'` " and code #' Text is written in markdown in lines starting with "`#'` " and code

View File

@ -7,7 +7,7 @@ date : 13th December 2016
# Intro # Intro
This a sample [Julia](http://julialang.org/) markdown document that can This a sample [Julia](http://julialang.org/) markdown document that can
be executed using [Weave.jl](https://github.com/mpastell/Weave.jl). be executed using [Weave.jl](https://github.com/JunoLab/Weave.jl).
The code is delimited from docs using markdown fenced code blocks The code is delimited from docs using markdown fenced code blocks
markup which can be seen looking at the source document markup which can be seen looking at the source document
@ -71,6 +71,6 @@ plot(y = cumsum(randn(1000, 1)), Geom.line)
Read the documentation: Read the documentation:
- stable: [http://mpastell.github.io/Weave.jl/stable/](http://mpastell.github.io/Weave.jl/stable/) - stable: [http://mpastell.github.io/Weave.jl/stable/](http://mpastell.github.io/Weave.jl/stable/)
- latest: [http://mpastell.github.io/Weave.jl/latest/](http://mpastell.github.io/Weave.jl/latest/) - latest: [http://weavejl.mpastell.com/dev/](http://weavejl.mpastell.com/dev/)
See other examples in the [GitHub repo](https://github.com/mpastell/Weave.jl/tree/master/examples) See other examples in the [GitHub repo](https://github.com/JunoLab/Weave.jl/tree/master/examples)

View File

@ -29,10 +29,10 @@
\section{Intro} \section{Intro}
This is a minimal example on using PGF format with Gadfly plots in This is a minimal example on using PGF format with Gadfly plots in
\href{https://github.com/mpastell/Weave.jl}{Weave.jl} document. \href{https://github.com/JunoLab/Weave.jl}{Weave.jl} document.
The source is in github: The source is in github:
\url{https://github.com/mpastell/Weave.jl/blob/master/examples/gadfly_pgf.texw}. \url{https://github.com/JunoLab/Weave.jl/blob/master/examples/gadfly_pgf.texw}.
You can run this example with first weaving it from Julia using: You can run this example with first weaving it from Julia using:

View File

@ -5,7 +5,7 @@
# Introduction # Introduction
This a sample [Julia](http://julialang.org/) noweb document that can This a sample [Julia](http://julialang.org/) noweb document that can
be executed using [Weave.jl](https://github.com/mpastell/Weave.jl). be executed using [Weave.jl](https://github.com/JunoLab/Weave.jl).
The code is delimited from docs using `<<>>=` and `@` markup which can be seen The code is delimited from docs using `<<>>=` and `@` markup which can be seen
looking at the source document `gadfly_sample.mdw` in the examples directory looking at the source document `gadfly_sample.mdw` in the examples directory
@ -65,6 +65,6 @@ plot(y = cumsum(randn(1000, 1)), Geom.line)
Read the documentation: Read the documentation:
- stable: <http://mpastell.github.io/Weave.jl/stable/> - stable: <http://mpastell.github.io/Weave.jl/stable/>
- latest: <http://mpastell.github.io/Weave.jl/latest/> - latest: <http://weavejl.mpastell.com/dev/>
See other examples in: <https://github.com/mpastell/Weave.jl/tree/master/examples> See other examples in: <https://github.com/JunoLab/Weave.jl/tree/master/examples>

View File

@ -30,6 +30,7 @@ end
# utilitity functions # utilitity functions
take2string!(io) = String(take!(io)) take2string!(io) = String(take!(io))
joinlines(lines) = join(lines, '\n')
""" """
list_out_formats() list_out_formats()
@ -96,7 +97,6 @@ Weave an input document to output file.
* `:all` caches everything * `:all` caches everything
* `:user` caches based on chunk options * `:user` caches based on chunk options
* `:refresh` runs all code chunks and save new cache * `:refresh` runs all code chunks and save new cache
- `throw_errors::Bool = false`: If `false` errors are included in output document and the whole document is executed. If `true` errors are thrown when they occur
- `template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing`: Template (file path) or `Mustache.MustacheTokens`s for `md2html` or `md2tex` formats - `template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing`: Template (file path) or `Mustache.MustacheTokens`s for `md2html` or `md2tex` formats
- `css::Union{Nothing,AbstractString} = nothing`: Path of a CSS file used for md2html format - `css::Union{Nothing,AbstractString} = nothing`: Path of a CSS file used for md2html format
- `highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing`: Theme used for syntax highlighting (defaults to `Highlights.Themes.DefaultTheme`) - `highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing`: Theme used for syntax highlighting (defaults to `Highlights.Themes.DefaultTheme`)
@ -118,7 +118,6 @@ function weave(
fig_ext::Union{Nothing,AbstractString} = nothing, fig_ext::Union{Nothing,AbstractString} = nothing,
cache_path::AbstractString = "cache", cache_path::AbstractString = "cache",
cache::Symbol = :off, cache::Symbol = :off,
throw_errors::Bool = false,
template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing, template::Union{Nothing,AbstractString,Mustache.MustacheTokens} = nothing,
css::Union{Nothing,AbstractString} = nothing, # TODO: rename to `stylesheet` css::Union{Nothing,AbstractString} = nothing, # TODO: rename to `stylesheet`
highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing, highlight_theme::Union{Nothing,Type{<:Highlights.AbstractTheme}} = nothing,
@ -158,7 +157,6 @@ function weave(
fig_ext = get(weave_options, "fig_ext", fig_ext) fig_ext = get(weave_options, "fig_ext", fig_ext)
cache_path = get(weave_options, "cache_path", cache_path) cache_path = get(weave_options, "cache_path", cache_path)
cache = Symbol(get(weave_options, "cache", cache)) cache = Symbol(get(weave_options, "cache", cache))
throw_errors = get(weave_options, "throw_errors", throw_errors)
end end
doc = run_doc( doc = run_doc(
@ -171,7 +169,6 @@ function weave(
fig_ext = fig_ext, fig_ext = fig_ext,
cache_path = cache_path, cache_path = cache_path,
cache = cache, cache = cache,
throw_errors = throw_errors,
) )
# render document # render document
@ -221,7 +218,7 @@ function weave(
rm(intermediate) rm(intermediate)
elseif doctype == "md2pdf" elseif doctype == "md2pdf"
run_latex(doc, out_path, latex_cmd) run_latex(doc, out_path, latex_cmd)
out_path = get_out_path(doc, out_path, ext = "pdf") out_path = get_out_path(doc, out_path, "pdf")
end end
@info "Weaved to $(out_path)" @info "Weaved to $(out_path)"
@ -263,7 +260,7 @@ using [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
!!! warning !!! warning
The code is _**not**_ executed by Weave, but by [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/). The code is _**not**_ executed by Weave, but by [`nbconvert`](https://nbconvert.readthedocs.io/en/latest/).
This means that the output doesn't necessarily always work properly; see [#116](https://github.com/mpastell/Weave.jl/issues/116). This means that the output doesn't necessarily always work properly; see [#116](https://github.com/JunoLab/Weave.jl/issues/116).
!!! note !!! note
In order to _just_ convert Weave document to Jupyter Notebook, In order to _just_ convert Weave document to Jupyter Notebook,
@ -321,18 +318,6 @@ end
include_weave(source, informat = nothing) = include_weave(Main, source, informat) include_weave(source, informat = nothing) = include_weave(Main, source, informat)
# Hooks to run before and after chunks, this is form IJulia,
# but note that Weave hooks take the chunk as input
const preexecute_hooks = Function[]
push_preexecute_hook(f::Function) = push!(preexecute_hooks, f)
pop_preexecute_hook(f::Function) =
splice!(preexecute_hooks, findfirst(x -> x == f, preexecute_hooks))
const postexecute_hooks = Function[]
push_postexecute_hook(f::Function) = push!(postexecute_hooks, f)
pop_postexecute_hook(f::Function) =
splice!(postexecute_hooks, findfirst(x -> x == f, postexecute_hooks))
include("types.jl") include("types.jl")
include("config.jl") include("config.jl")
include("WeaveMarkdown/markdown.jl") include("WeaveMarkdown/markdown.jl")

View File

@ -1,10 +1,11 @@
# TODO: follow RMarkdown convention more
const _DEFAULT_PARAMS = Dict{Symbol,Any}( const _DEFAULT_PARAMS = Dict{Symbol,Any}(
:echo => true, :echo => true,
:results => "markup", :results => "markup",
:hold => false, :hold => false,
:fig => true, :fig => true,
:include => true,
:eval => true, :eval => true,
:error => true,
:tangle => true, :tangle => true,
:cache => false, :cache => false,
:fig_cap => nothing, :fig_cap => nothing,
@ -14,11 +15,10 @@ const _DEFAULT_PARAMS = Dict{Symbol,Any}(
:fig_path => DEFAULT_FIG_PATH, :fig_path => DEFAULT_FIG_PATH,
:dpi => 96, :dpi => 96,
:term => false, :term => false,
:prompt => "\njulia> ", :prompt => "julia>",
:label => nothing, :label => nothing,
:wrap => true, :wrap => true,
:line_width => 75, :line_width => 75,
:engine => "julia",
:fig_ext => nothing, :fig_ext => nothing,
:fig_pos => nothing, :fig_pos => nothing,
:fig_env => nothing, :fig_env => nothing,

View File

@ -2,34 +2,20 @@ using Markdown, .WeaveMarkdown
# Contains report global properties # Contains report global properties
mutable struct Report <: AbstractDisplay mutable struct Report <: AbstractDisplay
cwd::AbstractString cwd::String
basename::AbstractString basename::String
format::WeaveFormat format::WeaveFormat
rich_output::AbstractString rich_output::String
fignum::Int fignum::Int
figures::Vector{String} figures::Vector{String}
cur_chunk::Any cur_chunk::Union{Nothing,CodeChunk}
mimetypes::Array{AbstractString} mimetypes::Vector{String}
first_plot::Bool first_plot::Bool
header_script::String header_script::String
throw_errors::Bool
end end
function Report(cwd, basename, format, mimetypes, throw_errors) Report(cwd, basename, format, mimetypes) =
Report( Report(cwd, basename, format, "", 1, String[], nothing, mimetypes, true, "")
cwd,
basename,
format,
"",
1,
String[],
nothing,
mimetypes,
true,
"",
throw_errors,
)
end
# Default mimetypes in order, can be overridden for some inside `run method` formats # Default mimetypes in order, can be overridden for some inside `run method` formats
const default_mime_types = ["image/svg+xml", "image/png", "text/html", "text/plain"] const default_mime_types = ["image/svg+xml", "image/png", "text/html", "text/plain"]

View File

@ -4,14 +4,13 @@ using Base64, ..Plots, ..Weave
# Pre-execute hooks to set the plot size for the chunk # Pre-execute hooks to set the plot size for the chunk
function plots_set_size(chunk) function plots_set_size!(chunk)
w = chunk.options[:fig_width] * chunk.options[:dpi] w = chunk.options[:fig_width] * chunk.options[:dpi]
h = chunk.options[:fig_height] * chunk.options[:dpi] h = chunk.options[:fig_height] * chunk.options[:dpi]
Plots.default(size = (w, h)) Plots.default(size = (w, h))
return chunk
end end
Weave.push_preexecute_hook(plots_set_size) Weave.push_preexecution_hook!(plots_set_size!)
# PNG or SVG is not working, output html # PNG or SVG is not working, output html
function Base.display( function Base.display(

View File

@ -91,9 +91,7 @@ function format_chunk(chunk::CodeChunk, docformat)
# Handle figures # Handle figures
if chunk.options[:fig] && length(chunk.figures) > 0 if chunk.options[:fig] && length(chunk.figures) > 0
if chunk.options[:include] result *= formatfigures(chunk, docformat)
result *= formatfigures(chunk, docformat)
end
end end
return result return result

View File

@ -13,7 +13,6 @@ function run_doc(
fig_ext::Union{Nothing,AbstractString} = nothing, fig_ext::Union{Nothing,AbstractString} = nothing,
cache_path::AbstractString = "cache", cache_path::AbstractString = "cache",
cache::Symbol = :off, cache::Symbol = :off,
throw_errors::Bool = false,
) )
# cache :all, :user, :off, :refresh # cache :all, :user, :off, :refresh
@ -43,7 +42,7 @@ function run_doc(
mimetypes = doc.format.mimetypes mimetypes = doc.format.mimetypes
report = Report(cwd, doc.basename, doc.format, mimetypes, throw_errors) report = Report(cwd, doc.basename, doc.format, mimetypes)
cd_back = let d = pwd(); () -> cd(d); end cd_back = let d = pwd(); () -> cd(d); end
cd(cwd) cd(cwd)
pushdisplay(report) pushdisplay(report)
@ -193,58 +192,43 @@ function run_inline(inline::InlineCode, doc::WeaveDoc, report::Report, mod::Modu
return inline return inline
end end
reset_report(report::Report) = report.figures = String[]
function run_code(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module) function run_code(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module)
ss = parse_input(chunk.content) code = chunk.content
n = length(ss) path = doc.path
results = ChunkOutput[] error = chunk.options[:error]
for (i, s) in enumerate(ss) codes = chunk.options[:term] ? split_code(code) : [code]
reset_report(report) capture = code -> capture_output(code, mod, path, error, report)
obj, out = capture_output( return capture.(codes)
mod,
s,
doc.path,
chunk.options[:term],
i == n,
report.throw_errors,
)
figures = report.figures # Captured figures
result = ChunkOutput(s, out, report.rich_output, figures)
report.rich_output = ""
push!(results, result)
end
return results
end end
# Parse chunk input to array of expressions function split_code(code)
function parse_input(s)
res = String[] res = String[]
s = lstrip(s) e = 1
n = sizeof(s) ex = :init
pos = 1 while true
while (oldpos = pos) n s = e
_, pos = Meta.parse(s, pos) ex, e = Meta.parse(code, s)
push!(res, s[oldpos:pos-1]) isnothing(ex) && break
push!(res, strip(code[s:e-1]))
end end
return res return res
end end
function capture_output(mod, s, path, term, lastline, throw_errors = false) function capture_output(code, mod, path, error, report)
local out = nothing reset_report!(report)
local obj = nothing
old = stdout old = stdout
rw, wr = redirect_stdout() rw, wr = redirect_stdout()
reader = @async read(rw, String) reader = @async read(rw, String)
local out = nothing
task_local_storage(:SOURCE_PATH, path) do task_local_storage(:SOURCE_PATH, path) do
try try
obj = include_string(mod, s, path) # TODO: fix line number obj = include_string(mod, code, path) # TODO: fix line number
!isnothing(obj) && (term || lastline) && display(obj) !isnothing(obj) && display(obj)
catch _err catch _err
err = unwrap_load_err(_err) err = unwrap_load_err(_err)
throw_errors && throw(err) error || throw(err)
display(err) display(err)
@warn "ERROR: $(typeof(err)) occurred, including output in Weaved document" @warn "ERROR: $(typeof(err)) occurred, including output in Weaved document"
finally finally
@ -255,13 +239,20 @@ function capture_output(mod, s, path, term, lastline, throw_errors = false)
end end
end end
out = replace(out, r"\u001b\[.*?m" => "") # remove ANSI color codes return ChunkOutput(code, remove_ansi_control_chars(out), report.rich_output, report.figures)
return (obj, out) end
function reset_report!(report)
report.rich_output = ""
report.figures = String[]
end end
unwrap_load_err(err) = return err unwrap_load_err(err) = return err
unwrap_load_err(err::LoadError) = return err.error unwrap_load_err(err::LoadError) = return err.error
# https://stackoverflow.com/a/33925425/12113178
remove_ansi_control_chars(s) = replace(s, r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]" => "")
function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module) function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module)
if !chunk.options[:eval] if !chunk.options[:eval]
chunk.output = "" chunk.output = ""
@ -269,10 +260,7 @@ function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module
return chunk return chunk
end end
# Run preexecute_hooks execute_prehooks!(chunk)
for hook in preexecute_hooks
chunk = Base.invokelatest(hook, chunk)
end
report.fignum = 1 report.fignum = 1
report.cur_chunk = chunk report.cur_chunk = chunk
@ -283,10 +271,7 @@ function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module
chunk.result = run_code(doc, chunk, report, mod) chunk.result = run_code(doc, chunk, report, mod)
# Run post_execute chunks execute_posthooks!(chunk)
for hook in postexecute_hooks
chunk = Base.invokelatest(hook, chunk)
end
chunks = if chunk.options[:term] chunks = if chunk.options[:term]
collect_term_results(chunk) collect_term_results(chunk)
@ -296,13 +281,28 @@ function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module
collect_results(chunk) collect_results(chunk)
end end
# else
# chunk.options[:fig] && (chunk.figures = copy(report.figures))
# end
return chunks return chunks
end end
# Hooks to run before and after chunks, this is form IJulia,
const preexecution_hooks = Function[]
push_preexecution_hook!(f::Function) = push!(preexecution_hooks, f)
function pop_preexecution_hook!(f::Function)
i = findfirst(x -> x == f, preexecution_hooks)
isnothing(i) && error("this function has not been registered in the pre-execution hook yet")
return splice!(preexecution_hooks, i)
end
execute_prehooks!(chunk::CodeChunk) = for prehook in preexecution_hooks; Base.invokelatest(prehook, chunk); end
const postexecution_hooks = Function[]
push_postexecution_hook!(f::Function) = push!(postexecution_hooks, f)
function pop_postexecution_hook!(f::Function)
i = findfirst(x -> x == f, postexecution_hooks)
isnothing(i) && error("this function has not been registered in the post-execution hook yet")
return splice!(postexecution_hooks, i)
end
execute_posthooks!(chunk::CodeChunk) = for posthook in postexecution_hooks; Base.invokelatest(posthook, chunk); end
""" """
clear_module!(mod::Module) clear_module!(mod::Module)
@ -391,7 +391,7 @@ function collect_term_results(chunk::CodeChunk)
prompt = chunk.options[:prompt] prompt = chunk.options[:prompt]
result_chunks = CodeChunk[] result_chunks = CodeChunk[]
for r in chunk.result for r in chunk.result
output *= string(prompt, r.code, r.stdout) output *= string('\n', indent_term_code(prompt, r.code), '\n', r.stdout)
if !isempty(r.figures) if !isempty(r.figures)
rchunk = CodeChunk( rchunk = CodeChunk(
"", "",
@ -421,6 +421,15 @@ function collect_term_results(chunk::CodeChunk)
return result_chunks return result_chunks
end end
function indent_term_code(prompt, code)
prompt_with_space = string(prompt, ' ')
n = length(prompt_with_space)
pads = ' ' ^ n
return map(enumerate(split(code, '\n'))) do (i,line)
isone(i) ? string(prompt_with_space, line) : string(pads, line)
end |> joinlines
end
function collect_hold_results(chunk::CodeChunk) function collect_hold_results(chunk::CodeChunk)
for r in chunk.result for r in chunk.result
chunk.output *= r.stdout chunk.output *= r.stdout

View File

@ -1,7 +1,4 @@
using Weave # Test if running document with and without cache works
using Test
#Test if running document with and without cache works
isdir("documents/cache") && rm("documents/cache", recursive = true) isdir("documents/cache") && rm("documents/cache", recursive = true)
weave("documents/chunk_options.noweb", cache=:all) weave("documents/chunk_options.noweb", cache=:all)
result = read("documents/chunk_options.md", String) result = read("documents/chunk_options.md", String)

View File

@ -1,18 +0,0 @@
~~~~{.julia}
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
~~~~~~~~~~~~~
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.js.svg){#fig:sin_fun}
![cos(x) function.](figures/gadfly_formats_test_2_1.js.svg)
~~~~{.julia}
plot(x=x, y = cos.(2x), Geom.line)
~~~~~~~~~~~~~
![](figures/gadfly_formats_test_cos2_fun_1.js.svg){width=15cm #fig:cos2_fun}\

View File

@ -1,17 +0,0 @@
````julia
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
````
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.pdf)
![cos(x) function.](figures/gadfly_formats_test_2_1.pdf)
````julia
plot(x=x, y = cos.(2x), Geom.line)
````
![](figures/gadfly_formats_test_cos2_fun_1.pdf)

View File

@ -1,17 +0,0 @@
````julia
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
````
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.png)
![cos(x) function.](figures/gadfly_formats_test_2_1.png)
````julia
plot(x=x, y = cos.(2x), Geom.line)
````
![](figures/gadfly_formats_test_cos2_fun_1.png)

View File

@ -1,18 +0,0 @@
~~~~{.julia}
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
~~~~~~~~~~~~~
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.png){#fig:sin_fun}
![cos(x) function.](figures/gadfly_formats_test_2_1.png)
~~~~{.julia}
plot(x=x, y = cos.(2x), Geom.line)
~~~~~~~~~~~~~
![](figures/gadfly_formats_test_cos2_fun_1.png){width=15cm #fig:cos2_fun}\

View File

@ -1,17 +0,0 @@
````julia
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
````
![sin(x) function.](figures/gadfly_formats_test_sin_fun_1.svg)
![cos(x) function.](figures/gadfly_formats_test_2_1.svg)
````julia
plot(x=x, y = cos.(2x), Geom.line)
````
![](figures/gadfly_formats_test_cos2_fun_1.svg)

View File

@ -1,22 +0,0 @@
\begin{juliacode}
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
\end{juliacode}
\begin{figure}[ht]
\center
\includegraphics[width=\linewidth]{figures/gadfly_formats_test_sin_fun_1.pdf}
\caption{sin(x) function.}
\label{fig:sin_fun}
\end{figure}
\begin{figure}[htpb]
\center
\includegraphics[width=\linewidth]{figures/gadfly_formats_test_2_1.pdf}
\caption{cos(x) function.}
\end{figure}
\begin{juliacode}
plot(x=x, y = cos.(2x), Geom.line)
\end{juliacode}
\includegraphics[width=15cm]{figures/gadfly_formats_test_cos2_fun_1.pdf}

View File

@ -1,22 +0,0 @@
\begin{juliacode}
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
\end{juliacode}
\begin{figure}[ht]
\center
\includegraphics[width=\linewidth]{figures/gadfly_formats_test_sin_fun_1.png}
\caption{sin(x) function.}
\label{fig:sin_fun}
\end{figure}
\begin{figure}[htpb]
\center
\includegraphics[width=\linewidth]{figures/gadfly_formats_test_2_1.png}
\caption{cos(x) function.}
\end{figure}
\begin{juliacode}
plot(x=x, y = cos.(2x), Geom.line)
\end{juliacode}
\includegraphics[width=15cm]{figures/gadfly_formats_test_cos2_fun_1.png}

View File

@ -1,22 +0,0 @@
\begin{juliacode}
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
\end{juliacode}
\begin{figure}[ht]
\center
\includegraphics[width=\linewidth]{figures/gadfly_formats_test_sin_fun_1.ps}
\caption{sin(x) function.}
\label{fig:sin_fun}
\end{figure}
\begin{figure}[htpb]
\center
\includegraphics[width=\linewidth]{figures/gadfly_formats_test_2_1.ps}
\caption{cos(x) function.}
\end{figure}
\begin{juliacode}
plot(x=x, y = cos.(2x), Geom.line)
\end{juliacode}
\includegraphics[width=15cm]{figures/gadfly_formats_test_cos2_fun_1.ps}

View File

@ -1,22 +0,0 @@
\begin{juliacode}
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
\end{juliacode}
\begin{figure}[ht]
\center
\resizebox{\linewidth}{!}{\input{figures/gadfly_formats_test_sin_fun_1.tex}}
\caption{sin(x) function.}
\label{fig:sin_fun}
\end{figure}
\begin{figure}[htpb]
\center
\resizebox{\linewidth}{!}{\input{figures/gadfly_formats_test_2_1.tex}}
\caption{cos(x) function.}
\end{figure}
\begin{juliacode}
plot(x=x, y = cos.(2x), Geom.line)
\end{juliacode}
\resizebox{15cm}{!}{\input{figures/gadfly_formats_test_cos2_fun_1.tex}}

View File

@ -1,19 +0,0 @@
---
weave_options:
out_path: gadfly
---
<<fig_cap="sin(x) function."; label="sin_fun"; fig_pos="ht">>=
using Gadfly
x = range(0, stop =2π, step=0.05)
plot(x=x, y = sin.(x), Geom.line)
@
<<echo=false; fig_cap="cos(x) function."; dpi=200>>=
plot(x=x, y = cos.(x), Geom.line)
@
<<label="cos2_fun"; out_width="15cm">>=
plot(x=x, y = cos.(2x), Geom.line)
@

View File

@ -1,12 +0,0 @@
# Gadfly
```{julia;fig_ext=".svg";dpi=300}
using Gadfly
x = collect(range(0, stop=2π, length=200))
plot(
layer(x=x, y = sin.(x), Geom.line),
layer(x=x, y = cos.(x), Geom.line, Theme(default_color=colorant"red")),
Guide.manual_color_key("Legend", ["sin", "cos"], ["deepskyblue", "red"])
)
```

View File

@ -1,22 +0,0 @@
<div class="Random plot">
<p>Some inline output</p>
<pre class='hljl'>
<span class='hljl-nf'>println</span><span class='hljl-p'>(</span><span class='hljl-s'>&quot;Testing output&quot;</span><span class='hljl-p'>)</span>
</pre>
<pre class="output">
Testing output
</pre>
</div>

View File

@ -1,22 +0,0 @@
\begin{frame}[fragile]
\frametitle{Random plot}
Some inline output
\begin{lstlisting}
(*@\HLJLnf{println}@*)(*@\HLJLp{(}@*)(*@\HLJLs{"{}Testing}@*) (*@\HLJLs{output"{}}@*)(*@\HLJLp{)}@*)
\end{lstlisting}
\begin{lstlisting}
Testing output
\end{lstlisting}
\end{frame}

View File

@ -1,17 +0,0 @@
Here's some text
And here's some code
```julia
x = 1
y = 2
@show x + y
```
Here's some more complicated code
```julia
@code_native +(1.0, π)
using Test
@test 1 == 1
```

View File

@ -1,31 +0,0 @@
---
title: A minimal beamer example using Weave markdown
author: Matti Pastell
weave_options:
out_path: inline
---
```julia; echo=false
struct Begin
text
title
end
struct End
text
end
Base.show(io::IO, m::MIME"text/latex", b::Begin) = write(io, "\\begin{$(b.text)}[fragile]\n\\frametitle{$(b.title)}\n")
Base.show(io::IO, m::MIME"text/latex", e::End) = write(io, "\\end{$(e.text)}")
Base.show(io::IO, m::MIME"text/html", b::Begin) = write(io, "<div class=\"$(b.title)\">\n")
Base.show(io::IO, m::MIME"text/html", e::End) = write(io, "</div>")
```
! Begin("frame", "Random plot")
Some inline `j print("output")`
```julia
println("Testing output")
```
! End("frame")

View File

@ -1,31 +0,0 @@
```julia
display("text/markdown",
"""
### Small markdown sample
**Hello** from `code` block.
""")
```
```julia
struct Dummy
s::String
end
function Base.show(io::IO, m::MIME"text/markdown", d::Dummy)
print(io, d.s)
end
Dummy("""
* one
* two
* three
""")
```

View File

@ -1,16 +0,0 @@
using Plots
pyplot()
x = range(0, stop=2*pi, length=50)
println(x)
p = plot(x = x, y = sin(x), size =(900,300))
plot(x = x, y = sin(x))
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
plot(y = cumsum(randn(1000, 1)))

View File

@ -1,60 +0,0 @@
~~~~{.julia}
using Plots
pyplot()
x = linspace(0, 2*pi)
println(x)
~~~~~~~~~~~~~
~~~~
linspace(0.0,6.283185307179586,50)
~~~~
~~~~{.julia}
p = plot(x, sin(x), size =(900,300))
~~~~~~~~~~~~~
~~~~{.julia}
julia> plot(x, sin(x))
~~~~~~~~~~~~~
![](figures/plotsjl_test_2_1.png)\
~~~~{.julia}
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
~~~~~~~~~~~~~
![](figures/plotsjl_test_3_1.png)\
~~~~{.julia}
julia> plot(rand(100) / 3,reg=true,fill=(0,:green))
~~~~~~~~~~~~~
![](figures/plotsjl_test_4_1.png)\
~~~~{.julia}
julia> scatter!(rand(100),markersize=6,c=:orange)
~~~~~~~~~~~~~
![](figures/plotsjl_test_4_2.png)\
![A random walk.](figures/plotsjl_test_random_1.png)

View File

@ -1,47 +0,0 @@
\begin{juliacode}
using Plots
pyplot()
x = linspace(0, 2*pi)
println(x)
\end{juliacode}
\begin{juliaout}
linspace(0.0,6.283185307179586,50)
\end{juliaout}
\begin{juliacode}
p = plot(x, sin(x), size =(900,300))
\end{juliacode}
\begin{juliaterm}
julia> plot(x, sin(x))
\end{juliaterm}
\includegraphics[width=\linewidth]{figures/plotsjl_test_2_1.pdf}
\begin{juliacode}
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
\end{juliacode}
\includegraphics[width=\linewidth]{figures/plotsjl_test_3_1.pdf}
\begin{juliaterm}
julia> plot(rand(100) / 3,reg=true,fill=(0,:green))
\end{juliaterm}
\includegraphics[width=\linewidth]{figures/plotsjl_test_4_1.pdf}
\begin{juliaterm}
julia> scatter!(rand(100),markersize=6,c=:orange)
\end{juliaterm}
\includegraphics[width=\linewidth]{figures/plotsjl_test_4_2.pdf}
\begin{figure}[htpb]
\center
\includegraphics[width=\linewidth]{figures/plotsjl_test_random_1.pdf}
\caption{A random walk.}
\label{fig:random}
\end{figure}

View File

@ -1,41 +0,0 @@
~~~~{.julia}
using Plots
gr()
x = range(0, stop=2π, length=50)
println(x)
~~~~~~~~~~~~~
~~~~
0.0:0.1282282715750936:6.283185307179586
~~~~
~~~~{.julia}
p = plot(x, sin.(x), size =(900,300))
p
~~~~~~~~~~~~~
![](figures/plotsjl_test_gr_1_1.png)\
~~~~{.julia}
plot(x, sin.(x))
~~~~~~~~~~~~~
![](figures/plotsjl_test_gr_2_1.png)\
~~~~{.julia}
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
~~~~~~~~~~~~~
![](figures/plotsjl_test_gr_3_1.png)\
![A random walk.](figures/plotsjl_test_gr_random_1.png){#fig:random}

View File

@ -1,33 +0,0 @@
\begin{juliacode}
using Plots
gr()
x = range(0, stop=2π, length=50)
println(x)
\end{juliacode}
\begin{juliaout}
0.0:0.1282282715750936:6.283185307179586
\end{juliaout}
\begin{juliacode}
p = plot(x, sin.(x), size =(900,300))
p
\end{juliacode}
\includegraphics[width=\linewidth]{figures/plotsjl_test_gr_1_1.pdf}
\begin{juliacode}
plot(x, sin.(x))
\end{juliacode}
\includegraphics[width=\linewidth]{figures/plotsjl_test_gr_2_1.pdf}
\begin{juliacode}
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
\end{juliacode}
\includegraphics[width=\linewidth]{figures/plotsjl_test_gr_3_1.pdf}
\begin{figure}[htpb]
\center
\includegraphics[width=\linewidth]{figures/plotsjl_test_gr_random_1.pdf}
\caption{A random walk.}
\label{fig:random}
\end{figure}

View File

@ -1,29 +0,0 @@
```julia
using Plots
pyplot()
x = linspace(0, 2*pi)
println(x)
p = plot(x, sin(x), size =(900,300))
```
```julia; term=true
plot(x, sin(x))
```
```julia
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
```
```julia; term=true
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
```
```{julia;echo=false; fig_cap="A random walk."; label="random"}
plot(cumsum(randn(1000, 1)))
```

View File

@ -1,25 +0,0 @@
```julia
using Plots
gr()
x = range(0, stop=2π, length=50)
println(x)
p = plot(x, sin.(x), size =(900,300))
p
```
```julia
plot(x, sin.(x))
```
```julia
plot(rand(100) / 3,reg=true,fill=(0,:green))
scatter!(rand(100),markersize=6,c=:orange)
```
```{julia;echo=false; fig_cap="A random walk."; label="random"}
plot(cumsum(randn(1000, 1), dims=1))
```

View File

@ -1,37 +0,0 @@
y= [2, 5, 12]
x = 1:10
d = Dict("Weave" => "testing")
y = [2, 4 ,8]
x = [12, 10]
println(y)
println(x)
println("Results without code")
println(x)
y = 1:5
println(y)
a = "Don't print me"
println(a)
println("No markup for results.")
println(collect(0:10:1000))
println(collect(0:10:1000))
println(collect(0:10:1000))

View File

@ -1,32 +0,0 @@
# NOTE
# this file keeps old end2end tests, which are very fragile
# - they are being gradually replaced with unit tests, that are much more maintainable and
# much more helpful for detecting bugs
# - the purpose of this file is to temporarily keep the old end2end tests in a way that
# they're allowed to fail
tpl = mt"""
{{{ :body }}}
"""
out = weave(joinpath(@__DIR__, "documents", "markdown_beamer.jmd"), doctype="md2html", template=tpl)
@test read(out, String) == read(out*".ref", String)
rm(out)
out = weave(joinpath(@__DIR__, "documents", "markdown_beamer.jmd"), doctype="md2tex", template=tpl)
@test read(out, String) == read(out*".ref", String)
rm(out)
@testset "chunk options" begin
result = read("documents/chunk_options.md", String)
ref = read("documents/chunk_options_ref.md", String)
@test result == ref
tangle("documents/chunk_options.noweb", out_path = "documents/tangle")
result = read("documents/tangle/chunk_options.jl", String)
ref = read("documents/tangle/chunk_options.jl.ref", String)
@test ref == result
end

View File

@ -1,85 +1,3 @@
# TODO: this test is horrible, refactor
using Weave: Highlights.Themes.DefaultTheme
# Test rendering of doc chunks
content = """
# Test chunk
Test rendering \$\alpha\$
"""
dchunk = Weave.DocChunk(content, 1, 1)
pformat = Weave.FORMATS["github"]
f = Weave.format_chunk(dchunk, pformat)
@test f == content
docformat = Weave.FORMATS["md2html"]
f_check = "<h1>Test chunk</h1>\n<p>Test rendering <span class=\"math\">\$\alpha\$</span></p>\n"
f = Weave.format_chunk(dchunk, docformat)
@test f_check == f
# Test with actual doc
parsed = Weave.WeaveDoc("documents/chunk_options.noweb")
doc = run_doc(parsed, doctype = "md2html")
c_check = "<pre class='hljl'>\n<span class='hljl-n'>x</span><span class='hljl-t'> </span><span class='hljl-oB'>=</span><span class='hljl-t'> </span><span class='hljl-p'>[</span><span class='hljl-ni'>12</span><span class='hljl-p'>,</span><span class='hljl-t'> </span><span class='hljl-ni'>10</span><span class='hljl-p'>]</span><span class='hljl-t'>\n</span><span class='hljl-nf'>println</span><span class='hljl-p'>(</span><span class='hljl-n'>y</span><span class='hljl-p'>)</span>\n</pre>\n"
doc.format.highlight_theme = DefaultTheme
c = Weave.format_code(doc.chunks[3].content, doc.format)
@test c_check == c
o_check = "\nprintln&#40;x&#41;\n"
o = Weave.format_output(doc.chunks[4].content, doc.format)
@test o_check == o
# Tex format
parsed = Weave.WeaveDoc("documents/chunk_options.noweb")
doc = run_doc(parsed, doctype = "md2tex")
c_check = "\\begin{lstlisting}\n(*@\\HLJLnf{println}@*)(*@\\HLJLp{(}@*)(*@\\HLJLn{x}@*)(*@\\HLJLp{)}@*)\n\\end{lstlisting}\n"
doc.format.highlight_theme = DefaultTheme
c = Weave.format_code(doc.chunks[4].content, doc.format)
@test c_check == c
o_check = "\nx = [12, 10]\nprintln(y)\n"
o = Weave.format_output(doc.chunks[3].content, doc.format)
@test o_check == o
# Test wrapping
cows = repeat("🐄", 100)
testcows = """
🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄
🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄🐄"""
wcows = Weave.wrapline(cows)
@test wcows == testcows
@test length(split(wcows, "\n")[1]) == 75
@test length(split(wcows, "\n")[2]) == 25
tfied = "\\ensuremath{\\bm{\\mathrm{L}}} \\ensuremath{\\bm{\\mathfrak{F}}} \\ensuremath{\\bm{\\iota}} \\ensuremath{\\mathfrak{A}} \\ensuremath{\\bm{\\varTheta}}"
@test Weave.uc2tex("𝐋 𝕱 𝛊 𝔄 𝚹") == tfied
# Test markdown output from chunks
parsed = Weave.WeaveDoc("documents/markdown_output.jmd")
doc = run_doc(parsed, doctype = "md2html")
@test doc.chunks[1].rich_output == "\n<div class=\"markdown\"><h3>Small markdown sample</h3>\n<p><strong>Hello</strong> from <code>code</code> block.</p>\n</div>"
@test doc.chunks[2].rich_output == "\n<div class=\"markdown\"><ul>\n<li><p>one</p>\n</li>\n<li><p>two</p>\n</li>\n<li><p>three</p>\n</li>\n</ul>\n</div>"
ldoc = run_doc(parsed, doctype = "md2tex")
@test ldoc.chunks[1].rich_output == "\n\\subsubsection{Small markdown sample}\n\\textbf{Hello} from \\texttt{code} block.\n\n"
@test ldoc.chunks[2].rich_output == "\n\\begin{itemize}\n\\item one\n\n\n\\item two\n\n\n\\item three\n\n\\end{itemize}\n"
mdoc = run_doc(parsed, doctype = "github")
@test mdoc.chunks[1].rich_output == "\n\n### Small markdown sample\n\n**Hello** from `code` block.\n\n"
@test mdoc.chunks[2].rich_output == "\n\n* one\n* two\n* three\n\n"
# Test disable escaping of unicode # Test disable escaping of unicode
@testset "escape/unescape unicode characters" begin @testset "escape/unescape unicode characters" begin

View File

@ -1,31 +0,0 @@
# Test for Gadfly with different chunk options and figure formatsusing Weave
using Gadfly, Cairo
function test_gadfly(doctype, fig_ext)
out = weave(
joinpath(@__DIR__ , "documents/gadfly_formats_test.jnw"),
doctype = doctype,
fig_ext = fig_ext
)
result = read(out, String)
# cp(out, out*fig_ext*"."*doctype, force=true) # Used when adding new tests
ref = read(out*fig_ext*"."*doctype, String)
@test result == ref
rm(out)
end
test_gadfly("github", ".png")
test_gadfly("github", ".pdf")
test_gadfly("github", ".svg")
test_gadfly("pandoc", ".png")
test_gadfly("pandoc", ".js.svg")
test_gadfly("tex", ".pdf")
test_gadfly("tex", ".png")
test_gadfly("tex", ".ps")
test_gadfly("tex", ".tex")
p = Gadfly.plot(x=1:10, y=1:10)
@test showable(MIME"application/pdf"(), p) == true
@test showable(MIME"application/png"(), p) == true

View File

@ -1,6 +1,9 @@
using Test # TODO: make this more sensible:
import Weave: WeaveMarkdown # - separate tests for
import Markdown # 1. features that are "copy-and-pasted" from `Markdown` module
# 2. features that are extended by Weave
using Weave: WeaveMarkdown, Markdown
# Test markdown2html writer # Test markdown2html writer

View File

@ -1,7 +0,0 @@
file = joinpath(@__DIR__, "documents", "jupyter_test.jmd")
using IJulia, Conda
Conda.add("nbconvert") # should be the same as IJulia.JUPYTER, i.e. the miniconda Python
Weave.notebook(file, jupyter_path = IJulia.JUPYTER)
@test "jupyter_test.ipynb" readdir(@__DIR__) # test if the result was weaved

View File

@ -1,22 +0,0 @@
using Plots
function pljtest(source, resfile, doctype)
weave("documents/$source", out_path = "documents/plotsjl/$resfile", doctype=doctype)
result = read("documents/plotsjl/$resfile", String)
ref = read("documents/plotsjl/$resfile.ref", String)
@test result == ref
rm("documents/plotsjl/$resfile")
end
pljtest("plotsjl_test_gr.jmd", "plotsjl_test_gr.md", "pandoc")
pljtest("plotsjl_test_gr.jmd", "plotsjl_test_gr.tex", "tex")
# test cache with plots
isdir("documents/cache") && rm("documents/cache", recursive = true)
weave("documents/plotsjl_test_gr.jmd", cache=:all)
result = read("documents/plotsjl_test_gr.html", String)
rm("documents/plotsjl_test_gr.html")
weave("documents/plotsjl_test_gr.jmd", cache=:all)
cached_result = read("documents/plotsjl_test_gr.html", String)
@test result == cached_result

View File

@ -1,3 +1,5 @@
@testset "evaluation error handling" begin
using Weave: unwrap_load_err using Weave: unwrap_load_err
@ -27,7 +29,7 @@ $err_stmt1
$err_stmt2 $err_stmt2
``` ```
```julia; term=true ```julia; term = true
$err_stmt3 $err_stmt3
``` ```
""" """
@ -47,6 +49,17 @@ let doc = mock_run(str; doctype = "github")
@test occursin(err_str3_2, get_output(3)) @test occursin(err_str3_2, get_output(3))
end end
@test_throws ArgumentError mock_run(str; doctype = "github", throw_errors = true) # TODO: move this into chunk option tests
str = """
```julia; error = true
using # won't be thrown
```
# TODO: test error rendering in `rich_output` ```julia; error = false
using NonExisting # will be thrown
```
"""
@test_throws ArgumentError mock_run(str; doctype = "github")
end # @testset "evaluation error handling"

View File

@ -1,3 +1,5 @@
@testset "meta information for evaluation" begin
doc_body = """ doc_body = """
```julia ```julia
include("test_include.jl") include("test_include.jl")
@ -23,13 +25,13 @@ include("test_include.jl")
read("./test_include.jl", String) read("./test_include.jl", String)
``` ```
""" """
doc_dir = joinpath(@__DIR__, "mocks") doc_dir = normpath(@__DIR__, "..", "mocks")
doc_path = joinpath(doc_dir, "test_meta.jmd") doc_path = normpath(doc_dir, "test_meta.jmd")
write(doc_path, doc_body) write(doc_path, doc_body)
script_line = ":include_me" script_line = ":include_me"
script_body = "$script_line" script_body = "$script_line"
script_path = joinpath(@__DIR__, "mocks", "test_include.jl") script_path = normpath(@__DIR__, "..", "mocks", "test_include.jl")
write(script_path, script_body) write(script_path, script_body)
@ -43,3 +45,5 @@ check_output(i, s) = occursin(s, mock.chunks[i].output)
@test check_output(4, doc_path) @test check_output(4, doc_path)
@test_broken check_output(5, 18) @test_broken check_output(5, 18)
@test check_output(6, string('"', script_line, '"')) # current working directory @test check_output(6, string('"', script_line, '"')) # current working directory
end # @testset "meta information for evaluation"

49
test/run/test_module.jl Normal file
View File

@ -0,0 +1,49 @@
@testset "module evaluation" begin
function mock_output(str, mod = nothing)
result_doc = mock_run(str; mod = mod)
return result_doc.chunks[1].output
end
str = """
```julia
@__MODULE__
```
"""
# in sandbox
@test occursin(r"\#+WeaveSandBox[\#\d]+", mock_output(str))
# in Main
@test strip(mock_output(str, Main)) == "Main"
end # @testset "module evaluation"
@testset "clear_module!" begin
ary = rand(1000000)
size = Base.summarysize(ary)
# simple case
m = Core.eval(@__MODULE__, :(module $(gensym(:WeaveTestModule)) end))
Core.eval(m, :(a = $ary))
Weave.clear_module!(m)
@test Base.summarysize(m) < size
# recursive case
m = Core.eval(@__MODULE__, :(module $(gensym(:WeaveTestModule)) end))
Core.eval(m, :(
module $(gensym(:WeaveTestSubModule))
a = $ary
end
))
Weave.clear_module!(m)
@test Base.summarysize(m) < size
# doesn't work with constants
m = Core.eval(@__MODULE__, :(module $(gensym(:WeaveTestModule)) end))
Core.eval(m, :(const a = $ary))
Weave.clear_module!(m)
@test_broken Base.summarysize(m) < size
end # @testset "clear_module!"

View File

@ -1,10 +1,15 @@
# TODO:
# - reorganize this
# - test for `include_weave`
# - fire horrible tests
# - test for ipynb integration
# - test for integrations with other libraries, especially for Plots.jl and Gadfly.jl
# %%
using Weave, Test using Weave, Test
using Weave: WeaveDoc, run_doc using Weave: WeaveDoc, run_doc
# TODO: add test for header processsing
# TODO: add test for `include_weave`
function mock_doc(str, informat = "markdown") function mock_doc(str, informat = "markdown")
f = tempname() f = tempname()
write(f, str) write(f, str)
@ -27,29 +32,21 @@ function test_mock_weave(test_function, str; kwargs...)
end end
# %%
@testset "Weave" begin @testset "Weave" begin
@testset "module evaluation" begin @testset "reader" begin
include("test_module_evaluation.jl") include("reader/test_chunk_options.jl")
include("reader/test_inline.jl")
end end
@testset "header" begin @testset "header processing" begin
include("test_header.jl") include("test_header.jl")
end end
@testset "inline" begin @testset "run" begin
include("test_inline.jl") include("run/test_module.jl")
end include("run/test_meta.jl")
include("run/test_error.jl")
@testset "chunk options" begin
include("test_chunk_options.jl")
end
@testset "evaluation's meta info" begin
include("test_meta.jl")
end
@testset "error rendering" begin
include("test_error_rendering.jl")
end end
@testset "conversions" begin @testset "conversions" begin
@ -60,39 +57,10 @@ end
include("test_display.jl") include("test_display.jl")
end end
@testset "Formatters" begin @testset "legacy" begin
include("formatter_test.jl") include("formatter_test.jl")
include("markdown_test.jl") include("markdown_test.jl")
include("figureformatter_test.jl") include("figureformatter_test.jl")
end
@testset "Cache" begin
include("cache_test.jl") include("cache_test.jl")
end end
# @testset "Notebooks" begin
# @info("Testing Jupyter options")
# include("notebooks.jl")
# end
# trigger only on CI
if get(ENV, "CI", nothing) == "true"
@testset "Plots" begin
include("plotsjl_test.jl")
end
@testset "Gadfly" begin
include("gadfly_formats.jl")
end
else
@info "skipped Plots.jl and Gadfly.jl integration test"
end
try
@testset "end2end (maybe fail)" begin
include("end2end.jl")
end
catch err
@error err
end
end end

View File

@ -1,2 +0,0 @@
{{{ :body }}}

View File

@ -1,45 +0,0 @@
@testset "evaluation module" begin
function mock_output(str, mod = nothing)
result_doc = mock_run(str; mod = mod)
return result_doc.chunks[1].output
end
str = """
```julia
@__MODULE__
```
"""
# in sandbox
@test occursin(r"\#+WeaveSandBox[\#\d]+", mock_output(str))
# in Main
@test strip(mock_output(str, Main)) == "Main"
end
@testset "clear_module!" begin
ary = rand(1000000)
size = Base.summarysize(ary)
# simple case
m = Core.eval(@__MODULE__, :(module $(gensym(:WeaveTestModule)) end))
Core.eval(m, :(a = $ary))
Weave.clear_module!(m)
@test Base.summarysize(m) < size
# recursive case
m = Core.eval(@__MODULE__, :(module $(gensym(:WeaveTestModule)) end))
Core.eval(m, :(
module $(gensym(:WeaveTestSubModule))
a = $ary
end
))
Weave.clear_module!(m)
@test Base.summarysize(m) < size
# doesn't work with constants
m = Core.eval(@__MODULE__, :(module $(gensym(:WeaveTestModule)) end))
Core.eval(m, :(const a = $ary))
Weave.clear_module!(m)
@test_broken Base.summarysize(m) < size
end