Browse Source

Add support for multiline markdown strings as markdown blocks

This is opt-in for now, requires passing mdstrings=true.

Co-authored-by: CarloLucibello <carlo.lucibello@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
pull/152/head
CarloLucibello 5 years ago committed by Fredrik Ekre
parent
commit
611bab7ad1
  1. 20
      docs/src/fileformat.md
  2. 19
      src/Literate.jl
  3. 57
      test/runtests.jl

20
docs/src/fileformat.md

@ -45,7 +45,7 @@ For simple use this is all you need to know. The following additional special sy
There is also some default convenience replacements that will always be performed, see There is also some default convenience replacements that will always be performed, see
[Default replacements](@ref). [Default replacements](@ref).
### Multiline comments ### Multiline comments and markdown strings
Literate version 2.7 adds support for Julia multiline comments for markdown input. Literate version 2.7 adds support for Julia multiline comments for markdown input.
All multiline comments in the input are rewritten to regular comments as part of the All multiline comments in the input are rewritten to regular comments as part of the
@ -71,6 +71,22 @@ is rewritten to
# This is also markdown. # This is also markdown.
``` ```
Similarly, Literate version 2.9 adds support for using literal markdown strings,
`md""" ... """`, for the markdown sections, for example
```julia
md"""
# Title
blah blah blah
"""
```
is rewritten to
```julia
# # Title
# blah blah blah
```
This is not enabled by default -- it requires passing `mdstrings=true`.
`Literate.markdown`/`Literate.notebook`/`Literate.script`.
## [**2.2.** Filtering lines](@id Filtering-lines) ## [**2.2.** Filtering lines](@id Filtering-lines)
@ -104,7 +120,7 @@ is a case where we can prepend `#md` to those lines:
#md # ```@docs #md # ```@docs
#md # Literate.markdown #md # Literate.markdown
#md # Literate.notebook #md # Literate.notebook
#md # Literate.markdown #md # Literate.script
#md # ``` #md # ```
```` ````
The lines in the example above would be filtered out in the preprocessing step, unless we are The lines in the example above would be filtered out in the preprocessing step, unless we are

19
src/Literate.jl

@ -150,14 +150,22 @@ function replace_default(content, sym;
push!(repls, "\r\n" => "\n") # normalize line endings push!(repls, "\r\n" => "\n") # normalize line endings
# unconditionally rewrite multiline comments to regular comments # unconditionally rewrite multiline comments and
multiline_r = r"^#=+$\R^(\X*?)\R^=+#$"m # conditionally multiline markdown strings to regular comments
while (m = match(multiline_r, content); m !== nothing) function replace_multiline(multiline_r, str)
while (m = match(multiline_r, str); m !== nothing)
newlines = sprint() do io newlines = sprint() do io
foreach(l -> println(io, "# ", l), eachline(IOBuffer(m[1]))) foreach(l -> println(io, "# ", l), eachline(IOBuffer(m[1])))
end end
content = replace(content, multiline_r => chop(newlines); count=1) str = replace(str, multiline_r => chop(newlines); count=1)
end end
return str
end
content = replace_multiline(r"^#=+$\R^(\X*?)\R^=+#$"m, content)
if config["mdstrings"]::Bool
content = replace_multiline(r"^md\"\"\"$\R^(\X*?)\R^\"\"\"$"m, content)
end
# unconditionally remove #src lines # unconditionally remove #src lines
push!(repls, r"^#src.*\n?"m => "") # remove leading #src lines push!(repls, r"^#src.*\n?"m => "") # remove leading #src lines
@ -245,6 +253,7 @@ function create_configuration(inputfile; user_config, user_kwargs, type=nothing)
cfg["postprocess"] = identity cfg["postprocess"] = identity
cfg["flavor"] = type === (:md) ? DocumenterFlavor() : DefaultFlavor() cfg["flavor"] = type === (:md) ? DocumenterFlavor() : DefaultFlavor()
cfg["credit"] = true cfg["credit"] = true
cfg["mdstrings"] = false
cfg["keep_comments"] = false cfg["keep_comments"] = false
cfg["execute"] = type === :md ? false : true cfg["execute"] = type === :md ? false : true
cfg["codefence"] = get(user_config, "flavor", cfg["flavor"]) isa DocumenterFlavor && cfg["codefence"] = get(user_config, "flavor", cfg["flavor"]) isa DocumenterFlavor &&
@ -439,7 +448,7 @@ function script(inputfile, outputdir=pwd(); config::Dict=Dict(), kwargs...)
write(ioscript, '\n') # add a newline between each chunk write(ioscript, '\n') # add a newline between each chunk
elseif isa(chunk, MDChunk) && config["keep_comments"]::Bool elseif isa(chunk, MDChunk) && config["keep_comments"]::Bool
for line in chunk.lines for line in chunk.lines
write(ioscript, rstrip(line.first * "# " * line.second * '\n')) write(ioscript, rstrip(line.first * "# " * line.second) * '\n')
end end
write(ioscript, '\n') # add a newline between each chunk write(ioscript, '\n') # add a newline between each chunk
end end

57
test/runtests.jl

@ -436,6 +436,58 @@ const GITLAB_ENV = Dict(
@test occursin("# First multiline", script) @test occursin("# First multiline", script)
@test occursin("# Second multiline comment", script) @test occursin("# Second multiline comment", script)
# mdstrings
mdstrings_file = "inputfile_mdstrings.jl"
write(mdstrings_file, """
md\"\"\"
# Markdown header
Content of the multiline markdown
string
\"\"\"
#-
#===
# Markdown header 2
Content of the multiline
comment
===#
2 + 2
""")
Literate.script(mdstrings_file, outdir,
keep_comments = true, credit=false)
script = read(joinpath(outdir, mdstrings_file), String)
@test strip(script) == """
md\"\"\"
# Markdown header
Content of the multiline markdown
string
\"\"\"
# # Markdown header 2
#
# Content of the multiline
# comment
2 + 2"""
Literate.script(mdstrings_file, outdir,
keep_comments = true, mdstrings = true, credit=false)
script = read(joinpath(outdir, mdstrings_file), String)
@test strip(script) == """
# # Markdown header
#
# Content of the multiline markdown
# string
# # Markdown header 2
#
# Content of the multiline
# comment
2 + 2"""
# verify that inputfile exists # verify that inputfile exists
@test_throws ArgumentError Literate.script("nonexistent.jl", outdir) @test_throws ArgumentError Literate.script("nonexistent.jl", outdir)
@ -705,6 +757,11 @@ end end
@test !occursin("name: inputfile", markdown) @test !occursin("name: inputfile", markdown)
@test !occursin("name: @__NAME__", markdown) @test !occursin("name: @__NAME__", markdown)
# mdstrings
Literate.markdown(inputfile, outdir, mdstrings = true)
markdown = read(joinpath(outdir, "inputfile.md"), String)
@test !occursin("md\"\"\"", markdown)
# execute # execute
write(inputfile, """ write(inputfile, """
using DisplayAs using DisplayAs

Loading…
Cancel
Save