Skip to content

Commit 42f3941

Browse files
Add support for multiline markdown strings as markdown blocks (#152)
This is opt-in for now, requires passing mdstrings=true. Co-authored-by: CarloLucibello <[email protected]> Co-authored-by: Fredrik Ekre <[email protected]>
1 parent 94bc226 commit 42f3941

File tree

3 files changed

+91
-9
lines changed

3 files changed

+91
-9
lines changed

docs/src/fileformat.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ For simple use this is all you need to know. The following additional special sy
4545
There is also some default convenience replacements that will always be performed, see
4646
[Default replacements](@ref).
4747

48-
### Multiline comments
48+
### Multiline comments and markdown strings
4949

5050
Literate version 2.7 adds support for Julia multiline comments for markdown input.
5151
All multiline comments in the input are rewritten to regular comments as part of the
@@ -71,6 +71,22 @@ is rewritten to
7171
# This is also markdown.
7272
```
7373

74+
Similarly, Literate version 2.9 adds support for using literal markdown strings,
75+
`md""" ... """`, for the markdown sections, for example
76+
77+
```julia
78+
md"""
79+
# Title
80+
blah blah blah
81+
"""
82+
```
83+
is rewritten to
84+
```julia
85+
# # Title
86+
# blah blah blah
87+
```
88+
This is not enabled by default -- it requires passing `mdstrings=true`.
89+
`Literate.markdown`/`Literate.notebook`/`Literate.script`.
7490

7591
## [**2.2.** Filtering lines](@id Filtering-lines)
7692

@@ -104,7 +120,7 @@ is a case where we can prepend `#md` to those lines:
104120
#md # ```@docs
105121
#md # Literate.markdown
106122
#md # Literate.notebook
107-
#md # Literate.markdown
123+
#md # Literate.script
108124
#md # ```
109125
````
110126
The lines in the example above would be filtered out in the preprocessing step, unless we are

src/Literate.jl

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,23 @@ function replace_default(content, sym;
150150

151151
push!(repls, "\r\n" => "\n") # normalize line endings
152152

153-
# unconditionally rewrite multiline comments to regular comments
154-
multiline_r = r"^#=+$\R^(\X*?)\R^=+#$"m
155-
while (m = match(multiline_r, content); m !== nothing)
156-
newlines = sprint() do io
157-
foreach(l -> println(io, "# ", l), eachline(IOBuffer(m[1])))
153+
# unconditionally rewrite multiline comments and
154+
# conditionally multiline markdown strings to regular comments
155+
function replace_multiline(multiline_r, str)
156+
while (m = match(multiline_r, str); m !== nothing)
157+
newlines = sprint() do io
158+
foreach(l -> println(io, "# ", l), eachline(IOBuffer(m[1])))
159+
end
160+
str = replace(str, multiline_r => chop(newlines); count=1)
158161
end
159-
content = replace(content, multiline_r => chop(newlines); count=1)
162+
return str
163+
end
164+
content = replace_multiline(r"^#=+$\R^(\X*?)\R^=+#$"m, content)
165+
if config["mdstrings"]::Bool
166+
content = replace_multiline(r"^md\"\"\"$\R^(\X*?)\R^\"\"\"$"m, content)
160167
end
161168

169+
162170
# unconditionally remove #src lines
163171
push!(repls, r"^#src.*\n?"m => "") # remove leading #src lines
164172
push!(repls, r".*#src$\n?"m => "") # remove trailing #src lines
@@ -245,6 +253,7 @@ function create_configuration(inputfile; user_config, user_kwargs, type=nothing)
245253
cfg["postprocess"] = identity
246254
cfg["flavor"] = type === (:md) ? DocumenterFlavor() : DefaultFlavor()
247255
cfg["credit"] = true
256+
cfg["mdstrings"] = false
248257
cfg["keep_comments"] = false
249258
cfg["execute"] = type === :md ? false : true
250259
cfg["codefence"] = get(user_config, "flavor", cfg["flavor"]) isa DocumenterFlavor &&
@@ -439,7 +448,7 @@ function script(inputfile, outputdir=pwd(); config::Dict=Dict(), kwargs...)
439448
write(ioscript, '\n') # add a newline between each chunk
440449
elseif isa(chunk, MDChunk) && config["keep_comments"]::Bool
441450
for line in chunk.lines
442-
write(ioscript, rstrip(line.first * "# " * line.second * '\n'))
451+
write(ioscript, rstrip(line.first * "# " * line.second) * '\n')
443452
end
444453
write(ioscript, '\n') # add a newline between each chunk
445454
end

test/runtests.jl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,58 @@ const GITLAB_ENV = Dict(
436436
@test occursin("# First multiline", script)
437437
@test occursin("# Second multiline comment", script)
438438

439+
# mdstrings
440+
mdstrings_file = "inputfile_mdstrings.jl"
441+
write(mdstrings_file, """
442+
md\"\"\"
443+
# Markdown header
444+
445+
Content of the multiline markdown
446+
string
447+
\"\"\"
448+
#-
449+
#===
450+
# Markdown header 2
451+
452+
Content of the multiline
453+
comment
454+
===#
455+
2 + 2
456+
""")
457+
Literate.script(mdstrings_file, outdir,
458+
keep_comments = true, credit=false)
459+
script = read(joinpath(outdir, mdstrings_file), String)
460+
@test strip(script) == """
461+
md\"\"\"
462+
463+
# Markdown header
464+
465+
Content of the multiline markdown
466+
string
467+
\"\"\"
468+
469+
# # Markdown header 2
470+
#
471+
# Content of the multiline
472+
# comment
473+
474+
2 + 2"""
475+
Literate.script(mdstrings_file, outdir,
476+
keep_comments = true, mdstrings = true, credit=false)
477+
script = read(joinpath(outdir, mdstrings_file), String)
478+
@test strip(script) == """
479+
# # Markdown header
480+
#
481+
# Content of the multiline markdown
482+
# string
483+
484+
# # Markdown header 2
485+
#
486+
# Content of the multiline
487+
# comment
488+
489+
2 + 2"""
490+
439491
# verify that inputfile exists
440492
@test_throws ArgumentError Literate.script("nonexistent.jl", outdir)
441493

@@ -705,6 +757,11 @@ end end
705757
@test !occursin("name: inputfile", markdown)
706758
@test !occursin("name: @__NAME__", markdown)
707759

760+
# mdstrings
761+
Literate.markdown(inputfile, outdir, mdstrings = true)
762+
markdown = read(joinpath(outdir, "inputfile.md"), String)
763+
@test !occursin("md\"\"\"", markdown)
764+
708765
# execute
709766
write(inputfile, """
710767
using DisplayAs

0 commit comments

Comments
 (0)