Browse Source

Add support for multiline markdown strings as markdown blocks (#152)

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/160/head
Carlo Lucibello 4 years ago committed by GitHub
parent
commit
42f39411cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      docs/src/fileformat.md
  2. 23
      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 @@ -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
[Default replacements](@ref).
### Multiline comments
### Multiline comments and markdown strings
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
@ -71,6 +71,22 @@ is rewritten to @@ -71,6 +71,22 @@ is rewritten to
# 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)
@ -104,7 +120,7 @@ is a case where we can prepend `#md` to those lines: @@ -104,7 +120,7 @@ is a case where we can prepend `#md` to those lines:
#md # ```@docs
#md # Literate.markdown
#md # Literate.notebook
#md # Literate.markdown
#md # Literate.script
#md # ```
````
The lines in the example above would be filtered out in the preprocessing step, unless we are

23
src/Literate.jl

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

57
test/runtests.jl

@ -436,6 +436,58 @@ const GITLAB_ENV = Dict( @@ -436,6 +436,58 @@ const GITLAB_ENV = Dict(
@test occursin("# First multiline", 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
@test_throws ArgumentError Literate.script("nonexistent.jl", outdir)
@ -705,6 +757,11 @@ end end @@ -705,6 +757,11 @@ end end
@test !occursin("name: inputfile", 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
write(inputfile, """
using DisplayAs

Loading…
Cancel
Save