Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue #144, first draft #145

Merged
merged 4 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions docs/src/outputformats.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ of the source snippet above is as follows:
```@eval
import Markdown
file = joinpath(@__DIR__, "../src/generated/name.md")
str = "````markdown\n" * rstrip(read(file, String)) * "\n````"
str = "`````markdown\n" * rstrip(read(file, String)) * "\n`````"
rm(file)
Markdown.parse(str)
```
Expand All @@ -29,17 +29,29 @@ an `@meta` block have been added, that sets the `EditURL` variable. This is used
by Documenter to redirect the "Edit on GitHub" link for the page,
see [Interaction with Documenter](@ref).

The `@example` blocks are wrapped in 4 consecutive backticks so as to allow for docstrings containing triple backticks, for example:
````julia
"""
This function perform the following calculation:
```math
x_1 + x_2
```
"""
f(x) = x[1] + x[2]
````
If your Julia code itself contains 4 consecutive backticks, you can use the keyword argument `codefence` to setup 5 backticks for code blocks, see [Configuration](@ref).

It possible to configure `Literate.markdown` to also evaluate code snippets, capture the
result and include it in the output, by passing `execute=true` as a keyword argument.
The result of the first code-block in the example above would then become
````markdown
```julia
`````markdown
````julia
x = 1//3
```
```
````
````
1//3
```
````
`````

