Browse Source

Apply Runic formatting

pull/266/head
Fredrik Ekre 12 months ago
parent
commit
2964c2758d
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 23
      .github/workflows/Check.yml
  2. 2
      README.md
  3. 4
      docs/make.jl
  4. 4
      docs/src/outputformats.jl
  5. 2
      examples/README.jl
  6. 6
      examples/example.jl
  7. 6
      src/IJulia.jl
  8. 177
      src/Literate.jl
  9. 498
      test/runtests.jl

23
.github/workflows/Check.yml

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
---
name: Check
on:
push:
branches:
- 'master'
- 'release-'
tags:
- '*'
pull_request:
jobs:
runic:
name: Runic formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1.11'
- uses: julia-actions/cache@v2
- uses: fredrikekre/runic-action@v1
with:
version: '1.2'

2
README.md

@ -21,7 +21,7 @@ running these commands from the package root of Literate.jl: @@ -21,7 +21,7 @@ running these commands from the package root of Literate.jl:
````julia
using Literate
Literate.markdown("examples/README.jl", "."; flavor=Literate.CommonMarkFlavor())
Literate.markdown("examples/README.jl", "."; flavor = Literate.CommonMarkFlavor())
````
### Related packages

4
docs/make.jl

@ -5,7 +5,7 @@ if haskey(ENV, "GITHUB_ACTIONS") @@ -5,7 +5,7 @@ if haskey(ENV, "GITHUB_ACTIONS")
end
deployconfig = Documenter.auto_detect_deploy_system()
Documenter.post_status(deployconfig; type="pending", repo="github.com/fredrikekre/Literate.jl.git")
Documenter.post_status(deployconfig; type = "pending", repo = "github.com/fredrikekre/Literate.jl.git")
using Literate
using Plots # to not capture precompilation output
@ -14,7 +14,7 @@ EXAMPLE = joinpath(@__DIR__, "..", "examples", "example.jl") @@ -14,7 +14,7 @@ EXAMPLE = joinpath(@__DIR__, "..", "examples", "example.jl")
OUTPUT = joinpath(@__DIR__, "src/generated")
function preprocess(str)
str = replace(str, "x = 123" => "y = 321"; count=1)
str = replace(str, "x = 123" => "y = 321"; count = 1)
return str
end

4
docs/src/outputformats.jl

@ -3,9 +3,9 @@ @@ -3,9 +3,9 @@
# In julia rational numbers can be constructed with the `//` operator.
# Lets define two rational numbers, `x` and `y`:
x = 1//3
x = 1 // 3
#-
y = 2//5
y = 2 // 5
# When adding `x` and `y` together we obtain a new rational number:

2
examples/README.jl

@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
# running these commands from the package root of Literate.jl:
using Literate
Literate.markdown("examples/README.jl", "."; flavor=Literate.CommonMarkFlavor())
Literate.markdown("examples/README.jl", "."; flavor = Literate.CommonMarkFlavor())
# ### Related packages

6
examples/example.jl

@ -33,8 +33,8 @@ @@ -33,8 +33,8 @@
# as markdown, and all the other lines are interpreted as code. Here is some code:
#nb %% A slide [code] {"slideshow": {"slide_type": "fragment"}}
x = 1//3
y = 2//5
x = 1 // 3
y = 2 // 5
#nb # %% A slide [markdown] {"slideshow": {"slide_type": "subslide"}}
# In markdown sections we can use markdown syntax. For example, we can
@ -96,7 +96,7 @@ foo() @@ -96,7 +96,7 @@ foo()
#nb %% A slide [code] {"slideshow": {"slide_type": "subslide"}}
using Plots
x = range(0, stop=6π, length=1000)
x = range(0, stop = 6π, length = 1000)
y1 = sin.(x)
y2 = cos.(x)
plot(x, [y1, y2])

6
src/IJulia.jl

@ -17,7 +17,7 @@ const application_vnd_vegalite_v2 = MIME("application/vnd.vegalite.v2+json") @@ -17,7 +17,7 @@ const application_vnd_vegalite_v2 = MIME("application/vnd.vegalite.v2+json")
# return a String=>String dictionary of mimetype=>data
# for passing to Jupyter display_data and execute_result messages.
function display_dict(x)
data = Dict{String,Any}("text/plain" => limitstringmime(text_plain, x))
data = Dict{String, Any}("text/plain" => limitstringmime(text_plain, x))
if showable(application_vnd_vegalite_v2, x)
data[string(application_vnd_vegalite_v2)] = JSON.parse(limitstringmime(application_vnd_vegalite_v2, x))
end
@ -57,14 +57,14 @@ function limitstringmime(mime::MIME, x) @@ -57,14 +57,14 @@ function limitstringmime(mime::MIME, x)
if israwtext(mime, x)
return String(x)
else
show(IOContext(buf, :limit=>true, :color=>true), mime, x)
show(IOContext(buf, :limit => true, :color => true), mime, x)
end
else
b64 = Base64EncodePipe(buf)
if isa(x, Vector{UInt8})
write(b64, x) # x assumed to be raw binary data
else
show(IOContext(b64, :limit=>true, :color=>true), mime, x)
show(IOContext(b64, :limit => true, :color => true), mime, x)
end
close(b64)
end

177
src/Literate.jl

