|
|
|
@ -6,7 +6,7 @@ https://fredrikekre.github.io/Literate.jl/ for documentation. |
|
|
|
""" |
|
|
|
""" |
|
|
|
module Literate |
|
|
|
module Literate |
|
|
|
|
|
|
|
|
|
|
|
import JSON, REPL, IOCapture |
|
|
|
import JSON, REPL, IOCapture, CommonMark |
|
|
|
|
|
|
|
|
|
|
|
include("IJulia.jl") |
|
|
|
include("IJulia.jl") |
|
|
|
import .IJulia |
|
|
|
import .IJulia |
|
|
|
@ -16,6 +16,7 @@ struct DefaultFlavor <: AbstractFlavor end |
|
|
|
struct DocumenterFlavor <: AbstractFlavor end |
|
|
|
struct DocumenterFlavor <: AbstractFlavor end |
|
|
|
struct CommonMarkFlavor <: AbstractFlavor end |
|
|
|
struct CommonMarkFlavor <: AbstractFlavor end |
|
|
|
struct FranklinFlavor <: AbstractFlavor end |
|
|
|
struct FranklinFlavor <: AbstractFlavor end |
|
|
|
|
|
|
|
struct CarpentriesFlavor <: AbstractFlavor end |
|
|
|
|
|
|
|
|
|
|
|
# # Some simple rules: |
|
|
|
# # Some simple rules: |
|
|
|
# |
|
|
|
# |
|
|
|
@ -246,7 +247,7 @@ function edit_commit(inputfile, user_config) |
|
|
|
readchomp( |
|
|
|
readchomp( |
|
|
|
pipeline( |
|
|
|
pipeline( |
|
|
|
setenv(`$(git) rev-parse --show-toplevel`; dir=dirname(inputfile)); |
|
|
|
setenv(`$(git) rev-parse --show-toplevel`; dir=dirname(inputfile)); |
|
|
|
stderr=devnull, |
|
|
|
stderr=devnull |
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
catch |
|
|
|
catch |
|
|
|
@ -527,6 +528,56 @@ function script(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwargs. |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#_______________________________________________________________________________________ |
|
|
|
|
|
|
|
# Define general functions needed for admonitions formating. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function containsAdmonition(chunk) |
|
|
|
|
|
|
|
for line in chunk.lines |
|
|
|
|
|
|
|
if startswith(strip(line.first * line.second), "!!!") |
|
|
|
|
|
|
|
return true |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
return false |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function chunkToMD(chunk) |
|
|
|
|
|
|
|
parser = CommonMark.Parser() |
|
|
|
|
|
|
|
CommonMark.enable!(parser, CommonMark.AdmonitionRule()) |
|
|
|
|
|
|
|
buffer = IOBuffer() |
|
|
|
|
|
|
|
for line in chunk.lines |
|
|
|
|
|
|
|
write(buffer, line.first * line.second, '\n') |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
str = String(take!(buffer)) |
|
|
|
|
|
|
|
return parser(str) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function rewriteContent!(mdContent) |
|
|
|
|
|
|
|
for (node, entering) in mdContent |
|
|
|
|
|
|
|
if isa(node.t, CommonMark.Admonition) |
|
|
|
|
|
|
|
admonition = node.t |
|
|
|
|
|
|
|
node.t = CommonMark.Paragraph() |
|
|
|
|
|
|
|
if admonition.category == "yaml" |
|
|
|
|
|
|
|
node.first_child.t = CommonMark.Text() |
|
|
|
|
|
|
|
node.first_child.nxt.t = CommonMark.Paragraph() |
|
|
|
|
|
|
|
CommonMark.insert_after(node.first_child.nxt.last_child, CommonMark.text("\n---\n")) |
|
|
|
|
|
|
|
CommonMark.insert_before(node.first_child.nxt, CommonMark.text("---\n")) |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
CommonMark.insert_before(node, CommonMark.text(""":::::: $(admonition.category) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## $(admonition.title) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
""")) |
|
|
|
|
|
|
|
CommonMark.insert_after(node, CommonMark.text("::::::\n\n")) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
mdContent |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#_______________________________________________________________________________________ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
|
""" |
|
|
|
Literate.markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwargs...) |
|
|
|
Literate.markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwargs...) |
|
|
|
|
|
|
|
|
|
|
|
@ -540,12 +591,37 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg |
|
|
|
# preprocessing and parsing |
|
|
|
# preprocessing and parsing |
|
|
|
chunks, config = |
|
|
|
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 |
|
|
|
# create the markdown file |
|
|
|
sb = sandbox() |
|
|
|
|
|
|
|
iomd = IOBuffer() |
|
|
|
iomd = IOBuffer() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
write_md_chunks!(iomd, chunks, outputdir, config) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# custom post-processing from user |
|
|
|
|
|
|
|
content = config["postprocess"](String(take!(iomd))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# write to file |
|
|
|
|
|
|
|
outputfile = write_result(content, config) |
|
|
|
|
|
|
|
return outputfile |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function write_md_chunks!(iomd, chunks, outputdir, config) |
|
|
|
|
|
|
|
flavor = config["flavor"] |
|
|
|
|
|
|
|
sb = sandbox() |
|
|
|
for (chunknum, chunk) in enumerate(chunks) |
|
|
|
for (chunknum, chunk) in enumerate(chunks) |
|
|
|
if isa(chunk, MDChunk) |
|
|
|
if isa(chunk, MDChunk) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if flavor isa CarpentriesFlavor |
|
|
|
|
|
|
|
if containsAdmonition(chunk) |
|
|
|
|
|
|
|
md_chunk = chunkToMD(chunk) |
|
|
|
|
|
|
|
rewriteContent!(md_chunk) |
|
|
|
|
|
|
|
CommonMark.markdown(iomd, md_chunk) |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
for line in chunk.lines |
|
|
|
for line in chunk.lines |
|
|
|
write(iomd, line.second, '\n') # skip indent here |
|
|
|
write(iomd, line.second, '\n') # skip indent here |
|
|
|
end |
|
|
|
end |
|
|
|
@ -578,21 +654,16 @@ function markdown(inputfile, outputdir=pwd(); config::AbstractDict=Dict(), kwarg |
|
|
|
fake_source=config["literate_outputfile"], |
|
|
|
fake_source=config["literate_outputfile"], |
|
|
|
flavor=config["flavor"], |
|
|
|
flavor=config["flavor"], |
|
|
|
image_formats=config["image_formats"], |
|
|
|
image_formats=config["image_formats"], |
|
|
|
file_prefix="$(config["name"])-$(chunknum)", |
|
|
|
file_prefix="$(config["name"])-$(chunknum)" |
|
|
|
) |
|
|
|
) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
write(iomd, '\n') # add a newline between each chunk |
|
|
|
write(iomd, '\n') # add a newline between each chunk |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
# custom post-processing from user |
|
|
|
|
|
|
|
content = config["postprocess"](String(take!(iomd))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# write to file |
|
|
|
|
|
|
|
outputfile = write_result(content, config) |
|
|
|
|
|
|
|
return outputfile |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function execute_markdown!(io::IO, sb::Module, block::String, outputdir; |
|
|
|
function execute_markdown!(io::IO, sb::Module, block::String, outputdir; |
|
|
|
inputfile::String, fake_source::String, |
|
|
|
inputfile::String, fake_source::String, |
|
|
|
@ -601,7 +672,8 @@ function execute_markdown!(io::IO, sb::Module, block::String, outputdir; |
|
|
|
r, str, _ = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source) |
|
|
|
r, str, _ = execute_block(sb, block; inputfile=inputfile, fake_source=fake_source) |
|
|
|
# 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 |
|
|
|
# issue #144: quadruple backticks allow for triple backticks in the output |
|
|
|
plain_fence = "\n````\n" => "\n````" |
|
|
|
plain_fence = "\n````$(flavor == CarpentriesFlavor() ? "output" : "")\n" => "\n````" |
|
|
|
|
|
|
|
# Here CarpentiresFlavor fork... |
|
|
|
if r !== nothing && !REPL.ends_with_semicolon(block) |
|
|
|
if r !== nothing && !REPL.ends_with_semicolon(block) |
|
|
|
if (flavor isa FranklinFlavor || flavor isa DocumenterFlavor) && |
|
|
|
if (flavor isa FranklinFlavor || flavor isa DocumenterFlavor) && |
|
|
|
Base.invokelatest(showable, MIME("text/html"), r) |
|
|
|
Base.invokelatest(showable, MIME("text/html"), r) |
|
|
|
|