Compare commits

..

No commits in common. "master" and "v0.10.3" have entirely different histories.

25 changed files with 193 additions and 186 deletions

View File

@ -15,7 +15,7 @@ jobs:
fail-fast: false # don't stop CI even when one of them fails
matrix:
version:
- '1.5'
- '1.4'
os:
- ubuntu-latest
- macOS-latest

View File

@ -3,7 +3,7 @@ language: julia
jobs:
include:
- stage: "Documentation"
julia: 1.5
julia: 1
os: linux
script:
- julia --project=doc/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'

15
NEWS.md
View File

@ -1,19 +1,6 @@
## Release notes for Weave.jl
### 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
### v0.10 - 2020/05/18
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)

View File

@ -1,6 +1,6 @@
name = "Weave"
uuid = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"
version = "0.10.12"
version = "0.10.3"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@ -12,17 +12,15 @@ Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
[compat]
Highlights = "0.3.1, 0.4, 0.5"
Highlights = "0.3.1, 0.4"
JSON = "0.21"
Mustache = "0.4.1, 0.5, 1"
Plots = "0.28, 0.29, 1.0"
RelocatableFolders = "0.1,0.2,0.3,1"
Requires = "1.0"
YAML = "0.3, 0.4"
julia = "1.2"

View File

@ -97,8 +97,3 @@ 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.
- [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.

View File

@ -39,11 +39,11 @@ Note that `Date` is available since the chunk is evaluated first.
---
title : Header Example
author : Shuhei Kadowaki
date: `j import Dates; Dates.Date(Dates.now())`
date: `j Date(now())`
---
```julia; echo = false
using Dates
using Datas
```
```

View File

@ -130,7 +130,7 @@ e.g. to include a Plots figure in markdown you can use:
```
or to produce any HTML output:
```
! display("text/html", HTML("Header from julia"));
! display("text/html", "Header from julia");
```
### Script Format
@ -165,12 +165,29 @@ See [Header Configuration](@ref) section for more details.
## Passing Runtime Arguments to Documents
You can pass arbitrary object to the weaved document using [`weave`](@ref)'s optional argument `args`.
It will be available as `WEAVE_ARGS` variable in the `weave`d document.
You can pass arguments as `Dict` to the weaved document using the `args` argument
to `weave`. The arguments will be available as `WEAVE_ARGS` variable in the document.
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.
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.
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`
In order to pass a filename to a document you need call `weave` using:
```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`

View File

@ -1,13 +1,14 @@
module Weave
using Highlights, Mustache, Requires, Pkg, REPL, RelocatableFolders, Base64
using Highlights, Mustache, Requires, Pkg, REPL
# directories
const PKG_DIR = normpath(@__DIR__, "..")
const TEMPLATE_DIR = @path joinpath(PKG_DIR, "templates")
const STYLESHEET_DIR = @path joinpath(PKG_DIR, "stylesheets")
const TEMPLATE_DIR = normpath(PKG_DIR, "templates")
const STYLESHEET_DIR = normpath(PKG_DIR, "stylesheets")
# keeps paths of sample documents for easy try
const EXAMPLE_FOLDER = @path joinpath(PKG_DIR, "examples")
const EXAMPLE_FOLDER = normpath(PKG_DIR, "examples")
# constant names
const WEAVE_OPTION_NAME = "weave_options"
@ -101,7 +102,7 @@ Weave an input document to output file.
* `:doc`: Path of the source document (default)
* `:pwd`: Julia working directory
* `"somepath"`: `String` of output directory e.g. `"~/outdir"`, or of filename e.g. `"~/outdir/outfile.tex"`
- `args::Any = Dict()`: A runtime object that is available as `WEAVE_ARGS` while `weave`ing
- `args::Dict = Dict()`: Arguments to be passed to the weaved document; will be available as `WEAVE_ARGS` in the document
- `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_ext::Union{Nothing,AbstractString} = nothing`: Extension for saved figures e.g. `".pdf"`, `".png"`. Default setting depends on `doctype`
@ -126,7 +127,7 @@ function weave(
doctype::Union{Nothing,AbstractString} = nothing,
informat::Union{Nothing,AbstractString} = nothing,
out_path::Union{Symbol,AbstractString} = :doc,
args::Any = Dict(),
args::Dict = Dict(),
mod::Union{Module,Nothing} = nothing,
fig_path::Union{Nothing,AbstractString} = nothing,
fig_ext::Union{Nothing,AbstractString} = nothing,
@ -243,16 +244,8 @@ function specific_options!(weave_options, doctype)
end
get_out_path(doc, out_path, ext::Nothing = nothing) = get_out_path(doc, out_path, doc.format.extension)
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
get_out_path(doc, out_path, ext) = abspath(get_cwd(doc, out_path), string(doc.basename , '.', ext))
"""
notebook(source::AbstractString; kwargs...)

View File

@ -5,11 +5,9 @@ using ..Weave: isnothing, take2string!
using Markdown
import Markdown: @trigger, @breaking, Code, MD, withstream, startswith, LaTeX
# HACK: that this definition is type-piracy. It is required since `Markdown`
# does not have a built in system for contextual rendering by users. `io` here
# 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)
# Note that this definition causes a "Method overwritten" warning,
# but defining this function in __init__() is not legal in julia v1.5
function Markdown.latex(io::IO, tex::Markdown.LaTeX)
math_envs = ["align", "equation", "eqnarray"]
use_dollars =
!any([occursin("\\begin{$me", tex.formula) for me in math_envs])

View File

@ -1,6 +1,6 @@
module WeavePlots
using ..Base64, ..Plots, ..Weave
using Base64, ..Plots, ..Weave
# Pre-execute hooks to set the plot size for the chunk
@ -17,7 +17,7 @@ function Base.display(
report::Weave.Report,
m::MIME"image/svg+xml",
data::Plots.Plot{Plots.PlotlyBackend},
)
)#
# Remove extra spaces from start of line for pandoc
s = repr(MIME("text/html"), data)
splitted = split(s, "\n")
@ -39,7 +39,7 @@ function Base.display(
report::Weave.Report,
m::MIME"image/png",
data::Plots.Plot{Plots.PlotlyBackend},
)
)#
display(report, MIME("image/svg+xml"), data)
end

View File

@ -5,7 +5,7 @@ function parse_markdown(document_body; is_pandoc = false)
r"^<<(?<options>.*?)>>=\s*$",
r"^@\s*$"
else
r"^[`~]{3}(\{?)julia\s*([;,\{]?)\s*(?<options>.*?)(\}|\s*)$",
r"^[`~]{3}(\{?)julia\s*([;,]?)\s*(?<options>.*?)(\}|\s*)$",
r"^[`~]{3}\s*$"
end
return header, parse_markdown_body(document_body, code_start, code_end, offset)

View File

@ -44,14 +44,18 @@ function render_chunk(docformat::WeaveFormat, chunk::CodeChunk)
chunk.content = render_code(docformat, chunk.content)
echo = chunk.options[:echo]
chunk.options[:eval] || return echo ? string(docformat.codestart, chunk.content, docformat.codeend) : ""
if !chunk.options[:eval]
return if chunk.options[:echo]
string(docformat.codestart, '\n', chunk.content, docformat.codeend)
else
""
end
end
if chunk.options[:term]
result = render_termchunk(docformat, chunk)
else
result = if echo
result = if chunk.options[:echo]
# Convert to output format and highlight (html, tex...) if needed
string(docformat.codestart, chunk.content, docformat.codeend, '\n')
else
@ -122,7 +126,7 @@ render_output(docformat::WeaveFormat, output) = output
function render_termchunk(docformat::WeaveFormat, chunk)
return if should_render(chunk)
string(docformat.termstart, chunk.output, docformat.termend)
string(docformat.termstart, chunk.output, '\n', docformat.termend, '\n')
else
""
end

View File

@ -1,24 +0,0 @@
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)