@ -39,7 +39,7 @@ struct QuartoFlavor <: AbstractFlavor end @@ -39,7 +39,7 @@ struct QuartoFlavor <: AbstractFlavor end
# Parser
abstract type Chunk end
struct MDChunk <: Chunk
lines::Vector{Pair{String,String}} # indent and content
lines::Vector{Pair{String, String}} # indent and content
end
MDChunk() = MDChunk(String[])
mutable struct CodeChunk <: Chunk
@ -133,12 +133,10 @@ function parse(flavor::AbstractFlavor, content; allow_continued = true) @@ -133,12 +133,10 @@ function parse(flavor::AbstractFlavor, content; allow_continued = true)
return chunks
end
function replace_default(content, sym;
config::Dict,
branch = "gh-pages",
commit = "master"
function replace_default(
content, sym; config::Dict, branch = "gh-pages", commit = "master"
)
repls = Pair{Any,Any}[]
repls = Pair{Any, Any}[]
# add some shameless advertisement
if config["credit"]::Bool
@ -168,7 +166,7 @@ function replace_default(content, sym; @@ -168,7 +166,7 @@ function replace_default(content, sym;
newlines = sprint() do io
foreach(l -> println(io, "# ", l), eachline(IOBuffer(m[1])))
end
str = replace(str, multiline_r => chop(newlines); count=1)
str = replace(str, multiline_r => chop(newlines); count = 1)
end
return str
end
@ -229,7 +227,7 @@ function replace_default(content, sym; @@ -229,7 +227,7 @@ function replace_default(content, sym;
push!(repls, r"\[([^]]+?)\]\(@id .*?\)"s => s"\1") # [foo](@id bar) => foo
# Convert Documenter admonitions to markdown quotes
r = r"^# !!! (?<type>\w+)(?: \"(?<title>.+)\")?(?<lines>(\v^# .*$)+)"m
adm_to_quote = function(s)
adm_to_quote = function (s)
m = match(r, s)::RegexMatch
io = IOBuffer()
print(io, "# > **")
@ -259,11 +257,13 @@ end @@ -259,11 +257,13 @@ end
filename(str) = first(splitext(last(splitdir(str))))
isdocumenter(cfg) = cfg["flavor"]::AbstractFlavor isa DocumenterFlavor
_DEFAULT_IMAGE_FORMATS = [(MIME("image/svg+xml"), ".svg"), (MIME("image/png"), ".png"),
(MIME("image/jpeg"), ".jpeg")]
_DEFAULT_IMAGE_FORMATS = [
(MIME("image/svg+xml"), ".svg"), (MIME("image/png"), ".png"),
(MIME("image/jpeg"), ".jpeg"),
]
# Cache of inputfile => head branch
const HEAD_BRANCH_CACHE = Dict{String,String}()
const HEAD_BRANCH_CACHE = Dict{String, String}()
# Guess the package (or repository) root url with "master" as fallback
# see JuliaDocs/Documenter.jl#1751
@ -277,8 +277,8 @@ function edit_commit(inputfile, user_config) @@ -277,8 +277,8 @@ function edit_commit(inputfile, user_config)
git_root = try
readchomp(
pipeline(
setenv(`$(git) rev-parse --show-toplevel`; dir=dirname(inputfile));
stderr=devnull,
setenv(`$(git) rev-parse --show-toplevel`; dir = dirname(inputfile));
stderr = devnull,
)
)
catch
@ -298,8 +298,8 @@ function edit_commit(inputfile, user_config) @@ -298,8 +298,8 @@ function edit_commit(inputfile, user_config)
str = try
read(
pipeline(
setenv(`$(git) remote show origin`, env; dir=dirname(inputfile)),
stderr=devnull,
setenv(`$(git) remote show origin`, env; dir = dirname(inputfile)),
stderr = devnull,
),
String,
)
@ -332,30 +332,38 @@ function pick_codefence(::QuartoFlavor, execute::Bool, name::AbstractString) @@ -332,30 +332,38 @@ function pick_codefence(::QuartoFlavor, execute::Bool, name::AbstractString)
return "```{julia}" => "```"
end
function create_configuration(inputfile; user_config, user_kwargs, type=nothing)
function create_configuration(inputfile; user_config, user_kwargs, type = nothing)
# Combine user config with user kwargs
user_config = Dict{String,Any}(string(k) => v for (k, v) in user_config)
user_kwargs = Dict{String,Any}(string(k) => v for (k, v) in user_kwargs)
user_config = Dict{String, Any}(string(k) => v for (k, v) in user_config)
user_kwargs = Dict{String, Any}(string(k) => v for (k, v) in user_kwargs)
user_config = merge!(user_config, user_kwargs)
# deprecation of documenter kwarg
if (d = get(user_config, "documenter", nothing); d !== nothing)
if type === :md
Base.depwarn("The documenter=$(d) keyword to Literate.markdown is deprecated." *
Base.depwarn(
"The documenter=$(d) keyword to Literate.markdown is deprecated." *
" Pass `flavor = Literate.$(d ? "DocumenterFlavor" : "CommonMarkFlavor")()`" *
" instead.", Symbol("Literate.markdown"))
" instead.", Symbol("Literate.markdown")
)
user_config["flavor"] = d ? DocumenterFlavor() : CommonMarkFlavor()
elseif type === :nb
Base.depwarn("The documenter=$(d) keyword to Literate.notebook is deprecated." *
" It is not used anymore for notebook output.", Symbol("Literate.notebook"))
Base.depwarn(
"The documenter=$(d) keyword to Literate.notebook is deprecated." *
" It is not used anymore for notebook output.",
Symbol("Literate.notebook")
)
elseif type === :jl
Base.depwarn("The documenter=$(d) keyword to Literate.script is deprecated." *
" It is not used anymore for script output.", Symbol("Literate.script"))
Base.depwarn(
"The documenter=$(d) keyword to Literate.script is deprecated." *
" It is not used anymore for script output.",
Symbol("Literate.script")
)
end
end
# Add default config
cfg = Dict{String,Any}()
cfg = Dict{String, Any}()
cfg["name"] = filename(inputfile)
cfg["preprocess"] = identity
cfg["postprocess"] = identity
@ -479,12 +487,13 @@ Available options: @@ -479,12 +487,13 @@ Available options:
`$(_DEFAULT_IMAGE_FORMATS)`. Results which are `showable` with a MIME type are saved with
the first match, with the corresponding extension.
"""
const DEFAULT_CONFIGURATION=nothing # Dummy const for documentation
const DEFAULT_CONFIGURATION = nothing # Dummy const for documentation
function preprocessor(inputfile, outputdir; user_config, user_kwargs, type)
# Create configuration by merging default and userdefined
config = create_configuration(inputfile; user_config=user_config,
user_kwargs=user_kwargs, type=type)
config = create_configuration(
inputfile; user_config = user_config, user_kwargs = user_kwargs, type = type
)
# Quarto output does not support execute = true
if config["flavor"] isa QuartoFlavor && config["execute"]
@ -526,16 +535,17 @@ function preprocessor(inputfile, outputdir; user_config, user_kwargs, type) @@ -526,16 +535,17 @@ function preprocessor(inputfile, outputdir; user_config, user_kwargs, type)
# change the Edit on GitHub link
edit_url = relpath(inputfile, config["literate_outputdir"])
edit_url = replace(edit_url, "\\" => "/")
content = """
meta_block = """
# ```@meta
# EditURL = "$(edit_url)"
# ```
""" * content
"""
content = meta_block * content
end
# default replacements
content = replace_default(content, type; config=config)
content = replace_default(content, type; config = config)
# parse the content into chunks
chunks = parse(config["flavor"], content; allow_continued = type !== :nb)
@ -543,7 +553,7 @@ function preprocessor(inputfile, outputdir; user_config, user_kwargs, type) @@ -543,7 +553,7 @@ function preprocessor(inputfile, outputdir; user_config, user_kwargs, type)
return chunks, config
end
function write_result(content, config; print=print)
function write_result(content, config; print = print)
outputfile = config["literate_outputfile"]
@info "writing result to `$(Base.contractuser(outputfile))`"
open(outputfile, "w") do io
@ -560,10 +570,10 @@ Generate a plain script file from `inputfile` and write the result to `outputdir @@ -560,10 +570,10 @@ Generate a plain script file from `inputfile` and write the result to `outputdir
See the manual section on [Configuration](@ref) for documentation
of possible configuration with `config` and other keyword arguments.
"""
function script(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwargs...)
function script(inputfile, outputdir = pwd(); config::AbstractDict = Dict(), kwargs...)
# preprocessing and parsing
chunks, config =
preprocessor(inputfile, outputdir; user_config=config, user_kwargs=kwargs, type=:jl)
preprocessor(inputfile, outputdir; user_config = config, user_kwargs = kwargs, type = :jl)
# create the script file
ioscript = IOBuffer()
@ -600,10 +610,10 @@ to the directory `outputdir`. @@ -600,10 +610,10 @@ to the directory `outputdir`.
See the manual section on [Configuration](@ref) for documentation
of possible configuration with `config` and other keyword arguments.
"""
function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwargs...)
function markdown(inputfile, outputdir = pwd(); config::AbstractDict = Dict(), kwargs...)
# preprocessing and parsing
chunks, config =
preprocessor(inputfile, outputdir; user_config=config, user_kwargs=kwargs, type=:md)
preprocessor(inputfile, outputdir; user_config = config, user_kwargs = kwargs, type = :md)
# create the markdown file
sb = sandbox()
@ -637,15 +647,16 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg @@ -637,15 +647,16 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg
any(write_line, chunk.lines) && write(iomd, seekstart(iocode))
if execute
cd(config["literate_outputdir"]) do
execute_markdown!(iomd, sb, join(chunk.lines, '\n'),
execute_markdown!(
iomd, sb, join(chunk.lines, '\n'),
config["literate_outputdir"];
inputfile=config["literate_inputfile"],
fake_source=config["literate_outputfile"],
flavor=config["flavor"],
image_formats=config["image_formats"],
file_prefix="$(config["name"])-$(chunknum)",
softscope=config["softscope"],
continue_on_error=config["continue_on_error"],
inputfile = config["literate_inputfile"],
fake_source = config["literate_outputfile"],
flavor = config["flavor"],
image_formats = config["image_formats"],
file_prefix = "$(config["name"])-$(chunknum)",
softscope = config["softscope"],
continue_on_error = config["continue_on_error"],
)
end
end
@ -661,13 +672,17 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg @@ -661,13 +672,17 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg
return outputfile
end
function execute_markdown!(io::IO, sb::Module, block::String, outputdir;
inputfile::String, fake_source::String,
flavor::AbstractFlavor, image_formats::Vector, file_prefix::String,
softscope::Bool, continue_on_error::Bool)
function execute_markdown!(
io::IO, sb::Module, block::String, outputdir;
inputfile::String, fake_source::String, flavor::AbstractFlavor,
image_formats::Vector, file_prefix::String, softscope::Bool,
continue_on_error::Bool
)
# TODO: Deal with explicit display(...) calls
r, str, _ = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source,
softscope=softscope, continue_on_error=continue_on_error)
r, str, _ = execute_block(
sb, block; inputfile = inputfile, fake_source = fake_source,
softscope = softscope, continue_on_error = continue_on_error
)
# issue #101: consecutive codefenced blocks need newline
# issue #144: quadruple backticks allow for triple backticks in the output
plain_fence = "\n````\n" => "\n````"
@ -731,16 +746,16 @@ Generate a notebook from `inputfile` and write the result to `outputdir`. @@ -731,16 +746,16 @@ Generate a notebook from `inputfile` and write the result to `outputdir`.
See the manual section on [Configuration](@ref) for documentation
of possible configuration with `config` and other keyword arguments.
"""
function notebook(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwargs...)
function notebook(inputfile, outputdir = pwd(); config::AbstractDict = Dict(), kwargs...)
# preprocessing and parsing
chunks, config =
preprocessor(inputfile, outputdir; user_config=config, user_kwargs=kwargs, type=:nb)
preprocessor(inputfile, outputdir; user_config = config, user_kwargs = kwargs, type = :nb)
# create the notebook
nb = jupyter_notebook(chunks, config)
# write to file
outputfile = write_result(nb, config; print = (io, c)->JSON.print(io, c, 1))
outputfile = write_result(nb, config; print = (io, c) -> JSON.print(io, c, 1))
return outputfile
end
@ -761,10 +776,12 @@ function jupyter_notebook(chunks, config) @@ -761,10 +776,12 @@ function jupyter_notebook(chunks, config)
else
metadata = Dict{String, Any}()
end
lines = isa(chunk, MDChunk) ?
String[x.second for x in chunk.lines] : # skip indent
chunk.lines
@views map!(x -> x * '\n', lines[1:end-1], lines[1:end-1])
if isa(chunk, MDChunk)
lines = String[x.second for x in chunk.lines] # skip indent
else
lines = chunk.lines
end
@views map!(x -> x * '\n', lines[1:(end - 1)], lines[1:(end - 1)])
cell["cell_type"] = chunktype
cell["metadata"] = metadata
cell["source"] = lines
@ -788,7 +805,7 @@ function jupyter_notebook(chunks, config) @@ -788,7 +805,7 @@ function jupyter_notebook(chunks, config)
language_info = Dict()
language_info["file_extension"] = ".jl"
language_info["mimetype"] = "application/julia"
language_info["name"]= "julia"
language_info["name"] = "julia"
language_info["version"] = string(VERSION)
metadata["language_info"] = language_info
@ -801,11 +818,12 @@ function jupyter_notebook(chunks, config) @@ -801,11 +818,12 @@ function jupyter_notebook(chunks, config)
@info "executing notebook `$(config["name"] * ".ipynb")`"
try
cd(config["literate_outputdir"]) do
nb = execute_notebook(nb; inputfile=config["literate_inputfile"],
fake_source=config["literate_outputfile"],
softscope=config["softscope"],
continue_on_error=config["continue_on_error"],
)
nb = execute_notebook(
nb; inputfile = config["literate_inputfile"],
fake_source = config["literate_outputfile"],
softscope = config["softscope"],
continue_on_error = config["continue_on_error"],
)
end
catch err
@error "error when executing notebook based on input file: " *
@ -816,8 +834,10 @@ function jupyter_notebook(chunks, config) @@ -816,8 +834,10 @@ function jupyter_notebook(chunks, config)
return nb
end
function execute_notebook(nb; inputfile::String, fake_source::String, softscope::Bool,
continue_on_error=continue_on_error)
function execute_notebook(
nb; inputfile::String, fake_source::String, softscope::Bool,
continue_on_error = continue_on_error
)
sb = sandbox()
execution_count = 0
for cell in nb["cells"]
@ -825,13 +845,14 @@ function execute_notebook(nb; inputfile::String, fake_source::String, softscope: @@ -825,13 +845,14 @@ function execute_notebook(nb; inputfile::String, fake_source::String, softscope:
execution_count += 1
cell["execution_count"] = execution_count
block = join(cell["source"])
r, str, display_dicts = execute_block(sb, block; inputfile=inputfile,
fake_source=fake_source, softscope=softscope,
continue_on_error=continue_on_error)
r, str, display_dicts = execute_block(
sb, block; inputfile = inputfile, fake_source = fake_source,
softscope = softscope, continue_on_error = continue_on_error
)
# str should go into stream
if !isempty(str)
stream = Dict{String,Any}()
stream = Dict{String, Any}()
stream["output_type"] = "stream"
stream["name"] = "stdout"
stream["text"] = collect(Any, eachline(IOBuffer(String(str)), keep = true))
@ -852,7 +873,7 @@ function execute_notebook(nb; inputfile::String, fake_source::String, softscope: @@ -852,7 +873,7 @@ function execute_notebook(nb; inputfile::String, fake_source::String, softscope:
# Any explicit calls to display(...)
for dict in display_dicts
display_data = Dict{String,Any}()
display_data = Dict{String, Any}()
display_data["output_type"] = "display_data"
display_data["metadata"] = Dict()
display_data["data"] = split_mime(dict)
@ -864,7 +885,7 @@ function execute_notebook(nb; inputfile::String, fake_source::String, softscope: @@ -864,7 +885,7 @@ function execute_notebook(nb; inputfile::String, fake_source::String, softscope:
# r should go into execute_result
if r !== nothing
execute_result = Dict{String,Any}()
execute_result = Dict{String, Any}()
execute_result["output_type"] = "execute_result"
execute_result["metadata"] = Dict()
execute_result["execution_count"] = execution_count
@ -899,7 +920,7 @@ end @@ -899,7 +920,7 @@ end
# TODO: Problematic to accept mime::MIME here?
function Base.display(ld::LiterateDisplay, mime::MIME, x)
r = Base.invokelatest(IJulia.limitstringmime, mime, x)
display_dicts = Dict{String,Any}(string(mime) => r)
display_dicts = Dict{String, Any}(string(mime) => r)
# TODO: IJulia does this part below for unknown mimes
# if istextmime(mime)
# display_dicts["text/plain"] = r
@ -909,8 +930,10 @@ function Base.display(ld::LiterateDisplay, mime::MIME, x) @@ -909,8 +930,10 @@ function Base.display(ld::LiterateDisplay, mime::MIME, x)
end
# Execute a code-block in a module and capture stdout/stderr and the result
function execute_block(sb::Module, block::String; inputfile::String, fake_source::String,
softscope::Bool, continue_on_error::Bool)
function execute_block(
sb::Module, block::String; inputfile::String, fake_source::String,
softscope::Bool, continue_on_error::Bool
)
@debug """execute_block($sb, block)
```
$(block)
@ -945,14 +968,16 @@ function execute_block(sb::Module, block::String; inputfile::String, fake_source @@ -945,14 +968,16 @@ function execute_block(sb::Module, block::String; inputfile::String, fake_source
all_output = c.output * "\n\nERROR: " * sprint(showerror, err)
return nothing, all_output, disp.data
else
error("""
error(
"""
$(sprint(showerror, c.value))
when executing the following code block from inputfile `$(Base.contractuser(inputfile))`
```julia
$block
```
""")
"""
)
end
end
return c.value, c.output, disp.data

498
test/runtests.jl

@ -23,6 +23,7 @@ function compare_chunks(chunks1, chunks2) @@ -23,6 +23,7 @@ function compare_chunks(chunks1, chunks2)
@test c1.continued == c2.continued
end
end
return
end
@testset "Literate.parse" begin
@ -115,8 +116,8 @@ end @@ -115,8 +116,8 @@ end
expected_chunks = Chunk[
MDChunk(["" => "Line 1"]),
CodeChunk(["Line 2"], false),
MDChunk(["" => "Line 3", "" => "","" => "Line 5"]),
CodeChunk(["Line 6", "","Line 8"], false),
MDChunk(["" => "Line 3", "" => "", "" => "Line 5"]),
CodeChunk(["Line 6", "", "Line 8"], false),
MDChunk(["" => "Line 9"]),
MDChunk(["" => "Line 11"]),
CodeChunk(["Line 12"], false),
@ -149,7 +150,7 @@ end @@ -149,7 +150,7 @@ end
CodeChunk(["# Line 73", "#", "# Line 75"], false),
CodeChunk([" # Line 77", " #", " # Line 79"], false),
MDChunk(["" => "Line 80: Quarto Specific"]),
CodeChunk(["##| Line 81"], false)
CodeChunk(["##| Line 81"], false),
]
parsed_chunks = Literate.parse(DefaultFlavor(), content)
compare_chunks(parsed_chunks, expected_chunks)
@ -158,8 +159,8 @@ end @@ -158,8 +159,8 @@ end
expected_chunks_quarto = Chunk[
MDChunk(["" => "Line 1"]),
CodeChunk(["Line 2"], false),
MDChunk(["" => "Line 3", "" => "","" => "Line 5"]),
CodeChunk(["Line 6", "","Line 8"], false),
MDChunk(["" => "Line 3", "" => "", "" => "Line 5"]),
CodeChunk(["Line 6", "", "Line 8"], false),
MDChunk(["" => "Line 9"]),
MDChunk(["" => "Line 11"]),
CodeChunk(["Line 12"], false),
@ -192,7 +193,7 @@ end @@ -192,7 +193,7 @@ end
CodeChunk(["# Line 73", "#", "# Line 75"], false),
CodeChunk([" # Line 77", " #", " # Line 79"], false),
MDChunk(["" => "Line 80: Quarto Specific"]),
CodeChunk(["#| Line 81"], false) # parses correctly as code cell command
CodeChunk(["#| Line 81"], false), # parses correctly as code cell command
]
parsed_chunks = Literate.parse(QuartoFlavor(), content)
compare_chunks(parsed_chunks, expected_chunks_quarto)
@ -202,8 +203,8 @@ end @@ -202,8 +203,8 @@ end
iows = IOBuffer()
for c in expected_chunks
if isa(c, CodeChunk)
foreach(x-> println(io, x), c.lines)
foreach(x-> println(iows, x, " "), c.lines)
foreach(x -> println(io, x), c.lines)
foreach(x -> println(iows, x, " "), c.lines)
else
foreach(x -> println(io, "# ", x), c.lines)
foreach(x -> println(iows, "# ", x, " "), c.lines)
@ -218,111 +219,111 @@ end @@ -218,111 +219,111 @@ end
end # testset parser
content = """
# # [Example](@id example-id)
# [foo](@ref), [bar](@ref bbaarr)
# [baz](@extref), [bax](@extref bbaaxx)
x = 1
#md # Only markdown
# Only markdown #md
#md x + 1
x + 1 #md
#!md # Not markdown
# Not markdown #!md
#!md x * 1
x * 1 #!md
#nb # Only notebook
# Only notebook #nb
#nb x + 2
x + 2 #nb
#!nb # Not notebook
# Not notebook #!nb
#!nb x * 2
x * 2 #!nb
#jl # Only script
# Only script #jl
#jl x + 3
x + 3 #jl
#!jl # Not script
# Not script #!jl
#!jl x * 3
x * 3 #!jl
#src # Source code only
Source code only #src
## # Comment
## another comment
#-
for i in 1:10
# # [Example](@id example-id)
# [foo](@ref), [bar](@ref bbaarr)
# [baz](@extref), [bax](@extref bbaaxx)
x = 1
#md # Only markdown
# Only markdown #md
#md x + 1
x + 1 #md
#!md # Not markdown
# Not markdown #!md
#!md x * 1
x * 1 #!md
#nb # Only notebook
# Only notebook #nb
#nb x + 2
x + 2 #nb
#!nb # Not notebook
# Not notebook #!nb
#!nb x * 2
x * 2 #!nb
#jl # Only script
# Only script #jl
#jl x + 3
x + 3 #jl
#!jl # Not script
# Not script #!jl
#!jl x * 3
x * 3 #!jl
#src # Source code only
Source code only #src
## # Comment
## another comment
#-
for i in 1:10
print(i)
# some markdown in a code block
#+
end
# name: @__NAME__
# Link to repo root: @__REPO_ROOT_URL__/file.jl
# Link to nbviewer: @__NBVIEWER_ROOT_URL__/file.jl
# Link to binder: @__BINDER_ROOT_URL__/file.jl
## name: @__NAME__
## Link to repo root: @__REPO_ROOT_URL__/file.jl
## Link to nbviewer: @__NBVIEWER_ROOT_URL__/file.jl
## Link to binder: @__BINDER_ROOT_URL__/file.jl
# PLACEHOLDER1
# PLACEHOLDER2
## PLACEHOLDER3
## PLACEHOLDER4
# Some inline math: ``\\frac{df}{dx}``, some multiline inline math: ``y =
# kx + m``, and some display math:
# ```math
# \\int f(x) dx
# ```
#-
# some markdown in a code block
#+
end
# name: @__NAME__
# Link to repo root: @__REPO_ROOT_URL__/file.jl
# Link to nbviewer: @__NBVIEWER_ROOT_URL__/file.jl
# Link to binder: @__BINDER_ROOT_URL__/file.jl
## name: @__NAME__
## Link to repo root: @__REPO_ROOT_URL__/file.jl
## Link to nbviewer: @__NBVIEWER_ROOT_URL__/file.jl
## Link to binder: @__BINDER_ROOT_URL__/file.jl
# PLACEHOLDER1
# PLACEHOLDER2
## PLACEHOLDER3
## PLACEHOLDER4
# Some inline math: ``\\frac{df}{dx}``, some multiline inline math: ``y =
# kx + m``, and some display math:
# ```math
# \\int f(x) dx
# ```
#-
# Indented markdown
for i in 1:10
for i in 1:10
# Indented markdown
#+
#+
## Indented comment
end
# Some inline html
# ```@raw html
# <a href="https://github.com/fredrikekre/Literate.jl">Literate.jl</a>
# ```
# Semicolon output supression
1 + 1;
# Completely hidden
hidden = 12 #hide
hidden * hidden #hide
# Partially hidden
hidden2 = 12 #hide
hidden2 * hidden2
#nb # A notebook cell with special metadata
#nb %% Meta1 {"meta": "data"}
#nb 1+1
#nb #-
#nb # A explicit code notebook cell
#nb #-
#nb %% [code]
#nb 1+2
#nb #-
#nb # %% [markdown] {"meta": "data"}
#nb # # Explicit markdown cell with metadata
# It can sometimes happen that a text editor line-wraps [a link which shouldn't
# break](@ref bbaarr)
#=
First multiline
comment
=#
end
#=======================
Second multiline comment
=======================#
"""
# Some inline html
# ```@raw html
# <a href="https://github.com/fredrikekre/Literate.jl">Literate.jl</a>
# ```
# Semicolon output supression
1 + 1;
# Completely hidden
hidden = 12 #hide
hidden * hidden #hide
# Partially hidden
hidden2 = 12 #hide
hidden2 * hidden2
#nb # A notebook cell with special metadata
#nb %% Meta1 {"meta": "data"}
#nb 1+1
#nb #-
#nb # A explicit code notebook cell
#nb #-
#nb %% [code]
#nb 1+2
#nb #-
#nb # %% [markdown] {"meta": "data"}
#nb # # Explicit markdown cell with metadata
# It can sometimes happen that a text editor line-wraps [a link which shouldn't
# break](@ref bbaarr)
#=
First multiline
comment
=#
#=======================
Second multiline comment
=======================#
"""
const TRAVIS_ENV = Dict(
"TRAVIS_REPO_SLUG" => "fredrikekre/Literate.jl",
@ -349,9 +350,15 @@ const GITLAB_ENV = Dict( @@ -349,9 +350,15 @@ const GITLAB_ENV = Dict(
(k => nothing for k in keys(ACTIONS_ENV))...,
)
@testset "Literate.script" begin; Base.CoreLogging.with_logger(Base.CoreLogging.NullLogger()) do
mktempdir(@__DIR__) do sandbox
cd(sandbox) do
function with_nullogger_tempdir_cd(f)
Base.CoreLogging.with_logger(Base.CoreLogging.NullLogger()) do
mktempdir(tmp -> cd(f, tmp), @__DIR__)
end
return
end
@testset "Literate.script" begin
with_nullogger_tempdir_cd() do
# write content to inputfile
inputfile = "inputfile.jl"
write(inputfile, content)
@ -407,9 +414,9 @@ const GITLAB_ENV = Dict( @@ -407,9 +414,9 @@ const GITLAB_ENV = Dict(
@test script == expected_script
# Travis with with PR preview build
withenv(TRAVIS_ENV...,
"TRAVIS_TAG" => "",
"TRAVIS_PULL_REQUEST" => "42") do
withenv(
TRAVIS_ENV..., "TRAVIS_TAG" => "", "TRAVIS_PULL_REQUEST" => "42"
) do
Literate.script(inputfile, outdir)
end
script = read(joinpath(outdir, "inputfile.jl"), String)
@ -418,8 +425,9 @@ const GITLAB_ENV = Dict( @@ -418,8 +425,9 @@ const GITLAB_ENV = Dict(
@test occursin("# Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=previews/PR42/file.jl", script)
# Travis with no tag -> dev directory
withenv(TRAVIS_ENV...,
"TRAVIS_TAG" => "") do
withenv(
TRAVIS_ENV..., "TRAVIS_TAG" => ""
) do
Literate.script(inputfile, outdir)
end
script = read(joinpath(outdir, "inputfile.jl"), String)
@ -437,9 +445,10 @@ const GITLAB_ENV = Dict( @@ -437,9 +445,10 @@ const GITLAB_ENV = Dict(
@test occursin("# Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=v1.2.0/file.jl", script)
# GitHub Actions with PR preview build
withenv(ACTIONS_ENV...,
"GITHUB_EVENT_NAME" => "pull_request",
"GITHUB_REF" => "refs/pull/42/merge") do
withenv(
ACTIONS_ENV...,
"GITHUB_EVENT_NAME" => "pull_request", "GITHUB_REF" => "refs/pull/42/merge"
) do
Literate.script(inputfile, outdir)
end
script = read(joinpath(outdir, "inputfile.jl"), String)
@ -448,8 +457,9 @@ const GITLAB_ENV = Dict( @@ -448,8 +457,9 @@ const GITLAB_ENV = Dict(
@test occursin("# Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=previews/PR42/file.jl", script)
# GitHub Actions without a tag -> dev directory
withenv(ACTIONS_ENV...,
"GITHUB_REF" => "refs/heads/master") do
withenv(
ACTIONS_ENV..., "GITHUB_REF" => "refs/heads/master"
) do
Literate.script(inputfile, outdir)
end
script = read(joinpath(outdir, "inputfile.jl"), String)
@ -458,8 +468,10 @@ const GITLAB_ENV = Dict( @@ -458,8 +468,10 @@ const GITLAB_ENV = Dict(
@test occursin("# Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=dev/file.jl", script)
# building under DocumentationGenerator.jl
withenv("DOCUMENTATIONGENERATOR" => "true",
"DOCUMENTATIONGENERATOR_BASE_URL" => "pkg.julialang.org/docs/Literate/XPnWG/1.2.0") do
withenv(
"DOCUMENTATIONGENERATOR" => "true",
"DOCUMENTATIONGENERATOR_BASE_URL" => "pkg.julialang.org/docs/Literate/XPnWG/1.2.0"
) do
Literate.script(inputfile, outdir)
end
script = read(joinpath(outdir, "inputfile.jl"), String)
@ -467,9 +479,11 @@ const GITLAB_ENV = Dict( @@ -467,9 +479,11 @@ const GITLAB_ENV = Dict(
@test_broken occursin("https://github.com/fredrikekre/Literate.jl/blob/master/file.jl", script)
# pre- and post-processing
Literate.script(inputfile, outdir,
Literate.script(
inputfile, outdir,
preprocess = x -> replace(x, "PLACEHOLDER3" => "3REDLOHECALP"),
postprocess = x -> replace(x, "PLACEHOLDER4" => "4REDLOHECALP"))
postprocess = x -> replace(x, "PLACEHOLDER4" => "4REDLOHECALP")
)
script = read(joinpath(outdir, "inputfile.jl"), String)
@test !occursin("PLACEHOLDER1", script)
@test !occursin("PLACEHOLDER2", script)
@ -497,11 +511,14 @@ const GITLAB_ENV = Dict( @@ -497,11 +511,14 @@ const GITLAB_ENV = Dict(
"""
# It can sometimes happen that a text editor line-wraps a link which shouldn't
# break""",
script)
script
)
# mdstrings
mdstrings_file = "inputfile_mdstrings.jl"
write(mdstrings_file, """
write(
mdstrings_file,
"""
md\"\"\"
# Markdown header
@ -516,9 +533,12 @@ const GITLAB_ENV = Dict( @@ -516,9 +533,12 @@ const GITLAB_ENV = Dict(
comment
===#
2 + 2
""")
Literate.script(mdstrings_file, outdir,
keep_comments = true, credit=false)
"""
)
Literate.script(
mdstrings_file, outdir,
keep_comments = true, credit = false
)
script = read(joinpath(outdir, mdstrings_file), String)
@test strip(script) == """
md\"\"\"
@ -535,8 +555,10 @@ const GITLAB_ENV = Dict( @@ -535,8 +555,10 @@ const GITLAB_ENV = Dict(
# comment
2 + 2"""
Literate.script(mdstrings_file, outdir,
keep_comments = true, mdstrings = true, credit=false)
Literate.script(
mdstrings_file, outdir,
keep_comments = true, mdstrings = true, credit = false
)
script = read(joinpath(outdir, mdstrings_file), String)
@test strip(script) == """
# # Markdown header
@ -555,16 +577,14 @@ const GITLAB_ENV = Dict( @@ -555,16 +577,14 @@ const GITLAB_ENV = Dict(
@test_throws ArgumentError Literate.script("nonexistent.jl", outdir)
# default output directory
Literate.script(inputfile; name="default-output-directory")
Literate.script(inputfile; name = "default-output-directory")
@test isfile("default-output-directory.jl")
@test_throws ArgumentError Literate.script(inputfile)
end
end
end end
end
@testset "Literate.markdown" begin; Base.CoreLogging.with_logger(Base.CoreLogging.NullLogger()) do
mktempdir(@__DIR__) do sandbox
cd(sandbox) do
@testset "Literate.markdown" begin
with_nullogger_tempdir_cd() do
# write content to inputfile
inputfile = "inputfile.jl"
write(inputfile, content)
@ -706,9 +726,9 @@ end end @@ -706,9 +726,9 @@ end end
@test markdown == expected_markdown
# Travis with PR preview build
withenv(TRAVIS_ENV...,
"TRAVIS_TAG" => "",
"TRAVIS_PULL_REQUEST" => "42") do
withenv(
TRAVIS_ENV..., "TRAVIS_TAG" => "", "TRAVIS_PULL_REQUEST" => "42"
) do
Literate.markdown(inputfile, outdir)
end
markdown = read(joinpath(outdir, "inputfile.md"), String)
@ -718,8 +738,9 @@ end end @@ -718,8 +738,9 @@ end end
@test occursin("EditURL = \"../inputfile.jl\"", markdown)
# Travis with no tag -> dev directory
withenv(TRAVIS_ENV...,
"TRAVIS_TAG" => "") do
withenv(
TRAVIS_ENV..., "TRAVIS_TAG" => ""
) do
Literate.markdown(inputfile, outdir)
end
markdown = read(joinpath(outdir, "inputfile.md"), String)
@ -739,9 +760,10 @@ end end @@ -739,9 +760,10 @@ end end
@test occursin("EditURL = \"../inputfile.jl\"", markdown)
# GitHub Actions with PR preview build
withenv(ACTIONS_ENV...,
"GITHUB_REF" => "refs/pull/42/merge",
"GITHUB_EVENT_NAME" => "pull_request") do
withenv(
ACTIONS_ENV...,
"GITHUB_REF" => "refs/pull/42/merge", "GITHUB_EVENT_NAME" => "pull_request"
) do
Literate.markdown(inputfile, outdir)
end
markdown = read(joinpath(outdir, "inputfile.md"), String)
@ -751,8 +773,9 @@ end end @@ -751,8 +773,9 @@ end end
@test occursin("EditURL = \"../inputfile.jl\"", markdown)
# GitHub Actions without a tag -> dev directory
withenv(ACTIONS_ENV...,
"GITHUB_REF" => "refs/heads/master") do
withenv(
ACTIONS_ENV..., "GITHUB_REF" => "refs/heads/master"
) do
Literate.markdown(inputfile, outdir)
end
markdown = read(joinpath(outdir, "inputfile.md"), String)
@ -772,8 +795,10 @@ end end @@ -772,8 +795,10 @@ end end
@test occursin("EditURL = \"../inputfile.jl\"", markdown)
# building under DocumentationGenerator.jl
withenv("DOCUMENTATIONGENERATOR" => "true",
"DOCUMENTATIONGENERATOR_BASE_URL" => "pkg.julialang.org/docs/Literate/XPnWG/1.2.0") do
withenv(
"DOCUMENTATIONGENERATOR" => "true",
"DOCUMENTATIONGENERATOR_BASE_URL" => "pkg.julialang.org/docs/Literate/XPnWG/1.2.0"
) do
Literate.markdown(inputfile, outdir)
end
markdown = read(joinpath(outdir, "inputfile.md"), String)
@ -781,9 +806,11 @@ end end @@ -781,9 +806,11 @@ end end
@test_broken occursin("https://github.com/fredrikekre/Literate.jl/blob/master/file.jl", markdown)
# pre- and post-processing
Literate.markdown(inputfile, outdir,
Literate.markdown(
inputfile, outdir,
preprocess = x -> replace(replace(x, "PLACEHOLDER1" => "1REDLOHECALP"), "PLACEHOLDER3" => "3REDLOHECALP"),
postprocess = x -> replace(replace(x, "PLACEHOLDER2" => "2REDLOHECALP"), "PLACEHOLDER4" => "4REDLOHECALP"))
postprocess = x -> replace(replace(x, "PLACEHOLDER2" => "2REDLOHECALP"), "PLACEHOLDER4" => "4REDLOHECALP")
)
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test !occursin("PLACEHOLDER1", markdown)
@test !occursin("PLACEHOLDER2", markdown)
@ -808,7 +835,7 @@ end end @@ -808,7 +835,7 @@ end end
let expected_error = ArgumentError("QuartoFlavor does not support `execute = true`.")
@test_throws expected_error Literate.markdown("quarto.jl", flavor = Literate.QuartoFlavor(), execute = true)
end
Literate.markdown(inputfile, outdir, flavor = Literate.QuartoFlavor(),execute=false)
Literate.markdown(inputfile, outdir, flavor = Literate.QuartoFlavor(), execute = false)
markdown = read(joinpath(outdir, "inputfile.qmd"), String)
@test occursin("```{julia}", markdown)
@test !occursin(r"`{3,}@example", markdown)
@ -850,14 +877,15 @@ end end @@ -850,14 +877,15 @@ end end
# edit_commit
withenv(ACTIONS_ENV...) do
Literate.markdown(inputfile, outdir; edit_commit="retsam")
Literate.markdown(inputfile, outdir; edit_commit = "retsam")
end
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test occursin("blob/retsam/", markdown)
@test !occursin("blob/master/", markdown)
# execute
write(inputfile, """
write(
inputfile, """
using DisplayAs
#-
1+1
@ -912,8 +940,9 @@ end end @@ -912,8 +940,9 @@ end end
(@__DIR__) == pwd() ? "cwd correct" : "cwd incorrect"
#-
basename(@__FILE__)
""")
Literate.markdown(inputfile, outdir; execute=true)
"""
)
Literate.markdown(inputfile, outdir; execute = true)
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test occursin("```\n2\n```", markdown) # text/plain
@test occursin("```\n2×2 $(Matrix{Int}):\n 1 2\n 3 4\n```", markdown) # text/plain
@ -938,14 +967,14 @@ end end @@ -938,14 +967,14 @@ end end
@test occursin("```\n\"inputfile.md\"\n```", markdown) # Correct source file (@__FILE__)
# FranklinFlavor
Literate.markdown(inputfile, outdir; execute=true, flavor=Literate.FranklinFlavor())
Literate.markdown(inputfile, outdir; execute = true, flavor = Literate.FranklinFlavor())
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test occursin("# MD", markdown) # text/markdown
@test occursin("~~~\n<h1>MD</h1>\n~~~", markdown) # text/html
# QuartoFlavor file extension
write(inputfile, "#=\r\nhello world\n=#\r\n")
_, config = Literate.preprocessor(inputfile, outdir; user_kwargs=(), user_config=Dict("flavor"=>Literate.QuartoFlavor()), type=:md)
_, config = Literate.preprocessor(inputfile, outdir; user_kwargs = (), user_config = Dict("flavor" => Literate.QuartoFlavor()), type = :md)
@test config["literate_ext"] == ".qmd"
# verify that inputfile exists
@ -953,16 +982,18 @@ end end @@ -953,16 +982,18 @@ end end
# default output directory
@test !isfile("inputfile.md")
Literate.markdown(inputfile; execute=false)
Literate.markdown(inputfile; execute = false)
@test isfile("inputfile.md")
# fredrikekre/Literate.jl#165: \r\n line endings with multiline comments/mdstrings
write(inputfile, "#=\r\nhello world\r\nhej världen\r\n=#\r\n")
chunks, _ = Literate.preprocessor(inputfile, outdir; user_kwargs=(), user_config=(), type=:md)
chunks, _ = Literate.preprocessor(inputfile, outdir; user_kwargs = (), user_config = (), type = :md)
@test chunks[2].lines == ["" => "hello world", "" => "hej världen"]
write(inputfile, "md\"\"\"\r\nhello world\r\nhej världen\r\n\"\"\"\r\n")
chunks, _ = Literate.preprocessor(inputfile, outdir; user_kwargs=pairs((; mdstrings=true)),
user_config=(), type=:md)
chunks, _ = Literate.preprocessor(
inputfile, outdir; user_kwargs = pairs((; mdstrings = true)),
user_config = (), type = :md
)
@test chunks[2].lines == ["" => "hello world", "" => "hej världen"]
# fredrikekre/Literate.jl#168
@ -981,8 +1012,10 @@ end end @@ -981,8 +1012,10 @@ end end
SVG()
""",
)
Literate.markdown(inputfile, relpath(outdir); execute=true,
flavor=Literate.CommonMarkFlavor())
Literate.markdown(
inputfile, relpath(outdir); execute = true,
flavor = Literate.CommonMarkFlavor()
)
@test read(joinpath(outdir, "inputfile-1.svg"), String) == "issue228"
# Softscope
@ -996,22 +1029,20 @@ end end @@ -996,22 +1029,20 @@ end end
println("ret = ", ret)
"""
)
Literate.markdown(inputfile, outdir; execute=true, softscope=true)
Literate.markdown(inputfile, outdir; execute = true, softscope = true)
@test occursin("ret = 55", read(joinpath(outdir, "inputfile.md"), String))
## Disabled softscope
try
Literate.markdown(inputfile, outdir; execute=true, softscope=false)
Literate.markdown(inputfile, outdir; execute = true, softscope = false)
error("unreachable")
catch err
@test occursin(r"`?ret`? not defined", sprint(Base.showerror, err))
end
end # cd(sandbox)
end # mktemp
end end
end
end
@testset "Literate.notebook" begin; Base.CoreLogging.with_logger(Base.CoreLogging.NullLogger()) do
mktempdir(@__DIR__) do sandbox
cd(sandbox) do
@testset "Literate.notebook" begin
with_nullogger_tempdir_cd() do
# write content to inputfile
inputfile = "inputfile.jl"
write(inputfile, content)
@ -1021,11 +1052,11 @@ end end @@ -1021,11 +1052,11 @@ end end
withenv(TRAVIS_ENV...) do
Literate.notebook(inputfile, outdir, execute = false)
end
expected_cells = rstrip.((
expected_cells = rstrip.(
[
"""
"cells": [
""",
"""
"source": [
"# Example\\n",
@ -1033,48 +1064,41 @@ end end @@ -1033,48 +1064,41 @@ end end
"baz, bax"
]
""",
"""
"source": [
"x = 1"
]
""",
"""
"source": [
"Not markdown\\n",
"Not markdown"
],
""",
"""
"source": [
"x * 1\\n",
"x * 1"
],
""",
"""
"source": [
"Only notebook\\n",
"Only notebook"
]
""",
"""
"source": [
"x + 2\\n",
"x + 2"
]
""",
"""
"source": [
"Not script\\n",
"Not script"
],
""",
"""
"source": [
"x * 3\\n",
@ -1083,7 +1107,6 @@ end end @@ -1083,7 +1107,6 @@ end end
"# another comment"
],
""",
"""
"source": [
"for i in 1:10\\n",
@ -1092,7 +1115,6 @@ end end @@ -1092,7 +1115,6 @@ end end
"end"
]
""",
"""
"source": [
"name: inputfile\\n",
@ -1101,7 +1123,6 @@ end end @@ -1101,7 +1123,6 @@ end end
"Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=v1.2.0/file.jl"
]
""",
"""
"source": [
"# name: inputfile\\n",
@ -1110,21 +1131,18 @@ end end @@ -1110,21 +1131,18 @@ end end
"# Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=v1.2.0/file.jl"
]
""",
"""
"source": [
"PLACEHOLDER1\\n",
"PLACEHOLDER2"
]
""",
"""
"source": [
"# PLACEHOLDER3\\n",
"# PLACEHOLDER4"
]
""",
"""
"source": [
"Some inline math: \$\\\\frac{df}{dx}\$, some multiline inline math: \$y =\\n",
@ -1134,13 +1152,11 @@ end end @@ -1134,13 +1152,11 @@ end end
"\$\$"
]
""",
"""
"source": [
"Indented markdown"
]
""",
"""
"source": [
"for i in 1:10\\n",
@ -1149,7 +1165,6 @@ end end @@ -1149,7 +1165,6 @@ end end
"end"
]
""",
"""
"source": [
"Some inline html\\n",
@ -1157,27 +1172,26 @@ end end @@ -1157,27 +1172,26 @@ end end
" <a href=\\"https://github.com/fredrikekre/Literate.jl\\">Literate.jl</a>"
]
""",
"""
"metadata": {
"meta": "data"
}
""",
"""
"source": [
"First multiline\\n",
"comment"
]
""",
"""
"source": [
"---\\n",
"\\n",
"*This notebook was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).*"
]
"""))
""",
]
)
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@ -1188,16 +1202,19 @@ end end @@ -1188,16 +1202,19 @@ end end
lastidx = nextind(notebook, last(idx))
end
# test some of the required metadata
for metadata in (" \"nbformat\": ", " \"nbformat_minor\": ", " \"metadata\": {", " \"language_info\": {",
for metadata in (
" \"nbformat\": ", " \"nbformat_minor\": ", " \"metadata\": {", " \"language_info\": {",
" \"file_extension\": \".jl\"", " \"mimetype\": \"application/julia\"",
" \"name\": \"julia\"", " \"version\": ", " \"kernelspec\": {",
" \"name\": \"julia-", " \"display_name\": \"Julia ", " \"language\": \"julia\"")
" \"name\": \"julia-", " \"display_name\": \"Julia ", " \"language\": \"julia\"",
)
@test occursin(metadata, notebook)
end
# no tag -> latest directory
withenv(TRAVIS_ENV...,
"TRAVIS_TAG" => "") do
withenv(
TRAVIS_ENV..., "TRAVIS_TAG" => ""
) do
Literate.notebook(inputfile, outdir, execute = false)
end
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@ -1211,25 +1228,29 @@ end end @@ -1211,25 +1228,29 @@ end end
@test occursin("fredrikekre/Literate.jl/blob/gh-pages/v1.2.0/", notebook)
# GitHub Actions with PR preview build
withenv(ACTIONS_ENV...,
"GITHUB_REF" => "refs/pull/42/merge",
"GITHUB_EVENT_NAME" => "pull_request") do
withenv(
ACTIONS_ENV...,
"GITHUB_REF" => "refs/pull/42/merge", "GITHUB_EVENT_NAME" => "pull_request"
) do
Literate.notebook(inputfile, outdir, execute = false)
end
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@test occursin("fredrikekre/Literate.jl/blob/gh-pages/previews/PR42/", notebook)
# GitHub Actions without a tag
withenv(ACTIONS_ENV...,
"GITHUB_REF" => "refs/heads/master") do
withenv(
ACTIONS_ENV..., "GITHUB_REF" => "refs/heads/master"
) do
Literate.notebook(inputfile, outdir, execute = false)
end
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@test occursin("fredrikekre/Literate.jl/blob/gh-pages/dev/", notebook)
# building under DocumentationGenerator.jl
withenv("DOCUMENTATIONGENERATOR" => "true",
"DOCUMENTATIONGENERATOR_BASE_URL" => "pkg.julialang.org/docs/Literate/XPnWG/1.2.0") do
withenv(
"DOCUMENTATIONGENERATOR" => "true",
"DOCUMENTATIONGENERATOR_BASE_URL" => "pkg.julialang.org/docs/Literate/XPnWG/1.2.0"
) do
Literate.notebook(inputfile, outdir, execute = false)
end
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@ -1246,9 +1267,11 @@ end end @@ -1246,9 +1267,11 @@ end end
end
return nb
end
Literate.notebook(inputfile, outdir, execute = false,
Literate.notebook(
inputfile, outdir, execute = false,
preprocess = x -> replace(replace(x, "PLACEHOLDER1" => "1REDLOHECALP"), "PLACEHOLDER3" => "3REDLOHECALP"),
postprocess = post)
postprocess = post
)
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@test !occursin("PLACEHOLDER1", notebook)
@test !occursin("PLACEHOLDER2", notebook)
@ -1277,22 +1300,23 @@ end end @@ -1277,22 +1300,23 @@ end end
# execute = true
Literate.notebook(inputfile, outdir)
expected_outputs = rstrip.((
expected_outputs = rstrip.(
[
"""
"cells": [
""",
"""
"data": {
"text/plain": "3"
},
""",
"""
"text": [
"12345678910"
]
"""))
""",
]
)
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@ -1321,12 +1345,14 @@ end end @@ -1321,12 +1345,14 @@ end end
# test error when executing notebook
write(inputfile, "for i in 1:10\n println(i)")
r = @test_logs((:error, r"error when executing notebook based on input file: "), match_mode=:any,
r = @test_logs(
(:error, r"error when executing notebook based on input file: "), match_mode = :any,
try
Literate.notebook(inputfile, outdir)
catch err
err
end)
end
)
@test isa(r, ErrorException)
@test occursin("when executing the following code block from inputfile ", r.msg)
@test occursin(inputfile, r.msg)
@ -1336,11 +1362,13 @@ end end @@ -1336,11 +1362,13 @@ end end
# default output directory
@test !isfile("inputfile.ipynb")
Literate.notebook(inputfile; execute=false)
Literate.notebook(inputfile; execute = false)
@test isfile("inputfile.ipynb")
# world time problem with `IJulia.display_dict`
write(inputfile, """
write(
inputfile,
"""
struct VegaLiteRenderable end
Base.show(io::IO, ::MIME"application/vnd.vegalite.v2+json", ::VegaLiteRenderable) =
write(io, \"\"\"
@ -1348,7 +1376,8 @@ end end @@ -1348,7 +1376,8 @@ end end
\"\"\")
Base.Multimedia.istextmime(::MIME{Symbol("application/vnd.vegalite.v2+json")}) = true
VegaLiteRenderable()
""")
"""
)
Literate.notebook(inputfile, outdir)
notebook = read(joinpath(outdir, "inputfile.ipynb"), String)
@test occursin("\"application/vnd.vegalite.v2+json\":", notebook)
@ -1450,14 +1479,13 @@ end end @@ -1450,14 +1479,13 @@ end end
@test occursin("ret = 55", read(joinpath(outdir, "inputfile2.ipynb"), String))
## Disabled softscope
try
Literate.notebook(new_inputfile, outdir; softscope=false)
Literate.notebook(new_inputfile, outdir; softscope = false)
error("unreachable")
catch err
@test occursin(r"`?ret`? not defined", sprint(Base.showerror, err))
end
end # cd(sandbox)
end # mktempdir
end end
end
end
@testset "continue_on_error=true" begin
input_with_error =
@ -1529,26 +1557,25 @@ end @@ -1529,26 +1557,25 @@ end
end
end
@testset "Configuration" begin; Base.CoreLogging.with_logger(Base.CoreLogging.NullLogger()) do
mktempdir(@__DIR__) do sandbox
cd(sandbox) do
@testset "Configuration" begin
with_nullogger_tempdir_cd() do
# write content to inputfile
inputfile = "inputfile.jl"
write(inputfile, content)
outdir = mktempdir(pwd())
config=Dict(
config = Dict(
"repo_root_url" => "www.example1.com",
"nbviewer_root_url" => "www.example2.com",
"binder_root_url" => "www.example3.com",
)
# Overwriting of URLs
withenv("TRAVIS_REPO_SLUG" => "fredrikekre/Literate.jl",
"TRAVIS_TAG" => "",
"TRAVIS_PULL_REQUEST" => "false",
"HAS_JOSH_K_SEAL_OF_APPROVAL" => "true") do
Literate.script(inputfile, outdir; config=config)
withenv(
"TRAVIS_REPO_SLUG" => "fredrikekre/Literate.jl", "TRAVIS_TAG" => "",
"TRAVIS_PULL_REQUEST" => "false", "HAS_JOSH_K_SEAL_OF_APPROVAL" => "true"
) do
Literate.script(inputfile, outdir; config = config)
end
script = read(joinpath(outdir, "inputfile.jl"), String)
@test occursin("Link to repo root: www.example1.com/file.jl", script)
@ -1556,7 +1583,7 @@ end @@ -1556,7 +1583,7 @@ end
@test occursin("Link to binder: www.example3.com/file.jl", script)
# Test pick_codefence function
default_codefence=pick_codefence(Literate.DefaultFlavor(), true, "testname")
default_codefence = pick_codefence(Literate.DefaultFlavor(), true, "testname")
@test default_codefence == ("````julia" => "````")
@test default_codefence == pick_codefence(Literate.FranklinFlavor(), true, "testname")
@test default_codefence == pick_codefence(Literate.DocumenterFlavor(), true, "testname")
@ -1566,13 +1593,12 @@ end @@ -1566,13 +1593,12 @@ end
@test ("```{julia}" => "```") == pick_codefence(Literate.QuartoFlavor(), false, "testname")
# Misc default configs
create(; type, kw...) = Literate.create_configuration(inputfile; user_config=Dict(), user_kwargs=kw, type=type)
cfg = create(; type=:md, execute=true)
create(; type, kw...) = Literate.create_configuration(inputfile; user_config = Dict(), user_kwargs = kw, type = type)
cfg = create(; type = :md, execute = true)
@test cfg["execute"]
@test cfg["codefence"] == ("````julia" => "````")
cfg = create(; type=:md, execute=false)
cfg = create(; type = :md, execute = false)
@test !cfg["execute"]
@test cfg["codefence"] == ("````@example inputfile" => "````")
end
end
end end
end

Loading…
Cancel
Save