Literate.jl
Literate.jl copied to clipboard
Feature request: unliterate()
Just so this (from Julia Discourse) does not get lost: have you considered adding an unliterate()
?
from your reply on Discourse: See also https://github.com/oxinabox/ipynb2LiterateJulia
Just pasting a link to the referenced discourse post: https://discourse.julialang.org/t/way-to-add-tests-that-utilize-jupyter-notebooks/38341/6
Maybe also relevant: ipynb2LiterateJulia does not work with the new nbconvert, see https://github.com/oxinabox/ipynb2LiterateJulia/issues/8
To soothe my mind (after a certain cross country relay) I attempted a rewrite of the archived JuliaAcademy material. The simple code below actually allows for a roundtrip (Literate.notebook(),unliterate(),...) without changing anything. Since my notebooks do not contain any important metadata, I did not implement anything for that.
"""
unliterate(input,outputdir=pwd())
Convert a ipynb notebook to a jl script. Based on code from the Julia Academy, but simplified.
If input is a directory, then all notebooks in that directly are converted.
"""
function unliterate(input,outputdir=pwd())
!isdir(outputdir) && error("$outputdir is not a directory")
if isdir(input)
Files = filter(x->splitext(x)[2]==".ipynb", readdir(input,join=true)) #all .ipynb files
for file in Files
unliterate(file,outputdir)
end
return
end
outputfile = joinpath(outputdir, splitext(basename(input))[1] * ".jl")
println(input,"\n",outputfile,"\n")
nb = open(JSON.parse,input, "r")
ioscript = IOBuffer()
prev_type = ""
for cell in nb["cells"]
cell["cell_type"] == prev_type && print(ioscript, "#-\n\n")
#if !isempty(cell["metadata"])
# println(cell["metadata"])
# @warn("Still not implemented. Use parse_nbmeta here?")
#end
if cell["cell_type"] == "markdown"
for line in cell["source"]
print(ioscript, "# ", line)
end
elseif cell["cell_type"] == "code"
for line in cell["source"]
line_i = lstrip(line)
if startswith(line_i, "#") && !startswith(line_i, "##")
print(ioscript, "#", line_i)
else
print(ioscript, line)
end
end
end
print(ioscript,"\n\n")
prev_type = cell["cell_type"]
end
content = String(take!(ioscript))
open(outputfile, "w") do io
print(io, content)
end
return
end
#------------------------------------------------------------------------------
and from stevengj's answer at discourse (https://discourse.julialang.org/t/export-jupyter-to-jl-does-not-preserve-markdown-cells/57556)
using JSON, Markdown
function ipynb2jl(ipynfile)
jlfile = replace(ipynfile, r"(\.ipynb)?$" => ".jl")
nb = open(JSON.parse, ipynfile, "r")
open(jlfile, "w") do f
for cell in nb["cells"]
if cell["cell_type"] == "code"
print(f, "\n\n")
print.(Ref(f), cell["source"])
elseif cell["cell_type"] == "markdown"
md = Markdown.parse(join(cell["source"]))
print(f, "\n\n# ", replace(repr("text/plain", md), '\n' => "\n# "))
end
end
end
end
@PaulSoderlind thanks a million, I just found this - you've saved me a lot of hassle.
The package NBInclude provides a function nbexport(filename, notebookfile)
that generates a .jl from a .pynb.