using JSON, Mustache """ convert_doc(infile::AbstractString, outfile::AbstractString; outformat::Union{Nothing,AbstractString} = nothing) Convert Weave documents between different formats - `infile`: Path of the input document - `outfile`: Path of the output document - `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"` """ function convert_doc( infile::AbstractString, outfile::AbstractString; outformat::Union{Nothing,AbstractString} = nothing, ) doc = WeaveDoc(infile) if isnothing(outformat) ext = lowercase(splitext(outfile)[2]) outformat = ext == ".jl" ? "script" : ext == ".jmd" ? "markdown" : ext == ".ipynb" ? "notebook" : "noweb" # fallback end converted = _convert_doc(doc, outformat) open(outfile, "w") do f write(f, converted) end return outfile end 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) nb = Dict() nb["nbformat"] = 4 nb["nbformat_minor"] = 2 metadata = Dict() kernelspec = Dict() kernelspec["language"] = "julia" kernelspec["name"] = "julia-$(VERSION.major).$(VERSION.minor)" 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" language_info["name"] = "julia" 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) push!( cells, Dict( "cell_type" => "markdown", "metadata" => Dict(), "source" => [strip(join([repr(c) for c in chunk.content], ""))], ), ) else push!( cells, Dict( "cell_type" => "code", "metadata" => Dict(), "source" => [strip(chunk.content)], "execution_count" => nothing, "outputs" => [], ), ) end end nb["cells"] = cells nb["metadata"] = metadata json_nb = JSON.json(nb, 2) return json_nb end function convert_to_noweb(doc) 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 return output end Base.repr(c::InlineText) = c.content Base.repr(c::InlineCode) = "`j $(c.content)`"