In this example the output is just plain text. However, if the resulting value of the code
block can be displayed as an image (png or jpeg) Literate will include the image
Expand Down
11 changes: 7 additions & 4 deletions src/Literate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ function create_configuration(inputfile; user_config, user_kwargs, type=nothing)
cfg["keep_comments"] = false
cfg["execute"] = type === :md ? false : true
cfg["codefence"] = get(user_config, "documenter", true) && !get(user_config, "execute", cfg["execute"]) ?
("```@example $(get(user_config, "name", cfg["name"]))" => "```") : ("```julia" => "```")
("````@example $(get(user_config, "name", cfg["name"]))" => "````") : ("````julia" => "````")
# Guess the package (or repository) root url
edit_commit = "master" # TODO: Make this configurable like Documenter?
deploy_branch = "gh-pages" # TODO: Make this configurable like Documenter?
Expand Down Expand Up @@ -296,7 +296,7 @@ See the manual section about [Configuration](@ref) for more information.
| `credit` | Boolean for controlling the addition of `This file was generated with Literate.jl ...` to the bottom of the page. If you find Literate.jl useful then feel free to keep this. | `true` | |
| `keep_comments` | When `true`, keeps markdown lines as comments in the output script. | `false` | Only applicable for `Literate.script`. |
| `execute` | Whether to execute and capture the output. | `true` (notebook), `false` (markdown) | Only applicable for `Literate.notebook` and `Literate.markdown`. For markdown this requires at least Literate 2.4. |
| `codefence` | Pair containing opening and closing fence for wrapping code blocks. | `````"```julia" => "```"````` | If `documenter` is `true` the default is `````"```@example"=>"```"`````. |
| `codefence` | Pair containing opening and closing fence for wrapping code blocks. | `````"````julia" => "````"````` | If `documenter` is `true` the default is `````"````@example"=>"````"`````. |
| `devurl` | URL for "in-development" docs. | `"dev"` | See [Documenter docs](https://juliadocs.github.io/Documenter.jl/). Unused if `repo_root_url`/`nbviewer_root_url`/`binder_root_url` are set. |
| `repo_root_url` | URL to the root of the repository. | - | Determined automatically on Travis CI, GitHub Actions and GitLab CI. Used for `@__REPO_ROOT_URL__`. |
| `nbviewer_root_url` | URL to the root of the repository as seen on nbviewer. | - | Determined automatically on Travis CI, GitHub Actions and GitLab CI. Used for `@__NBVIEWER_ROOT_URL__`. |
Expand Down Expand Up @@ -441,7 +441,8 @@ function markdown(inputfile, outputdir=pwd(); config::Dict=Dict(), kwargs...)
codefence = config["codefence"]::Pair
write(iocode, codefence.first)
# make sure the code block is finalized if we are printing to ```@example
if chunk.continued && startswith(codefence.first, "```@example") && config["documenter"]::Bool
# (or ````@example, any number of backticks >= 3 works)
if chunk.continued && occursin(r"^`{3,}@example", codefence.first) && config["documenter"]::Bool
write(iocode, "; continued = true")
end
write(iocode, '\n')
Expand Down Expand Up @@ -475,7 +476,9 @@ end
function execute_markdown!(io::IO, sb::Module, block::String, outputdir; inputfile::String="<unknown>")
# TODO: Deal with explicit display(...) calls
r, str, _ = execute_block(sb, block; inputfile=inputfile)
plain_fence = "\n```\n" => "\n```" # issue #101: consecutive codefenced blocks need newline
# issue #101: consecutive codefenced blocks need newline
# issue #144: quadruple backticks allow for triple backticks in the output
plain_fence = "\n````\n" => "\n````"
if r !== nothing && !REPL.ends_with_semicolon(block)
for (mime, ext) in [(MIME("image/png"), ".png"), (MIME("image/jpeg"), ".jpeg")]
if showable(mime, r)
Expand Down
64 changes: 32 additions & 32 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -467,66 +467,66 @@ end end
# [Example](@id example-id)
[foo](@ref), [bar](@ref bbaarr)

```@example inputfile
````@example inputfile
x = 1
```
````

Only markdown
Only markdown

```@example inputfile
````@example inputfile
x + 1
x + 1
```
````

Not notebook
Not notebook

```@example inputfile
````@example inputfile
x * 2
x * 2
```
````

Not script
Not script

```@example inputfile
````@example inputfile
x * 3
x * 3
# # Comment
# another comment
```
````

```@example inputfile; continued = true
````@example inputfile; continued = true
for i in 1:10
print(i)
```
````

some markdown in a code block

```@example inputfile
````@example inputfile
end
```
````

name: inputfile
Link to repo root: https://github.com/fredrikekre/Literate.jl/blob/master/file.jl
Link to nbviewer: https://nbviewer.jupyter.org/github/fredrikekre/Literate.jl/blob/gh-pages/v1.2.0/file.jl
Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=v1.2.0/file.jl

```@example inputfile
````@example inputfile
# name: inputfile
# Link to repo root: https://github.com/fredrikekre/Literate.jl/blob/master/file.jl
# Link to nbviewer: https://nbviewer.jupyter.org/github/fredrikekre/Literate.jl/blob/gh-pages/v1.2.0/file.jl
# Link to binder: https://mybinder.org/v2/gh/fredrikekre/Literate.jl/gh-pages?filepath=v1.2.0/file.jl
```
````

PLACEHOLDER1
PLACEHOLDER2

```@example inputfile
````@example inputfile
# PLACEHOLDER3
# PLACEHOLDER4
```
````

Some math:
```math
Expand All @@ -535,37 +535,37 @@ end end

Indented markdown

```@example inputfile; continued = true
````@example inputfile; continued = true
for i in 1:10
```
````

Indented markdown

```@example inputfile
````@example inputfile
# Indented comment
end
```
````

Semicolon output supression

```@example inputfile
````@example inputfile
1 + 1;
nothing #hide
```
````

Completely hidden

```@example inputfile
````@example inputfile
hidden = 12 #hide
hidden * hidden #hide
```
````

Partially hidden

```@example inputfile
````@example inputfile
hidden2 = 12 #hide
hidden2 * hidden2
```
````

First multiline
comment
Expand Down Expand Up @@ -673,7 +673,7 @@ end end
Literate.markdown(inputfile, outdir, documenter = false)
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test occursin("```julia", markdown)
@test !occursin("```@example", markdown)
@test !occursin(r"`{3,}@example", markdown)
@test !occursin("continued = true", markdown)
@test !occursin("EditURL", markdown)
@test !occursin("#hide", markdown)
Expand All @@ -682,14 +682,14 @@ end end
Literate.markdown(inputfile, outdir, codefence = "```c" => "```")
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test occursin("```c", markdown)
@test !occursin("```@example", markdown)
@test !occursin(r"`{3,}@example", markdown)
@test !occursin("```julia", markdown)

# name
Literate.markdown(inputfile, outdir, name = "foobar")
markdown = read(joinpath(outdir, "foobar.md"), String)
@test occursin("```@example foobar", markdown)
@test !occursin("```@example inputfile", markdown)
@test occursin(r"`{3,}@example foobar", markdown)
@test !occursin(r"`{3,}@example inputfile", markdown)
@test occursin("name: foobar", markdown)
@test !occursin("name: inputfile", markdown)
@test !occursin("name: @__NAME__", markdown)
Expand Down Expand Up @@ -1181,10 +1181,10 @@ end end
create(; kw...) = Literate.create_configuration(inputfile; user_config=Dict(), user_kwargs=kw)
cfg = create(; type=:md, execute=true)
@test cfg["execute"]
@test cfg["codefence"] == ("```julia" => "```")
@test cfg["codefence"] == ("````julia" => "````")
cfg = create(; type=:md, execute=false)
@test !cfg["execute"]
@test cfg["codefence"] == ("```@example inputfile" => "```")
@test cfg["codefence"] == ("````@example inputfile" => "````")
end
end
end end