Weave.jl/src/converter.jl

145 lines
4.2 KiB
Julia
Raw Normal View History

2020-05-15 17:32:28 +02:00
using JSON, Mustache
2016-12-12 13:05:26 +01:00
"""
2020-05-15 17:32:28 +02:00
convert_doc(infile::AbstractString, outfile::AbstractString; outformat::Union{Nothing,AbstractString} = nothing)
2016-12-12 13:05:26 +01:00
Convert Weave documents between different formats
2020-03-26 09:35:05 +01:00
- `infile`: Path of the input document
- `outfile`: Path of the output document
2020-05-15 17:32:28 +02:00
- `outformat = nothing`: Output document format (optional). By default (i.e. given `nothing`) Weave will try to automatically detect it from the `outfile`'s extension. You can also specify either of `"script"`, `"markdown"`, `"notebook"`, or `"noweb"`
2016-12-12 13:05:26 +01:00
"""
2020-05-08 16:39:17 +02:00
function convert_doc(
infile::AbstractString,
outfile::AbstractString;
2020-05-15 17:32:28 +02:00
outformat::Union{Nothing,AbstractString} = nothing,
2020-05-08 16:39:17 +02:00
)
doc = WeaveDoc(infile)
2020-05-15 17:32:28 +02:00
if isnothing(outformat)
ext = lowercase(splitext(outfile)[2])
outformat =
ext == ".jl" ? "script" :
ext == ".jmd" ? "markdown" :
ext == ".ipynb" ? "notebook" :
"noweb" # fallback
end
2016-12-12 13:05:26 +01:00
2020-05-15 17:32:28 +02:00
converted = _convert_doc(doc, outformat)
2020-05-08 16:39:17 +02:00
open(outfile, "w") do f
write(f, converted)
end
2020-05-15 17:32:28 +02:00
return outfile
end
2020-05-15 17:32:28 +02:00
function _convert_doc(doc, outformat)
outformat == "script" ? convert_to_script(doc) :
outformat == "markdown" ? convert_to_markdown(doc) :
outformat == "notebook" ? convert_to_notebook(doc) :
convert_to_noweb(doc)
end
function convert_to_script(doc)
output = ""
for chunk in doc.chunks
if typeof(chunk) == Weave.DocChunk
content = join([repr(c) for c in chunk.content], "")
output *= join(["#' " * s for s in split(content, "\n")], "\n")
else
output *= "\n#+ "
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
output *= "\n\n" * lstrip(chunk.content)
output *= "\n"
end
end
return output
end
function convert_to_markdown(doc)
output = ""
for chunk in doc.chunks
if isa(chunk, DocChunk)
output *= join([repr(c) for c in chunk.content], "")
else
output *= "\n" * "```julia"
isempty(chunk.optionstring) || (output *= ";" * chunk.optionstring)
output *= "\n" * lstrip(chunk.content)
output *= "```\n"
end
end
return output
end
function convert_to_notebook(doc)
2019-02-26 08:12:28 +01:00
nb = Dict()
2020-05-08 16:39:17 +02:00
nb["nbformat"] = 4
2019-02-26 08:12:28 +01:00
nb["nbformat_minor"] = 2
metadata = Dict()
kernelspec = Dict()
2020-05-08 16:39:17 +02:00
kernelspec["language"] = "julia"
kernelspec["name"] = "julia-$(VERSION.major).$(VERSION.minor)"
2019-02-26 08:12:28 +01:00
kernelspec["display_name"] = "Julia $(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
metadata["kernelspec"] = kernelspec
language_info = Dict()
language_info["file_extension"] = ".jl"
language_info["mimetype"] = "application/julia"
2020-05-08 16:39:17 +02:00
language_info["name"] = "julia"
2019-02-26 08:12:28 +01:00
language_info["version"] = "$(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
metadata["language_info"] = language_info
cells = []
ex_count = 1
for chunk in doc.chunks
if isa(chunk, DocChunk)
2020-05-08 16:39:17 +02:00
push!(
cells,
Dict(
"cell_type" => "markdown",
"metadata" => Dict(),
"source" => [strip(join([repr(c) for c in chunk.content], ""))],
),
)
2019-02-26 08:12:28 +01:00
else
2020-05-08 16:39:17 +02:00
push!(
cells,
Dict(
"cell_type" => "code",
"metadata" => Dict(),
"source" => [strip(chunk.content)],
"execution_count" => nothing,
"outputs" => [],
),
)
end
end
2019-02-26 08:12:28 +01:00
nb["cells"] = cells
nb["metadata"] = metadata
json_nb = JSON.json(nb, 2)
return json_nb
end
2020-05-15 17:32:28 +02:00
function convert_to_noweb(doc)
2020-05-08 16:39:17 +02:00
output = ""
for chunk in doc.chunks
if isa(chunk, DocChunk)
output *= join([repr(c) for c in chunk.content], "")
else
output *= "\n" * "<<"
isempty(chunk.optionstring) || (output *= strip(chunk.optionstring))
output *= ">>="
output *= "\n" * lstrip(chunk.content)
output *= "@\n"
end
end
2020-05-08 16:39:17 +02:00
return output
end
2020-05-15 17:32:28 +02:00
Base.repr(c::InlineText) = c.content
Base.repr(c::InlineCode) = "`j $(c.content)`"