Packages
livebook
0.7.1
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook/notebook/export/elixir.ex
defmodule Livebook.Notebook.Export.Elixir do
alias Livebook.Notebook
alias Livebook.Notebook.Cell
@doc """
Converts the given notebook into a Elixir source code.
"""
@spec notebook_to_elixir(Notebook.t()) :: String.t()
def notebook_to_elixir(notebook) do
iodata = render_notebook(notebook)
# Add trailing newline
IO.iodata_to_binary([iodata, "\n"])
end
defp render_notebook(notebook) do
%{setup_section: %{cells: [setup_cell]} = setup_section} = notebook
prelude = "# Run as: iex --dot-iex path/to/notebook.exs"
name = ["# Title: ", notebook.name]
setup_cell = render_setup_cell(setup_cell, setup_section)
sections = Enum.map(notebook.sections, &render_section(&1, notebook))
[prelude, name, setup_cell | sections]
|> Enum.reject(&is_nil/1)
|> Enum.intersperse("\n\n")
end
defp render_section(section, notebook) do
name = ["# ── ", section.name, " ──"]
name =
if section.parent_id do
{:ok, parent} = Notebook.fetch_section(notebook, section.parent_id)
[name, " (⎇ from ", parent.name, ")"]
else
name
end
cells =
section.cells
|> Enum.map(&render_cell(&1, section))
|> Enum.reject(&(&1 == []))
[name | cells]
|> Enum.intersperse("\n\n")
end
defp render_setup_cell(%{source: ""}, _section), do: nil
defp render_setup_cell(cell, section), do: render_cell(cell, section)
defp render_cell(%Cell.Markdown{} = cell, _section) do
cell.source
|> Livebook.LiveMarkdown.MarkdownHelpers.reformat()
|> String.split("\n")
|> Enum.map_intersperse("\n", &comment_out/1)
end
defp render_cell(%Cell.Code{} = cell, section) do
code = get_code_cell_code(cell)
if section.parent_id do
code
|> IO.iodata_to_binary()
|> String.split("\n")
|> Enum.map_intersperse("\n", &comment_out/1)
else
code
end
end
defp render_cell(%Cell.Smart{} = cell, ctx) do
render_cell(%{Cell.Code.new() | source: cell.source}, ctx)
end
defp render_cell(_cell, _section), do: []
defp comment_out(""), do: ""
defp comment_out(line), do: ["# ", line]
defp get_code_cell_code(%{source: source, disable_formatting: true}),
do: source
defp get_code_cell_code(%{source: source}), do: format_code(source)
defp format_code(code) do
try do
Code.format_string!(code)
rescue
_ -> code
end
end
end