mirror of https://github.com/mpastell/Weave.jl
Compare commits
62 Commits
Author | SHA1 | Date |
---|---|---|
Sebastian Pfitzner | 77793c775c | |
Sheehan Olver | ad0885ce00 | |
Sebastian Pfitzner | e10aaefd94 | |
Sebastian Pfitzner | 8ad4e876d3 | |
Sebastian Pfitzner | af2a6e14c9 | |
Sebastian Pfitzner | 20aaefec0a | |
Gerhard Aigner | 2a78676d41 | |
Gerhard Aigner | 59332c1768 | |
Sebastian Pfitzner | db28a69d94 | |
Sheehan Olver | 0b96591f39 | |
Sebastian Pfitzner | a38cec95db | |
Sebastian Pfitzner | 562f8e4ab3 | |
Sebastian Pfitzner | 9f666b3bb5 | |
KristofferC | a63577f69c | |
Xing Shi Cai | 7e0f5641c2 | |
Nicholas W. M. Ritchie | b022a54458 | |
Nicholas W. M. Ritchie | b669a14038 | |
Sebastian Pfitzner | b7941c2811 | |
ExpandingMan | d40e95a4bb | |
xgdgsc | df47ea191f | |
Sebastian Pfitzner | 381de22c7d | |
github-actions[bot] | 06b259a7b0 | |
Sebastian Pfitzner | 749c0c262c | |
Sebastian Pfitzner | 696db1d82b | |
Mike | d4c65729e4 | |
Mike | 1dfb8d76d6 | |
Sebastian Pfitzner | 48c99c791f | |
Sebastian Pfitzner | ec3f464c37 | |
Mike | 4c60bd8d64 | |
Sebastian Pfitzner | e1d31c2ef6 | |
Shuhei Kadowaki | 99916dd70c | |
Sebastian Pfitzner | 6b6f82bed4 | |
Shuhei Kadowaki | b1de7efede | |
Nathan Hattersley | 849cc20e88 | |
Shuhei Kadowaki | 10de1057a3 | |
Shuhei Kadowaki | e753f70f7a | |
PGunnink | 8dc0441b90 | |
Shuhei Kadowaki | c9fc740d72 | |
Shuhei Kadowaki | cc5913e812 | |
JonasIsensee | e02d5ce2fd | |
Shuhei Kadowaki | b583ac2e40 | |
Shuhei Kadowaki | 955675d89a | |
Shuhei Kadowaki | 196d4ca7ce | |
Shuhei Kadowaki | d3a7f2aea7 | |
Shuhei Kadowaki | 7d361bb40d | |
Shuhei Kadowaki | e927495a62 | |
Shuhei Kadowaki | 78befc61b5 | |
Shuhei Kadowaki | c24a262135 | |
Shuhei Kadowaki | 3e8200c2f8 | |
Shuhei Kadowaki | 8f23084471 | |
Shuhei Kadowaki | a1830e0502 | |
Shuhei Kadowaki | 0e662ecdec | |
Fredrik Bagge Carlson | fa71830479 | |
Shuhei Kadowaki | 21d7fbdbea | |
Shuhei Kadowaki | fe3711074b | |
Tor Erlend Fjelde | 766847ec65 | |
Shuhei Kadowaki | 46a0f8bff4 | |
Oscar Dowson | 51f905ca83 | |
Jonas Isensee | 90d8c8430f | |
Jonas Isensee | a61ade7778 | |
Jonas Isensee | 8ac94989f1 | |
Jonas Isensee | 191282c1e5 |
|
@ -15,7 +15,7 @@ jobs:
|
||||||
fail-fast: false # don't stop CI even when one of them fails
|
fail-fast: false # don't stop CI even when one of them fails
|
||||||
matrix:
|
matrix:
|
||||||
version:
|
version:
|
||||||
- '1.4'
|
- '1.5'
|
||||||
os:
|
os:
|
||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
- macOS-latest
|
- macOS-latest
|
||||||
|
|
|
@ -3,7 +3,7 @@ language: julia
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- stage: "Documentation"
|
- stage: "Documentation"
|
||||||
julia: 1
|
julia: 1.5
|
||||||
os: linux
|
os: linux
|
||||||
script:
|
script:
|
||||||
- julia --project=doc/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
|
- julia --project=doc/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
|
||||||
|
|
15
NEWS.md
15
NEWS.md
|
@ -1,6 +1,19 @@
|
||||||
## Release notes for Weave.jl
|
## Release notes for Weave.jl
|
||||||
|
|
||||||
### v0.10 - 2020/05/18
|
### v0.10.6 – 2020/10/03
|
||||||
|
|
||||||
|
improvements:
|
||||||
|
- cleaned up chunk rendering (removed unnecessary extra newlines): #401
|
||||||
|
- `WEAVE_ARGS` now can take arbitrary objects: https://github.com/JunoLab/Weave.jl/commit/c24a2621359b5d0af1bb6825f488e58cc11b8a9e
|
||||||
|
- improved docs: #397 by @baggepinnen
|
||||||
|
|
||||||
|
bug fixes
|
||||||
|
- fixed #398: #399
|
||||||
|
- removed unnecessary quote for markdown output: https://github.com/JunoLab/Weave.jl/commit/a1830e05029f33195627ec5dedbacb30af23947e
|
||||||
|
- fixed #386: #396 by @torfjelde
|
||||||
|
|
||||||
|
|
||||||
|
### v0.10 – 2020/05/18
|
||||||
|
|
||||||
improvements:
|
improvements:
|
||||||
- `weave` is now integrated with Juno's progress bar; just call `weave` function inside Juno or use `julia-client: weave-to-html(pdf)` command (#331)
|
- `weave` is now integrated with Juno's progress bar; just call `weave` function inside Juno or use `julia-client: weave-to-html(pdf)` command (#331)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name = "Weave"
|
name = "Weave"
|
||||||
uuid = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"
|
uuid = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"
|
||||||
version = "0.10.3"
|
version = "0.10.12"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||||
|
@ -12,15 +12,17 @@ Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
|
||||||
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||||||
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||||
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||||
|
RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
|
||||||
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
|
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
|
||||||
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
||||||
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
||||||
|
|
||||||
[compat]
|
[compat]
|
||||||
Highlights = "0.3.1, 0.4"
|
Highlights = "0.3.1, 0.4, 0.5"
|
||||||
JSON = "0.21"
|
JSON = "0.21"
|
||||||
Mustache = "0.4.1, 0.5, 1"
|
Mustache = "0.4.1, 0.5, 1"
|
||||||
Plots = "0.28, 0.29, 1.0"
|
Plots = "0.28, 0.29, 1.0"
|
||||||
|
RelocatableFolders = "0.1,0.2,0.3,1"
|
||||||
Requires = "1.0"
|
Requires = "1.0"
|
||||||
YAML = "0.3, 0.4"
|
YAML = "0.3, 0.4"
|
||||||
julia = "1.2"
|
julia = "1.2"
|
||||||
|
|
|
@ -97,3 +97,8 @@ Thanks for the important additions, fixes and comments.
|
||||||
|
|
||||||
- [DiffEqTutorials.jl](https://github.com/JuliaDiffEq/DiffEqTutorials.jl) uses Weave to output tutorials (`.jmd` documents) to html, pdf and Jupyter notebooks.
|
- [DiffEqTutorials.jl](https://github.com/JuliaDiffEq/DiffEqTutorials.jl) uses Weave to output tutorials (`.jmd` documents) to html, pdf and Jupyter notebooks.
|
||||||
- [TuringTutorials](https://github.com/TuringLang/TuringTutorials) uses Weave to convert notebooks to html.
|
- [TuringTutorials](https://github.com/TuringLang/TuringTutorials) uses Weave to convert notebooks to html.
|
||||||
|
|
||||||
|
## Related packages
|
||||||
|
|
||||||
|
- [Literate.jl](https://github.com/fredrikekre/Literate.jl) can be used to generate Markdown and Jupyter notebooks directly from Julia source files with markdown in comments.
|
||||||
|
- [Quarto](https://quarto.org) can generate Jupyter notebooks, HTML, or PDF directly from a Markdown format containing Julia code blocks, and also works with R and Python.
|
||||||
|
|
|
@ -39,11 +39,11 @@ Note that `Date` is available since the chunk is evaluated first.
|
||||||
---
|
---
|
||||||
title : Header Example
|
title : Header Example
|
||||||
author : Shuhei Kadowaki
|
author : Shuhei Kadowaki
|
||||||
date: `j Date(now())`
|
date: `j import Dates; Dates.Date(Dates.now())`
|
||||||
---
|
---
|
||||||
|
|
||||||
```julia; echo = false
|
```julia; echo = false
|
||||||
using Datas
|
using Dates
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ e.g. to include a Plots figure in markdown you can use:
|
||||||
```
|
```
|
||||||
or to produce any HTML output:
|
or to produce any HTML output:
|
||||||
```
|
```
|
||||||
! display("text/html", "Header from julia");
|
! display("text/html", HTML("Header from julia"));
|
||||||
```
|
```
|
||||||
|
|
||||||
### Script Format
|
### Script Format
|
||||||
|
@ -165,29 +165,12 @@ See [Header Configuration](@ref) section for more details.
|
||||||
|
|
||||||
## Passing Runtime Arguments to Documents
|
## Passing Runtime Arguments to Documents
|
||||||
|
|
||||||
You can pass arguments as `Dict` to the weaved document using the `args` argument
|
You can pass arbitrary object to the weaved document using [`weave`](@ref)'s optional argument `args`.
|
||||||
to `weave`. The arguments will be available as `WEAVE_ARGS` variable in the document.
|
It will be available as `WEAVE_ARGS` variable in the `weave`d document.
|
||||||
|
|
||||||
This makes it possible to create the same report easily for e.g. different
|
This makes it possible to create the same report easily for e.g. different date ranges of input data from a database or from files with similar format giving the filename as input.
|
||||||
date ranges of input data from a database or from files with similar format giving the
|
|
||||||
filename as input.
|
|
||||||
|
|
||||||
In order to pass a filename to a document you need call `weave` using:
|
E.g. if you call `weave("weavefile.jmd", args = (datalocation = "somedata.h5",))`, and then you can retrieve the `datalocation` in `weavefile.jmd` as follows: `WEAVE_ARGS.datalocation`
|
||||||
|
|
||||||
```julia
|
|
||||||
weave("mydoc.jmd", args = Dict("filename" => "somedata.h5"))
|
|
||||||
```
|
|
||||||
|
|
||||||
and you can access the filename from document as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
```julia
|
|
||||||
print(WEAVE_ARGS["filename"])
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
You can use the `out_path` argument to control the name of the
|
|
||||||
output document.
|
|
||||||
|
|
||||||
|
|
||||||
## `include_weave`
|
## `include_weave`
|
||||||
|
|
25
src/Weave.jl
25
src/Weave.jl
|
@ -1,14 +1,13 @@
|
||||||
module Weave
|
module Weave
|
||||||
|
|
||||||
using Highlights, Mustache, Requires, Pkg, REPL
|
using Highlights, Mustache, Requires, Pkg, REPL, RelocatableFolders, Base64
|
||||||
|
|
||||||
|
|
||||||
# directories
|
# directories
|
||||||
const PKG_DIR = normpath(@__DIR__, "..")
|
const PKG_DIR = normpath(@__DIR__, "..")
|
||||||
const TEMPLATE_DIR = normpath(PKG_DIR, "templates")
|
const TEMPLATE_DIR = @path joinpath(PKG_DIR, "templates")
|
||||||
const STYLESHEET_DIR = normpath(PKG_DIR, "stylesheets")
|
const STYLESHEET_DIR = @path joinpath(PKG_DIR, "stylesheets")
|
||||||
# keeps paths of sample documents for easy try
|
# keeps paths of sample documents for easy try
|
||||||
const EXAMPLE_FOLDER = normpath(PKG_DIR, "examples")
|
const EXAMPLE_FOLDER = @path joinpath(PKG_DIR, "examples")
|
||||||
|
|
||||||
# constant names
|
# constant names
|
||||||
const WEAVE_OPTION_NAME = "weave_options"
|
const WEAVE_OPTION_NAME = "weave_options"
|
||||||
|
@ -102,7 +101,7 @@ Weave an input document to output file.
|
||||||
* `:doc`: Path of the source document (default)
|
* `:doc`: Path of the source document (default)
|
||||||
* `:pwd`: Julia working directory
|
* `:pwd`: Julia working directory
|
||||||
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
|
||||||
- `args::Dict = Dict()`: Arguments to be passed to the weaved document; will be available as `WEAVE_ARGS` in the document
|
- `args::Any = Dict()`: A runtime object that is available as `WEAVE_ARGS` while `weave`ing
|
||||||
- `mod::Union{Module,Nothing} = nothing`: Module where Weave `eval`s code. You can pass a `Module` object, otherwise create an new sandbox module.
|
- `mod::Union{Module,Nothing} = nothing`: Module where Weave `eval`s code. You can pass a `Module` object, otherwise create an new sandbox module.
|
||||||
- `fig_path::Union{Nothing,AbstractString} = nothing`: Where figures will be generated, relative to `out_path`. By default (i.e. given `nothing`), Weave will automatically create `$(DEFAULT_FIG_PATH)` directory.
|
- `fig_path::Union{Nothing,AbstractString} = nothing`: Where figures will be generated, relative to `out_path`. By default (i.e. given `nothing`), Weave will automatically create `$(DEFAULT_FIG_PATH)` directory.
|
||||||
- `fig_ext::Union{Nothing,AbstractString} = nothing`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`
|
- `fig_ext::Union{Nothing,AbstractString} = nothing`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`
|
||||||
|
@ -127,7 +126,7 @@ function weave(
|
||||||
doctype::Union{Nothing,AbstractString} = nothing,
|
doctype::Union{Nothing,AbstractString} = nothing,
|
||||||
informat::Union{Nothing,AbstractString} = nothing,
|
informat::Union{Nothing,AbstractString} = nothing,
|
||||||
out_path::Union{Symbol,AbstractString} = :doc,
|
out_path::Union{Symbol,AbstractString} = :doc,
|
||||||
args::Dict = Dict(),
|
args::Any = Dict(),
|
||||||
mod::Union{Module,Nothing} = nothing,
|
mod::Union{Module,Nothing} = nothing,
|
||||||
fig_path::Union{Nothing,AbstractString} = nothing,
|
fig_path::Union{Nothing,AbstractString} = nothing,
|
||||||
fig_ext::Union{Nothing,AbstractString} = nothing,
|
fig_ext::Union{Nothing,AbstractString} = nothing,
|
||||||
|
@ -244,8 +243,16 @@ function specific_options!(weave_options, doctype)
|
||||||
end
|
end
|
||||||
|
|
||||||
get_out_path(doc, out_path, ext::Nothing = nothing) = get_out_path(doc, out_path, doc.format.extension)
|
get_out_path(doc, out_path, ext::Nothing = nothing) = get_out_path(doc, out_path, doc.format.extension)
|
||||||
get_out_path(doc, out_path, ext) = abspath(get_cwd(doc, out_path), string(doc.basename , '.', ext))
|
function get_out_path(doc, out_path, ext)
|
||||||
|
if (out_path === :doc) || (out_path === :pwd)
|
||||||
|
abspath(get_cwd(doc, out_path), string(doc.basename, '.', ext))
|
||||||
|
elseif isempty(splitext(out_path)[2]) # directory given
|
||||||
|
abspath(get_cwd(doc, out_path), string(doc.basename, '.', ext))
|
||||||
|
else
|
||||||
|
# out_path is given, but if extension is explitly provided override this will override the extension
|
||||||
|
abspath(string(splitext(out_path)[1], '.', ext))
|
||||||
|
end
|
||||||
|
end
|
||||||
"""
|
"""
|
||||||
notebook(source::AbstractString; kwargs...)
|
notebook(source::AbstractString; kwargs...)
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@ using ..Weave: isnothing, take2string!
|
||||||
using Markdown
|
using Markdown
|
||||||
import Markdown: @trigger, @breaking, Code, MD, withstream, startswith, LaTeX
|
import Markdown: @trigger, @breaking, Code, MD, withstream, startswith, LaTeX
|
||||||
|
|
||||||
# Note that this definition causes a "Method overwritten" warning,
|
# HACK: that this definition is type-piracy. It is required since `Markdown`
|
||||||
# but defining this function in __init__() is not legal in julia v1.5
|
# does not have a built in system for contextual rendering by users. `io` here
|
||||||
function Markdown.latex(io::IO, tex::Markdown.LaTeX)
|
# should always be either `IOBuffer` or `IOContext` since it is reached via
|
||||||
|
# `sprint` in all user-facing code paths in `Markdown`.
|
||||||
|
function Markdown.latex(io::Union{IOBuffer,IOContext}, tex::Markdown.LaTeX)
|
||||||
math_envs = ["align", "equation", "eqnarray"]
|
math_envs = ["align", "equation", "eqnarray"]
|
||||||
use_dollars =
|
use_dollars =
|
||||||
!any([occursin("\\begin{$me", tex.formula) for me in math_envs])
|
!any([occursin("\\begin{$me", tex.formula) for me in math_envs])
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module WeavePlots
|
module WeavePlots
|
||||||
|
|
||||||
using Base64, ..Plots, ..Weave
|
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
|
||||||
|
@ -17,7 +17,7 @@ function Base.display(
|
||||||
report::Weave.Report,
|
report::Weave.Report,
|
||||||
m::MIME"image/svg+xml",
|
m::MIME"image/svg+xml",
|
||||||
data::Plots.Plot{Plots.PlotlyBackend},
|
data::Plots.Plot{Plots.PlotlyBackend},
|
||||||
)#
|
)
|
||||||
# Remove extra spaces from start of line for pandoc
|
# Remove extra spaces from start of line for pandoc
|
||||||
s = repr(MIME("text/html"), data)
|
s = repr(MIME("text/html"), data)
|
||||||
splitted = split(s, "\n")
|
splitted = split(s, "\n")
|
||||||
|
@ -39,7 +39,7 @@ function Base.display(
|
||||||
report::Weave.Report,
|
report::Weave.Report,
|
||||||
m::MIME"image/png",
|
m::MIME"image/png",
|
||||||
data::Plots.Plot{Plots.PlotlyBackend},
|
data::Plots.Plot{Plots.PlotlyBackend},
|
||||||
)#
|
)
|
||||||
display(report, MIME("image/svg+xml"), data)
|
display(report, MIME("image/svg+xml"), data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ function parse_markdown(document_body; is_pandoc = false)
|
||||||
r"^<<(?<options>.*?)>>=\s*$",
|
r"^<<(?<options>.*?)>>=\s*$",
|
||||||
r"^@\s*$"
|
r"^@\s*$"
|
||||||
else
|
else
|
||||||
r"^[`~]{3}(\{?)julia\s*([;,]?)\s*(?<options>.*?)(\}|\s*)$",
|
r"^[`~]{3}(\{?)julia\s*([;,\{]?)\s*(?<options>.*?)(\}|\s*)$",
|
||||||
r"^[`~]{3}\s*$"
|
r"^[`~]{3}\s*$"
|
||||||
end
|
end
|
||||||
return header, parse_markdown_body(document_body, code_start, code_end, offset)
|
return header, parse_markdown_body(document_body, code_start, code_end, offset)
|
||||||
|
|
|
@ -44,18 +44,14 @@ function render_chunk(docformat::WeaveFormat, chunk::CodeChunk)
|
||||||
|
|
||||||
chunk.content = render_code(docformat, chunk.content)
|
chunk.content = render_code(docformat, chunk.content)
|
||||||
|
|
||||||
if !chunk.options[:eval]
|
echo = chunk.options[:echo]
|
||||||
return if chunk.options[:echo]
|
|
||||||
string(docformat.codestart, '\n', chunk.content, docformat.codeend)
|
chunk.options[:eval] || return echo ? string(docformat.codestart, chunk.content, docformat.codeend) : ""
|
||||||
else
|
|
||||||
""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if chunk.options[:term]
|
if chunk.options[:term]
|
||||||
result = render_termchunk(docformat, chunk)
|
result = render_termchunk(docformat, chunk)
|
||||||
else
|
else
|
||||||
result = if chunk.options[:echo]
|
result = if echo
|
||||||
# Convert to output format and highlight (html, tex...) if needed
|
# Convert to output format and highlight (html, tex...) if needed
|
||||||
string(docformat.codestart, chunk.content, docformat.codeend, '\n')
|
string(docformat.codestart, chunk.content, docformat.codeend, '\n')
|
||||||
else
|
else
|
||||||
|
@ -126,7 +122,7 @@ render_output(docformat::WeaveFormat, output) = output
|
||||||
|
|
||||||
function render_termchunk(docformat::WeaveFormat, chunk)
|
function render_termchunk(docformat::WeaveFormat, chunk)
|
||||||
return if should_render(chunk)
|
return if should_render(chunk)
|
||||||
string(docformat.termstart, chunk.output, '\n', docformat.termend, '\n')
|
string(docformat.termstart, chunk.output, docformat.termend)
|
||||||
else
|
else
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
abstract type ExportFormat <: WeaveFormat end
|
||||||
|
|
||||||
|
function Base.getproperty(sf::T, s::Symbol) where {T<:ExportFormat}
|
||||||
|
hasfield(T, s) && return getfield(sf, s)
|
||||||
|
return getproperty(sf.primaryformat, s)
|
||||||
|
end
|
||||||
|
function Base.setproperty!(sf::T, s::Symbol, v) where {T<:ExportFormat}
|
||||||
|
if hasfield(T, s)
|
||||||
|
setfield!(sf, s, v)
|
||||||
|
else
|
||||||
|
setproperty!(sf.primaryformat, s, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function Base.hasproperty(sf::T, s::Symbol) where {T<:ExportFormat}
|
||||||
|
hasfield(T, s) || hasproperty(sf.primaryformat, s)
|
||||||
|
end
|
||||||
|
|
||||||
|
render_doc(df::ExportFormat, body, doc) = render_doc(df.primaryformat, body, doc)
|
||||||
|
|
||||||
|
render_chunk(df::ExportFormat, chunk) = render_chunk(df.primaryformat, chunk)
|
||||||
|
# Need to define these to avoid ambiguities
|
||||||
|
render_chunk(df::ExportFormat, chunk::DocChunk) = render_chunk(df.primaryformat, chunk)
|
||||||
|
render_chunk(df::ExportFormat, chunk::CodeChunk) = render_chunk(df.primaryformat, chunk)
|
||||||
|
render_output(df::ExportFormat, output) = render_output(df.primaryformat, output)
|
|
@ -15,8 +15,8 @@ render_termchunk(docformat::HTMLFormat, chunk) =
|
||||||
Base.@kwdef mutable struct WeaveHTML <: HTMLFormat
|
Base.@kwdef mutable struct WeaveHTML <: HTMLFormat
|
||||||
description = "Weave-style HTML"
|
description = "Weave-style HTML"
|
||||||
extension = "html"
|
extension = "html"
|
||||||
codestart = "\n"
|
codestart = '\n'
|
||||||
codeend = "\n"
|
codeend = '\n'
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "<pre class=\"output\">"
|
outputstart = "<pre class=\"output\">"
|
||||||
|
@ -124,23 +124,9 @@ end
|
||||||
# Pandoc
|
# Pandoc
|
||||||
# ------
|
# ------
|
||||||
|
|
||||||
Base.@kwdef mutable struct Pandoc2HTML <: HTMLFormat
|
Base.@kwdef mutable struct Pandoc2HTML <: ExportFormat
|
||||||
description = "HTML via intermediate Pandoc Markdown (requires Pandoc 2)"
|
description = "HTML via intermediate Pandoc Markdown (requires Pandoc 2)"
|
||||||
extension = "md"
|
primaryformat = Pandoc()
|
||||||
codestart = "\n"
|
|
||||||
codeend = "\n"
|
|
||||||
termstart = codestart
|
|
||||||
termend = codeend
|
|
||||||
outputstart = "\n"
|
|
||||||
outputend = "\n"
|
|
||||||
mimetypes = ["image/png", "image/svg+xml", "image/jpg", "text/html", "text/markdown", "text/plain"]
|
|
||||||
fig_ext = ".png"
|
|
||||||
out_width = nothing
|
|
||||||
out_height = nothing
|
|
||||||
fig_pos = nothing
|
|
||||||
fig_env = nothing
|
|
||||||
# specials
|
|
||||||
preserve_header = true
|
|
||||||
template_path = nothing
|
template_path = nothing
|
||||||
stylesheet_path = nothing
|
stylesheet_path = nothing
|
||||||
highlight_theme = nothing
|
highlight_theme = nothing
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
Base.@kwdef mutable struct GitHubMarkdown <: WeaveFormat
|
Base.@kwdef mutable struct GitHubMarkdown <: WeaveFormat
|
||||||
description = "GitHub Markdown"
|
description = "GitHub Markdown"
|
||||||
extension = "md"
|
extension = "md"
|
||||||
codestart = "````julia"
|
codestart = "```julia"
|
||||||
codeend = "````\n\n"
|
codeend = "```\n"
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "````"
|
outputstart = "```"
|
||||||
outputend = "````\n\n"
|
outputend = "```\n\n"
|
||||||
fig_ext = ".png"
|
fig_ext = ".png"
|
||||||
mimetypes = ["image/png", "image/svg+xml", "image/jpg",
|
mimetypes = ["image/png", "image/svg+xml", "image/jpg",
|
||||||
"text/markdown", "text/plain"]
|
"text/markdown", "text/plain"]
|
||||||
|
@ -50,12 +50,12 @@ end
|
||||||
Base.@kwdef mutable struct Hugo <: WeaveFormat
|
Base.@kwdef mutable struct Hugo <: WeaveFormat
|
||||||
description = "Hugo Markdown (using shortcodes)"
|
description = "Hugo Markdown (using shortcodes)"
|
||||||
extension = "md"
|
extension = "md"
|
||||||
codestart = "````julia"
|
codestart = "```julia"
|
||||||
codeend = "````\n\n"
|
codeend = "```\n"
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "````"
|
outputstart = "```"
|
||||||
outputend = "````\n\n"
|
outputend = "```\n\n"
|
||||||
mimetypes = default_mime_types
|
mimetypes = default_mime_types
|
||||||
fig_ext = ".png"
|
fig_ext = ".png"
|
||||||
out_width = nothing
|
out_width = nothing
|
||||||
|
@ -88,12 +88,12 @@ end
|
||||||
Base.@kwdef mutable struct MultiMarkdown <: WeaveFormat
|
Base.@kwdef mutable struct MultiMarkdown <: WeaveFormat
|
||||||
description = "MultiMarkdown"
|
description = "MultiMarkdown"
|
||||||
extension = "md"
|
extension = "md"
|
||||||
codestart = "````julia"
|
codestart = "```julia"
|
||||||
codeend = "````\n\n"
|
codeend = "```\n"
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "````"
|
outputstart = "```"
|
||||||
outputend = "````\n\n"
|
outputend = "```\n\n"
|
||||||
mimetypes = default_mime_types
|
mimetypes = default_mime_types
|
||||||
fig_ext = ".png"
|
fig_ext = ".png"
|
||||||
out_width = nothing
|
out_width = nothing
|
||||||
|
@ -143,7 +143,7 @@ Base.@kwdef mutable struct Rest <: WeaveFormat
|
||||||
description = "reStructuredText and Sphinx"
|
description = "reStructuredText and Sphinx"
|
||||||
extension = "rst"
|
extension = "rst"
|
||||||
codestart = ".. code-block:: julia\n"
|
codestart = ".. code-block:: julia\n"
|
||||||
codeend = "\n\n"
|
codeend = "\n"
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "::\n"
|
outputstart = "::\n"
|
||||||
|
@ -190,7 +190,7 @@ Base.@kwdef mutable struct AsciiDoc <: WeaveFormat
|
||||||
description = "AsciiDoc"
|
description = "AsciiDoc"
|
||||||
extension = "txt"
|
extension = "txt"
|
||||||
codestart = "[source,julia]\n--------------------------------------"
|
codestart = "[source,julia]\n--------------------------------------"
|
||||||
codeend = "--------------------------------------\n\n"
|
codeend = "--------------------------------------\n"
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "--------------------------------------"
|
outputstart = "--------------------------------------"
|
||||||
|
|
|
@ -37,7 +37,7 @@ Base.@kwdef mutable struct Pandoc <: PandocFormat
|
||||||
description = "Pandoc Markdown"
|
description = "Pandoc Markdown"
|
||||||
extension = "md"
|
extension = "md"
|
||||||
codestart = "~~~~{.julia}"
|
codestart = "~~~~{.julia}"
|
||||||
codeend = "~~~~~~~~~~~~~\n\n"
|
codeend = "~~~~~~~~~~~~~\n"
|
||||||
termstart = codestart
|
termstart = codestart
|
||||||
termend = codeend
|
termend = codeend
|
||||||
outputstart = "~~~~"
|
outputstart = "~~~~"
|
||||||
|
@ -54,28 +54,14 @@ Base.@kwdef mutable struct Pandoc <: PandocFormat
|
||||||
end
|
end
|
||||||
register_format!("pandoc", Pandoc())
|
register_format!("pandoc", Pandoc())
|
||||||
|
|
||||||
|
|
||||||
const DEFAULT_PANDOC_OPTIONS = String[]
|
const DEFAULT_PANDOC_OPTIONS = String[]
|
||||||
|
|
||||||
Base.@kwdef mutable struct Pandoc2PDF <: PandocFormat
|
Base.@kwdef mutable struct Pandoc2PDF <: ExportFormat
|
||||||
description = "PDF via intermediate Pandoc Markdown"
|
description = "PDF via intermediate Pandoc Markdown"
|
||||||
extension = "md"
|
primaryformat = Pandoc()
|
||||||
codestart = "~~~~{.julia}"
|
|
||||||
codeend = "~~~~~~~~~~~~~\n\n"
|
|
||||||
termstart = codestart
|
|
||||||
termend = codeend
|
|
||||||
outputstart = "~~~~"
|
|
||||||
outputend = "~~~~\n\n"
|
|
||||||
# Prefer png figures for markdown conversion, svg doesn't work with latex
|
|
||||||
mimetypes = ["image/png", "image/jpg", "image/svg+xml", "text/markdown", "text/plain"]
|
|
||||||
fig_ext = ".png"
|
|
||||||
out_width = nothing
|
|
||||||
out_height = nothing
|
|
||||||
fig_pos = nothing
|
|
||||||
fig_env = nothing
|
|
||||||
# specials
|
|
||||||
preserve_header = true
|
|
||||||
header_template = normpath(TEMPLATE_DIR, "pandoc2pdf_header.txt")
|
|
||||||
pandoc_options = DEFAULT_PANDOC_OPTIONS
|
pandoc_options = DEFAULT_PANDOC_OPTIONS
|
||||||
|
header_template = normpath(TEMPLATE_DIR, "pandoc2pdf_header.txt")
|
||||||
end
|
end
|
||||||
register_format!("pandoc2pdf", Pandoc2PDF())
|
register_format!("pandoc2pdf", Pandoc2PDF())
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ function render_doc(doc::WeaveDoc)
|
||||||
return render_doc(docformat, body, doc)
|
return render_doc(docformat, body, doc)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
include("exportformat.jl")
|
||||||
include("common.jl")
|
include("common.jl")
|
||||||
|
include("pandocformats.jl")
|
||||||
include("htmlformats.jl")
|
include("htmlformats.jl")
|
||||||
include("texformats.jl")
|
include("texformats.jl")
|
||||||
include("pandocformats.jl")
|
|
||||||
include("miscformats.jl")
|
include("miscformats.jl")
|
||||||
|
|
|
@ -34,7 +34,10 @@ render_output(docformat::LaTeXFormat, output) = unicode2latex(docformat, output,
|
||||||
|
|
||||||
render_code(docformat::LaTeXFormat, code) = unicode2latex(docformat, code, true)
|
render_code(docformat::LaTeXFormat, code) = unicode2latex(docformat, code, true)
|
||||||
|
|
||||||
render_termchunk(docformat::LaTeXFormat, chunk) = string(docformat.termstart, chunk.output, docformat.termend, "\n")
|
render_termchunk(docformat::LaTeXFormat, chunk) =
|
||||||
|
string(docformat.termstart,
|
||||||
|
unicode2latex(docformat, chunk.output, true),
|
||||||
|
docformat.termend, "\n")
|
||||||
|
|
||||||
# from julia symbols (e.g. "\bfhoge") to valid latex
|
# from julia symbols (e.g. "\bfhoge") to valid latex
|
||||||
const UNICODE2LATEX = let
|
const UNICODE2LATEX = let
|
||||||
|
@ -149,11 +152,11 @@ end
|
||||||
Base.@kwdef mutable struct LaTeXMinted <: LaTeXFormat
|
Base.@kwdef mutable struct LaTeXMinted <: LaTeXFormat
|
||||||
description = "LaTeX using minted package for code highlighting"
|
description = "LaTeX using minted package for code highlighting"
|
||||||
extension = "tex"
|
extension = "tex"
|
||||||
codestart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
|
codestart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
|
||||||
codeend = "\\end{minted}"
|
codeend = "\\end{minted}"
|
||||||
termstart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\footnotesize, xleftmargin=0.5em]{jlcon}"
|
termstart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\footnotesize, xleftmargin=0.5em]{jlcon}"
|
||||||
termend = "\\end{minted}"
|
termend = "\\end{minted}"
|
||||||
outputstart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\small, xleftmargin=0.5em, frame = leftline]{text}"
|
outputstart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\small, xleftmargin=0.5em, frame = leftline]{text}"
|
||||||
outputend = "\\end{minted}"
|
outputend = "\\end{minted}"
|
||||||
mimetypes = ["application/pdf", "image/png", "text/latex", "text/plain"]
|
mimetypes = ["application/pdf", "image/png", "text/latex", "text/plain"]
|
||||||
fig_ext = ".pdf"
|
fig_ext = ".pdf"
|
||||||
|
@ -198,8 +201,14 @@ function render_code(docformat::WeaveLaTeXFormat, code)
|
||||||
unicode2latex(docformat, ret, false)
|
unicode2latex(docformat, ret, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
render_termchunk(docformat::WeaveLaTeXFormat, chunk) =
|
function render_termchunk(docformat::WeaveLaTeXFormat, chunk)
|
||||||
should_render(chunk) ? highlight_term(MIME("text/latex"), chunk.output, docformat.highlight_theme) : ""
|
if should_render(chunk)
|
||||||
|
ret = highlight_term(MIME("text/latex"), chunk.output, docformat.highlight_theme)
|
||||||
|
unicode2latex(docformat, ret, true)
|
||||||
|
else
|
||||||
|
""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function render_doc(docformat::WeaveLaTeXFormat, body, doc)
|
function render_doc(docformat::WeaveLaTeXFormat, body, doc)
|
||||||
return Mustache.render(
|
return Mustache.render(
|
||||||
|
@ -233,44 +242,23 @@ Base.@kwdef mutable struct WeaveLaTeX <: WeaveLaTeXFormat
|
||||||
tex_deps = ""
|
tex_deps = ""
|
||||||
# how to escape latex in verbatim/code environment
|
# how to escape latex in verbatim/code environment
|
||||||
escape_starter = "(*@"
|
escape_starter = "(*@"
|
||||||
escape_closer = reverse(escape_starter)
|
escape_closer = "@*)"
|
||||||
end
|
end
|
||||||
register_format!("md2tex", WeaveLaTeX())
|
register_format!("md2tex", WeaveLaTeX())
|
||||||
|
|
||||||
# will be used by `write_doc`
|
# will be used by `write_doc`
|
||||||
const DEFAULT_LATEX_CMD = ["xelatex", "-shell-escape", "-halt-on-error"]
|
const DEFAULT_LATEX_CMD = ["xelatex", "-shell-escape", "-halt-on-error"]
|
||||||
|
|
||||||
Base.@kwdef mutable struct WeaveLaTeX2PDF <: WeaveLaTeXFormat
|
|
||||||
description = "PDF via Weave-styled LaTeX"
|
|
||||||
extension = "tex"
|
|
||||||
codestart = ""
|
|
||||||
codeend = ""
|
|
||||||
termstart = codestart
|
|
||||||
termend = codeend
|
|
||||||
outputstart = "\\begin{lstlisting}"
|
|
||||||
outputend = "\\end{lstlisting}\n"
|
|
||||||
mimetypes = ["application/pdf", "image/png", "image/jpg", "text/latex", "text/markdown", "text/plain"]
|
|
||||||
fig_ext = ".pdf"
|
|
||||||
out_width = "\\linewidth"
|
|
||||||
out_height = nothing
|
|
||||||
fig_pos = nothing
|
|
||||||
fig_env = nothing
|
|
||||||
# specials
|
|
||||||
highlight_theme = nothing
|
|
||||||
template = nothing
|
|
||||||
keep_unicode = false
|
|
||||||
tex_deps = ""
|
|
||||||
latex_cmd = DEFAULT_LATEX_CMD
|
|
||||||
# how to escape latex in verbatim/code environment
|
|
||||||
escape_starter = "(*@"
|
|
||||||
escape_closer = reverse(escape_starter)
|
|
||||||
end
|
|
||||||
register_format!("md2pdf", WeaveLaTeX2PDF())
|
|
||||||
|
|
||||||
function set_format_options!(docformat::WeaveLaTeX2PDF; template = nothing, highlight_theme = nothing, keep_unicode = false, latex_cmd = DEFAULT_LATEX_CMD, _kwargs...)
|
Base.@kwdef mutable struct LaTeX2PDF <: ExportFormat
|
||||||
docformat.template =
|
primaryformat = WeaveLaTeX()
|
||||||
get_mustache_template(isnothing(template) ? normpath(TEMPLATE_DIR, "md2pdf.tpl") : template)
|
description = "PDF via LaTeX"
|
||||||
docformat.highlight_theme = get_highlight_theme(highlight_theme)
|
latex_cmd = DEFAULT_LATEX_CMD
|
||||||
docformat.keep_unicode |= keep_unicode
|
end
|
||||||
docformat.latex_cmd = latex_cmd
|
register_format!("md2pdf", LaTeX2PDF())
|
||||||
|
register_format!("minted2pdf", LaTeX2PDF(primaryformat=LaTeXMinted()))
|
||||||
|
|
||||||
|
function set_format_options!(docformat::LaTeX2PDF; latex_cmd = DEFAULT_LATEX_CMD, _kwargs...)
|
||||||
|
docformat.latex_cmd = latex_cmd
|
||||||
|
set_format_options!(docformat.primaryformat; _kwargs...)
|
||||||
end
|
end
|
||||||
|
|
74
src/run.jl
74
src/run.jl
|
@ -7,7 +7,7 @@ function run_doc(
|
||||||
doc::WeaveDoc;
|
doc::WeaveDoc;
|
||||||
doctype::Union{Nothing,AbstractString} = nothing,
|
doctype::Union{Nothing,AbstractString} = nothing,
|
||||||
out_path::Union{Symbol,AbstractString} = :doc,
|
out_path::Union{Symbol,AbstractString} = :doc,
|
||||||
args::Dict = Dict(),
|
args::Any = Dict(),
|
||||||
mod::Union{Module,Nothing} = nothing,
|
mod::Union{Module,Nothing} = nothing,
|
||||||
fig_path::Union{Nothing,AbstractString} = nothing,
|
fig_path::Union{Nothing,AbstractString} = nothing,
|
||||||
fig_ext::Union{Nothing,AbstractString} = nothing,
|
fig_ext::Union{Nothing,AbstractString} = nothing,
|
||||||
|
@ -20,8 +20,9 @@ function run_doc(
|
||||||
doc.format = deepcopy(get_format(doctype))
|
doc.format = deepcopy(get_format(doctype))
|
||||||
|
|
||||||
cwd = doc.cwd = get_cwd(doc, out_path)
|
cwd = doc.cwd = get_cwd(doc, out_path)
|
||||||
isdir(cwd) || mkdir(cwd)
|
mkpath(cwd)
|
||||||
|
|
||||||
|
# TODO: provide a way not to create `fig_path` ?
|
||||||
if isnothing(fig_path)
|
if isnothing(fig_path)
|
||||||
fig_path = if (endswith(doctype, "2pdf") && cache === :off) || endswith(doctype, "2html")
|
fig_path = if (endswith(doctype, "2pdf") && cache === :off) || endswith(doctype, "2html")
|
||||||
basename(mktempdir(abspath(cwd)))
|
basename(mktempdir(abspath(cwd)))
|
||||||
|
@ -29,7 +30,7 @@ function run_doc(
|
||||||
DEFAULT_FIG_PATH
|
DEFAULT_FIG_PATH
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
let d = normpath(cwd, fig_path); isdir(d) || mkdir(d); end
|
mkpath(normpath(cwd, fig_path))
|
||||||
# This is needed for latex and should work on all output formats
|
# This is needed for latex and should work on all output formats
|
||||||
@static Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/"))
|
@static Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/"))
|
||||||
set_rc_params(doc, fig_path, fig_ext)
|
set_rc_params(doc, fig_path, fig_ext)
|
||||||
|
@ -38,7 +39,7 @@ function run_doc(
|
||||||
|
|
||||||
# New sandbox for each document with args exposed
|
# New sandbox for each document with args exposed
|
||||||
isnothing(mod) && (mod = sandbox = Core.eval(Main, :(module $(gensym(:WeaveSandBox)) end))::Module)
|
isnothing(mod) && (mod = sandbox = Core.eval(Main, :(module $(gensym(:WeaveSandBox)) end))::Module)
|
||||||
@eval mod WEAVE_ARGS = $args
|
Core.eval(mod, :(WEAVE_ARGS = $(args)))
|
||||||
|
|
||||||
mimetypes = doc.format.mimetypes
|
mimetypes = doc.format.mimetypes
|
||||||
|
|
||||||
|
@ -89,6 +90,8 @@ function run_doc(
|
||||||
@info "Weaved all chunks" progress=1 _id=PROGRESS_ID
|
@info "Weaved all chunks" progress=1 _id=PROGRESS_ID
|
||||||
cd_back()
|
cd_back()
|
||||||
popdisplay(report) # ensure display pops out even if internal error occurs
|
popdisplay(report) # ensure display pops out even if internal error occurs
|
||||||
|
# Temporary fig_path is not automatically removed because it contains files so...
|
||||||
|
!isnothing(fig_path) && startswith(fig_path, "jl_") && rm(normpath(cwd, fig_path), force=true, recursive=true)
|
||||||
end
|
end
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
@ -139,27 +142,17 @@ function embed_figures!(chunk::CodeChunk, cwd)
|
||||||
chunk.figures[i] = img2base64(fig, cwd)
|
chunk.figures[i] = img2base64(fig, cwd)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
embed_figures!(chunks, cwd) = embed_figures!.(chunks, Ref(cwd))
|
||||||
function embed_figures!(chunks::Vector{CodeChunk}, cwd)
|
|
||||||
for chunk in chunks
|
|
||||||
embed_figures!(chunk, cwd)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function img2base64(fig, cwd)
|
function img2base64(fig, cwd)
|
||||||
ext = splitext(fig)[2]
|
ext = splitext(fig)[2]
|
||||||
f = open(joinpath(cwd, fig), "r")
|
f = open(joinpath(cwd, fig), "r")
|
||||||
raw = read(f)
|
raw = read(f)
|
||||||
close(f)
|
close(f)
|
||||||
if ext == ".png"
|
return ext == ".png" ? "data:image/png;base64," * stringmime(MIME("image/png"), raw) :
|
||||||
return "data:image/png;base64," * stringmime(MIME("image/png"), raw)
|
ext == ".svg" ? "data:image/svg+xml;base64," * stringmime(MIME("image/svg"), raw) :
|
||||||
elseif ext == ".svg"
|
ext == ".gif" ? "data:image/gif;base64," * stringmime(MIME("image/gif"), raw) :
|
||||||
return "data:image/svg+xml;base64," * stringmime(MIME("image/svg"), raw)
|
fig
|
||||||
elseif ext == ".gif"
|
|
||||||
return "data:image/gif;base64," * stringmime(MIME("image/gif"), raw)
|
|
||||||
else
|
|
||||||
return (fig)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function run_chunk(chunk::DocChunk, doc, report, mod)
|
function run_chunk(chunk::DocChunk, doc, report, mod)
|
||||||
|
@ -225,7 +218,7 @@ function capture_output(code, mod, path, error, report)
|
||||||
task_local_storage(:SOURCE_PATH, path) do
|
task_local_storage(:SOURCE_PATH, path) do
|
||||||
try
|
try
|
||||||
obj = include_string(mod, code, path) # TODO: fix line number
|
obj = include_string(mod, code, path) # TODO: fix line number
|
||||||
!isnothing(obj) && display(obj)
|
!isnothing(obj) && !REPL.ends_with_semicolon(code) && display(obj)
|
||||||
catch _err
|
catch _err
|
||||||
err = unwrap_load_err(_err)
|
err = unwrap_load_err(_err)
|
||||||
error || throw(err)
|
error || throw(err)
|
||||||
|
@ -273,15 +266,9 @@ function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module
|
||||||
|
|
||||||
execute_posthooks!(chunk)
|
execute_posthooks!(chunk)
|
||||||
|
|
||||||
chunks = if chunk.options[:term]
|
return chunk.options[:term] ? collect_term_results(chunk) :
|
||||||
collect_term_results(chunk)
|
chunk.options[:hold] ? collect_hold_results(chunk) :
|
||||||
elseif chunk.options[:hold]
|
collect_results(chunk)
|
||||||
collect_hold_results(chunk)
|
|
||||||
else
|
|
||||||
collect_results(chunk)
|
|
||||||
end
|
|
||||||
|
|
||||||
return chunks
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Hooks to run before and after chunks, this is form IJulia,
|
# Hooks to run before and after chunks, this is form IJulia,
|
||||||
|
@ -292,7 +279,11 @@ function pop_preexecution_hook!(f::Function)
|
||||||
isnothing(i) && error("this function has not been registered in the pre-execution hook yet")
|
isnothing(i) && error("this function has not been registered in the pre-execution hook yet")
|
||||||
return splice!(preexecution_hooks, i)
|
return splice!(preexecution_hooks, i)
|
||||||
end
|
end
|
||||||
execute_prehooks!(chunk::CodeChunk) = for prehook in preexecution_hooks; Base.invokelatest(prehook, chunk); end
|
function execute_prehooks!(chunk::CodeChunk)
|
||||||
|
for prehook in preexecution_hooks
|
||||||
|
Base.invokelatest(prehook, chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
const postexecution_hooks = Function[]
|
const postexecution_hooks = Function[]
|
||||||
push_postexecution_hook!(f::Function) = push!(postexecution_hooks, f)
|
push_postexecution_hook!(f::Function) = push!(postexecution_hooks, f)
|
||||||
|
@ -301,7 +292,11 @@ function pop_postexecution_hook!(f::Function)
|
||||||
isnothing(i) && error("this function has not been registered in the post-execution hook yet")
|
isnothing(i) && error("this function has not been registered in the post-execution hook yet")
|
||||||
return splice!(postexecution_hooks, i)
|
return splice!(postexecution_hooks, i)
|
||||||
end
|
end
|
||||||
execute_posthooks!(chunk::CodeChunk) = for posthook in postexecution_hooks; Base.invokelatest(posthook, chunk); end
|
function execute_posthooks!(chunk::CodeChunk)
|
||||||
|
for posthook in postexecution_hooks
|
||||||
|
Base.invokelatest(posthook, chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
clear_module!(mod::Module)
|
clear_module!(mod::Module)
|
||||||
|
@ -340,11 +335,7 @@ function get_figname(report::Report, chunk; fignum = nothing, ext = nothing)
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_rc_params(doc::WeaveDoc, fig_path, fig_ext)
|
function set_rc_params(doc::WeaveDoc, fig_path, fig_ext)
|
||||||
if isnothing(fig_ext)
|
doc.chunk_defaults[:fig_ext] = isnothing(fig_ext) ? doc.format.fig_ext : fig_ext
|
||||||
doc.chunk_defaults[:fig_ext] = doc.format.fig_ext
|
|
||||||
else
|
|
||||||
doc.chunk_defaults[:fig_ext] = fig_ext
|
|
||||||
end
|
|
||||||
doc.chunk_defaults[:fig_path] = fig_path
|
doc.chunk_defaults[:fig_path] = fig_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -352,11 +343,9 @@ function collect_results(chunk::CodeChunk)
|
||||||
content = ""
|
content = ""
|
||||||
result_chunks = CodeChunk[]
|
result_chunks = CodeChunk[]
|
||||||
for r in chunk.result
|
for r in chunk.result
|
||||||
|
content *= r.code
|
||||||
# Check if there is any output from chunk
|
# Check if there is any output from chunk
|
||||||
if strip(r.stdout) == "" && isempty(r.figures) && strip(r.rich_output) == ""
|
if any(!isempty ∘ strip, (r.stdout, r.rich_output)) || !isempty(r.figures)
|
||||||
content *= r.code
|
|
||||||
else
|
|
||||||
content = "\n" * content * r.code
|
|
||||||
rchunk = CodeChunk(
|
rchunk = CodeChunk(
|
||||||
content,
|
content,
|
||||||
chunk.number,
|
chunk.number,
|
||||||
|
@ -364,15 +353,14 @@ function collect_results(chunk::CodeChunk)
|
||||||
chunk.optionstring,
|
chunk.optionstring,
|
||||||
copy(chunk.options),
|
copy(chunk.options),
|
||||||
)
|
)
|
||||||
content = ""
|
|
||||||
rchunk.figures = r.figures
|
|
||||||
rchunk.output = r.stdout
|
rchunk.output = r.stdout
|
||||||
rchunk.rich_output = r.rich_output
|
rchunk.rich_output = r.rich_output
|
||||||
|
rchunk.figures = r.figures
|
||||||
push!(result_chunks, rchunk)
|
push!(result_chunks, rchunk)
|
||||||
|
content = ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if !isempty(content)
|
if !isempty(content)
|
||||||
startswith(content, "\n") || (content = "\n" * content)
|
|
||||||
rchunk = CodeChunk(
|
rchunk = CodeChunk(
|
||||||
content,
|
content,
|
||||||
chunk.number,
|
chunk.number,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
function write_doc(docformat::WeaveLaTeX2PDF, doc, rendered, out_path)
|
function write_doc(docformat::LaTeX2PDF, doc, rendered, out_path)
|
||||||
cd_back = let d = pwd(); () -> cd(d); end
|
cd_back = let d = pwd(); () -> cd(d); end
|
||||||
cd(doc.cwd)
|
cd(doc.cwd)
|
||||||
try
|
try
|
||||||
|
|
|
@ -61,7 +61,7 @@ function write_doc(docformat::Pandoc2PDF, doc, rendered, out_path)
|
||||||
cmd = `pandoc -f markdown+raw_tex -s --pdf-engine=xelatex --highlight-style=tango
|
cmd = `pandoc -f markdown+raw_tex -s --pdf-engine=xelatex --highlight-style=tango
|
||||||
$filt $citeproc $(docformat.pandoc_options)
|
$filt $citeproc $(docformat.pandoc_options)
|
||||||
--include-in-header=$(docformat.header_template)
|
--include-in-header=$(docformat.header_template)
|
||||||
-V fontsize=12pt -o $(out)`
|
-o $(out)`
|
||||||
proc = open(cmd, "r+")
|
proc = open(cmd, "r+")
|
||||||
println(proc.in, rendered)
|
println(proc.in, rendered)
|
||||||
close(proc.in)
|
close(proc.in)
|
||||||
|
|
|
@ -3,7 +3,7 @@ using Weave.Dates
|
||||||
|
|
||||||
test_doctypes = filter(first.(Weave.list_out_formats())) do doctype
|
test_doctypes = filter(first.(Weave.list_out_formats())) do doctype
|
||||||
# don't test doctypes which need external programs
|
# don't test doctypes which need external programs
|
||||||
doctype ∉ ("pandoc2html", "pandoc2pdf", "md2pdf")
|
doctype ∉ ("pandoc2html", "pandoc2pdf", "md2pdf", "minted2pdf")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_func(body)
|
function test_func(body)
|
||||||
|
@ -24,7 +24,6 @@ using Dates
|
||||||
Date(now())
|
Date(now())
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for doctype in test_doctypes
|
for doctype in test_doctypes
|
||||||
test_mock_weave(test_func, julia_markdown_body; informat = "markdown", doctype = doctype)
|
test_mock_weave(test_func, julia_markdown_body; informat = "markdown", doctype = doctype)
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,6 +72,10 @@ let opts = get_options("```julia, opt1 = 1, opt2 = \"2\"\n```")
|
||||||
@test (:opt1 => 1) in opts
|
@test (:opt1 => 1) in opts
|
||||||
@test (:opt2 => "2") in opts
|
@test (:opt2 => "2") in opts
|
||||||
end
|
end
|
||||||
|
let opts = get_options("```julia{opt1 = 1, opt2 = \"2\"}\n```")
|
||||||
|
@test (:opt1 => 1) in opts
|
||||||
|
@test (:opt2 => "2") in opts
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -46,4 +46,14 @@ Core.eval(m, :(const a = $ary))
|
||||||
Weave.clear_module!(m)
|
Weave.clear_module!(m)
|
||||||
@test_broken Base.summarysize(m) < size
|
@test_broken Base.summarysize(m) < size
|
||||||
|
|
||||||
|
julia_markdown_body = """
|
||||||
|
this is just to test the `out_path` option
|
||||||
|
"""
|
||||||
|
|
||||||
|
f_in = tempname()
|
||||||
|
f_out = tempname() * ".md"
|
||||||
|
write(f_in, julia_markdown_body)
|
||||||
|
f = weave(f_in; out_path=f_out)
|
||||||
|
@test isfile(f_out)
|
||||||
|
|
||||||
end # @testset "clear_module!"
|
end # @testset "clear_module!"
|
||||||
|
|
|
@ -6,18 +6,18 @@
|
||||||
doc = mock_run("""
|
doc = mock_run("""
|
||||||
```julia
|
```julia
|
||||||
using DataFrames
|
using DataFrames
|
||||||
DataFrame(rand(10,3))
|
DataFrame(a=rand(10))
|
||||||
```
|
```
|
||||||
"""; doctype = "md2html")
|
"""; doctype = "md2html")
|
||||||
@test isdefined(doc.chunks[1], :rich_output)
|
@test isdefined(doc.chunks[1], :rich_output)
|
||||||
@test count("<tr>", doc.chunks[1].rich_output) == 12 # additonal 2 for name and type row
|
@test count("<tr", doc.chunks[1].rich_output) == 12 # additonal 2 for name and type row
|
||||||
|
|
||||||
# limit
|
# limit
|
||||||
n = 100000
|
n = 100000
|
||||||
doc = mock_run("""
|
doc = mock_run("""
|
||||||
```julia
|
```julia
|
||||||
using DataFrames
|
using DataFrames
|
||||||
DataFrame(rand($n,3))
|
DataFrame(a=rand($n))
|
||||||
```
|
```
|
||||||
"""; doctype = "md2html")
|
"""; doctype = "md2html")
|
||||||
@test isdefined(doc.chunks[1], :rich_output)
|
@test isdefined(doc.chunks[1], :rich_output)
|
||||||
|
|
Loading…
Reference in New Issue