View File

@ -15,8 +15,8 @@ render_termchunk(docformat::HTMLFormat, chunk) =
Base.@kwdef mutable struct WeaveHTML <: HTMLFormat
description = "Weave-style HTML"
extension = "html"
codestart = '\n'
codeend = '\n'
codestart = "\n"
codeend = "\n"
termstart = codestart
termend = codeend
outputstart = "<pre class=\"output\">"
@ -124,9 +124,23 @@ end
# Pandoc
# ------
Base.@kwdef mutable struct Pandoc2HTML <: ExportFormat
Base.@kwdef mutable struct Pandoc2HTML <: HTMLFormat
description = "HTML via intermediate Pandoc Markdown (requires Pandoc 2)"
primaryformat = Pandoc()
extension = "md"
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
stylesheet_path = nothing
highlight_theme = nothing

View File

@ -4,12 +4,12 @@
Base.@kwdef mutable struct GitHubMarkdown <: WeaveFormat
description = "GitHub Markdown"
extension = "md"
codestart = "```julia"
codeend = "```\n"
codestart = "````julia"
codeend = "````\n\n"
termstart = codestart
termend = codeend
outputstart = "```"
outputend = "```\n\n"
outputstart = "````"
outputend = "````\n\n"
fig_ext = ".png"
mimetypes = ["image/png", "image/svg+xml", "image/jpg",
"text/markdown", "text/plain"]
@ -50,12 +50,12 @@ end
Base.@kwdef mutable struct Hugo <: WeaveFormat
description = "Hugo Markdown (using shortcodes)"
extension = "md"
codestart = "```julia"
codeend = "```\n"
codestart = "````julia"
codeend = "````\n\n"
termstart = codestart
termend = codeend
outputstart = "```"
outputend = "```\n\n"
outputstart = "````"
outputend = "````\n\n"
mimetypes = default_mime_types
fig_ext = ".png"
out_width = nothing
@ -88,12 +88,12 @@ end
Base.@kwdef mutable struct MultiMarkdown <: WeaveFormat
description = "MultiMarkdown"
extension = "md"
codestart = "```julia"
codeend = "```\n"
codestart = "````julia"
codeend = "````\n\n"
termstart = codestart
termend = codeend
outputstart = "```"
outputend = "```\n\n"
outputstart = "````"
outputend = "````\n\n"
mimetypes = default_mime_types
fig_ext = ".png"
out_width = nothing
@ -143,7 +143,7 @@ Base.@kwdef mutable struct Rest <: WeaveFormat
description = "reStructuredText and Sphinx"
extension = "rst"
codestart = ".. code-block:: julia\n"
codeend = "\n"
codeend = "\n\n"
termstart = codestart
termend = codeend
outputstart = "::\n"
@ -190,7 +190,7 @@ Base.@kwdef mutable struct AsciiDoc <: WeaveFormat
description = "AsciiDoc"
extension = "txt"
codestart = "[source,julia]\n--------------------------------------"
codeend = "--------------------------------------\n"
codeend = "--------------------------------------\n\n"
termstart = codestart
termend = codeend
outputstart = "--------------------------------------"

View File

@ -37,7 +37,7 @@ Base.@kwdef mutable struct Pandoc <: PandocFormat
description = "Pandoc Markdown"
extension = "md"
codestart = "~~~~{.julia}"
codeend = "~~~~~~~~~~~~~\n"
codeend = "~~~~~~~~~~~~~\n\n"
termstart = codestart
termend = codeend
outputstart = "~~~~"
@ -54,14 +54,28 @@ Base.@kwdef mutable struct Pandoc <: PandocFormat
end
register_format!("pandoc", Pandoc())
const DEFAULT_PANDOC_OPTIONS = String[]
Base.@kwdef mutable struct Pandoc2PDF <: ExportFormat
Base.@kwdef mutable struct Pandoc2PDF <: PandocFormat
description = "PDF via intermediate Pandoc Markdown"
primaryformat = Pandoc()
pandoc_options = DEFAULT_PANDOC_OPTIONS
extension = "md"
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
end
register_format!("pandoc2pdf", Pandoc2PDF())

View File

@ -23,9 +23,9 @@ function render_doc(doc::WeaveDoc)
return render_doc(docformat, body, doc)
end
include("exportformat.jl")
include("common.jl")
include("pandocformats.jl")
include("htmlformats.jl")
include("texformats.jl")
include("pandocformats.jl")
include("miscformats.jl")

View File

@ -34,10 +34,7 @@ render_output(docformat::LaTeXFormat, output) = unicode2latex(docformat, output,
render_code(docformat::LaTeXFormat, code) = unicode2latex(docformat, code, true)
render_termchunk(docformat::LaTeXFormat, chunk) =
string(docformat.termstart,
unicode2latex(docformat, chunk.output, true),
docformat.termend, "\n")
render_termchunk(docformat::LaTeXFormat, chunk) = string(docformat.termstart, chunk.output, docformat.termend, "\n")
# from julia symbols (e.g. "\bfhoge") to valid latex
const UNICODE2LATEX = let
@ -152,11 +149,11 @@ end
Base.@kwdef mutable struct LaTeXMinted <: LaTeXFormat
description = "LaTeX using minted package for code highlighting"
extension = "tex"
codestart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
codestart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
codeend = "\\end{minted}"
termstart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\footnotesize, xleftmargin=0.5em]{jlcon}"
termstart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\footnotesize, xleftmargin=0.5em]{jlcon}"
termend = "\\end{minted}"
outputstart = "\\begin{minted}[texcomments = true, mathescape, fontsize=\\small, xleftmargin=0.5em, frame = leftline]{text}"
outputstart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\small, xleftmargin=0.5em, frame = leftline]{text}"
outputend = "\\end{minted}"
mimetypes = ["application/pdf", "image/png", "text/latex", "text/plain"]
fig_ext = ".pdf"
@ -201,14 +198,8 @@ function render_code(docformat::WeaveLaTeXFormat, code)
unicode2latex(docformat, ret, false)
end
function render_termchunk(docformat::WeaveLaTeXFormat, chunk)
if should_render(chunk)
ret = highlight_term(MIME("text/latex"), chunk.output, docformat.highlight_theme)
unicode2latex(docformat, ret, true)
else
""
end
end
render_termchunk(docformat::WeaveLaTeXFormat, chunk) =
should_render(chunk) ? highlight_term(MIME("text/latex"), chunk.output, docformat.highlight_theme) : ""
function render_doc(docformat::WeaveLaTeXFormat, body, doc)
return Mustache.render(
@ -242,23 +233,44 @@ Base.@kwdef mutable struct WeaveLaTeX <: WeaveLaTeXFormat
tex_deps = ""
# how to escape latex in verbatim/code environment
escape_starter = "(*@"
escape_closer = "@*)"
escape_closer = reverse(escape_starter)
end
register_format!("md2tex", WeaveLaTeX())
# will be used by `write_doc`
const DEFAULT_LATEX_CMD = ["xelatex", "-shell-escape", "-halt-on-error"]
Base.@kwdef mutable struct LaTeX2PDF <: ExportFormat
primaryformat = WeaveLaTeX()
description = "PDF via LaTeX"
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", LaTeX2PDF())
register_format!("minted2pdf", LaTeX2PDF(primaryformat=LaTeXMinted()))
register_format!("md2pdf", WeaveLaTeX2PDF())
function set_format_options!(docformat::LaTeX2PDF; latex_cmd = DEFAULT_LATEX_CMD, _kwargs...)
function set_format_options!(docformat::WeaveLaTeX2PDF; template = nothing, highlight_theme = nothing, keep_unicode = false, latex_cmd = DEFAULT_LATEX_CMD, _kwargs...)
docformat.template =
get_mustache_template(isnothing(template) ? normpath(TEMPLATE_DIR, "md2pdf.tpl") : template)
docformat.highlight_theme = get_highlight_theme(highlight_theme)
docformat.keep_unicode |= keep_unicode
docformat.latex_cmd = latex_cmd
set_format_options!(docformat.primaryformat; _kwargs...)
end

View File

@ -7,7 +7,7 @@ function run_doc(
doc::WeaveDoc;
doctype::Union{Nothing,AbstractString} = nothing,
out_path::Union{Symbol,AbstractString} = :doc,
args::Any = Dict(),
args::Dict = Dict(),
mod::Union{Module,Nothing} = nothing,
fig_path::Union{Nothing,AbstractString} = nothing,
fig_ext::Union{Nothing,AbstractString} = nothing,
@ -20,9 +20,8 @@ function run_doc(
doc.format = deepcopy(get_format(doctype))
cwd = doc.cwd = get_cwd(doc, out_path)
mkpath(cwd)
isdir(cwd) || mkdir(cwd)
# TODO: provide a way not to create `fig_path` ?
if isnothing(fig_path)
fig_path = if (endswith(doctype, "2pdf") && cache === :off) || endswith(doctype, "2html")
basename(mktempdir(abspath(cwd)))
@ -30,7 +29,7 @@ function run_doc(
DEFAULT_FIG_PATH
end
end
mkpath(normpath(cwd, fig_path))
let d = normpath(cwd, fig_path); isdir(d) || mkdir(d); end
# This is needed for latex and should work on all output formats
@static Sys.iswindows() && (fig_path = replace(fig_path, "\\" => "/"))
set_rc_params(doc, fig_path, fig_ext)
@ -39,7 +38,7 @@ function run_doc(
# New sandbox for each document with args exposed
isnothing(mod) && (mod = sandbox = Core.eval(Main, :(module $(gensym(:WeaveSandBox)) end))::Module)
Core.eval(mod, :(WEAVE_ARGS = $(args)))
@eval mod WEAVE_ARGS = $args
mimetypes = doc.format.mimetypes
@ -90,8 +89,6 @@ function run_doc(
@info "Weaved all chunks" progress=1 _id=PROGRESS_ID
cd_back()
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
return doc
@ -142,17 +139,27 @@ function embed_figures!(chunk::CodeChunk, cwd)
chunk.figures[i] = img2base64(fig, cwd)
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)
ext = splitext(fig)[2]
f = open(joinpath(cwd, fig), "r")
raw = read(f)
close(f)
return ext == ".png" ? "data:image/png;base64," * stringmime(MIME("image/png"), raw) :
ext == ".svg" ? "data:image/svg+xml;base64," * stringmime(MIME("image/svg"), raw) :
ext == ".gif" ? "data:image/gif;base64," * stringmime(MIME("image/gif"), raw) :
fig
if ext == ".png"
return "data:image/png;base64," * stringmime(MIME("image/png"), raw)
elseif ext == ".svg"
return "data:image/svg+xml;base64," * stringmime(MIME("image/svg"), raw)
elseif ext == ".gif"
return "data:image/gif;base64," * stringmime(MIME("image/gif"), raw)
else
return (fig)
end
end
function run_chunk(chunk::DocChunk, doc, report, mod)
@ -218,7 +225,7 @@ function capture_output(code, mod, path, error, report)
task_local_storage(:SOURCE_PATH, path) do
try
obj = include_string(mod, code, path) # TODO: fix line number
!isnothing(obj) && !REPL.ends_with_semicolon(code) && display(obj)
!isnothing(obj) && display(obj)
catch _err
err = unwrap_load_err(_err)
error || throw(err)
@ -266,9 +273,15 @@ function eval_chunk(doc::WeaveDoc, chunk::CodeChunk, report::Report, mod::Module
execute_posthooks!(chunk)
return chunk.options[:term] ? collect_term_results(chunk) :
chunk.options[:hold] ? collect_hold_results(chunk) :
collect_results(chunk)
chunks = if chunk.options[:term]
collect_term_results(chunk)
elseif chunk.options[:hold]
collect_hold_results(chunk)
else
collect_results(chunk)
end
return chunks
end
# Hooks to run before and after chunks, this is form IJulia,
@ -279,11 +292,7 @@ function pop_preexecution_hook!(f::Function)
isnothing(i) && error("this function has not been registered in the pre-execution hook yet")
return splice!(preexecution_hooks, i)
end
function execute_prehooks!(chunk::CodeChunk)
for prehook in preexecution_hooks
Base.invokelatest(prehook, chunk)
end
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)
@ -292,11 +301,7 @@ function pop_postexecution_hook!(f::Function)
isnothing(i) && error("this function has not been registered in the post-execution hook yet")
return splice!(postexecution_hooks, i)
end
function execute_posthooks!(chunk::CodeChunk)
for posthook in postexecution_hooks
Base.invokelatest(posthook, chunk)
end
end
execute_posthooks!(chunk::CodeChunk) = for posthook in postexecution_hooks; Base.invokelatest(posthook, chunk); end
"""
clear_module!(mod::Module)
@ -335,7 +340,11 @@ function get_figname(report::Report, chunk; fignum = nothing, ext = nothing)
end
function set_rc_params(doc::WeaveDoc, fig_path, fig_ext)
doc.chunk_defaults[:fig_ext] = isnothing(fig_ext) ? doc.format.fig_ext : fig_ext
if isnothing(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
end
@ -343,9 +352,11 @@ function collect_results(chunk::CodeChunk)
content = ""
result_chunks = CodeChunk[]
for r in chunk.result
content *= r.code
# Check if there is any output from chunk
if any(!isempty strip, (r.stdout, r.rich_output)) || !isempty(r.figures)
if strip(r.stdout) == "" && isempty(r.figures) && strip(r.rich_output) == ""
content *= r.code
else
content = "\n" * content * r.code
rchunk = CodeChunk(
content,
chunk.number,
@ -353,14 +364,15 @@ function collect_results(chunk::CodeChunk)
chunk.optionstring,
copy(chunk.options),
)
content = ""
rchunk.figures = r.figures
rchunk.output = r.stdout
rchunk.rich_output = r.rich_output
rchunk.figures = r.figures
push!(result_chunks, rchunk)
content = ""
end
end
if !isempty(content)
startswith(content, "\n") || (content = "\n" * content)
rchunk = CodeChunk(
content,
chunk.number,

View File

@ -1,4 +1,4 @@
function write_doc(docformat::LaTeX2PDF, doc, rendered, out_path)
function write_doc(docformat::WeaveLaTeX2PDF, doc, rendered, out_path)
cd_back = let d = pwd(); () -> cd(d); end
cd(doc.cwd)
try

View File

@ -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
$filt $citeproc $(docformat.pandoc_options)
--include-in-header=$(docformat.header_template)
-o $(out)`
-V fontsize=12pt -o $(out)`
proc = open(cmd, "r+")
println(proc.in, rendered)
close(proc.in)

View File

@ -3,7 +3,7 @@ using Weave.Dates
test_doctypes = filter(first.(Weave.list_out_formats())) do doctype
# don't test doctypes which need external programs
doctype ("pandoc2html", "pandoc2pdf", "md2pdf", "minted2pdf")
doctype ("pandoc2html", "pandoc2pdf", "md2pdf")
end
function test_func(body)
@ -24,6 +24,7 @@ using Dates
Date(now())
```
"""
for doctype in test_doctypes
test_mock_weave(test_func, julia_markdown_body; informat = "markdown", doctype = doctype)
end

View File

@ -72,10 +72,6 @@ let opts = get_options("```julia, opt1 = 1, opt2 = \"2\"\n```")
@test (:opt1 => 1) in opts
@test (:opt2 => "2") in opts
end
let opts = get_options("```julia{opt1 = 1, opt2 = \"2\"}\n```")
@test (:opt1 => 1) in opts
@test (:opt2 => "2") in opts
end
end

View File

@ -46,14 +46,4 @@ Core.eval(m, :(const a = $ary))
Weave.clear_module!(m)
@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!"

View File

@ -6,18 +6,18 @@
doc = mock_run("""
```julia
using DataFrames
DataFrame(a=rand(10))
DataFrame(rand(10,3))
```
"""; doctype = "md2html")
@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
n = 100000
doc = mock_run("""
```julia
using DataFrames
DataFrame(a=rand($n))
DataFrame(rand($n,3))
```
"""; doctype = "md2html")
@test isdefined(doc.chunks[1], :rich_output)