diff --git a/lib/live_book/notebook.ex b/lib/live_book/notebook.ex new file mode 100644 index 000000000..ad3ef02ce --- /dev/null +++ b/lib/live_book/notebook.ex @@ -0,0 +1,43 @@ +defmodule LiveBook.Notebook do + @moduledoc """ + Data structure representing a notebook. + + A notebook it's just the representation and roughly + maps to a file that the user can edit. + A notebook *session* is a living process that holds a specific + notebook instance and allows users to collaboratively apply + changes to this notebook. + + A notebook is divided into a set of isolated *sections*. + """ + + defstruct [:metadata, :sections] + + alias LiveBook.Notebook.Section + + @type t :: %__MODULE__{ + metadata: metadata(), + sections: list(Section.t()) + } + + @type metadata :: %{ + name: String.t(), + version: String.t() + } + + @version "1.0" + + @doc """ + Returns a blank notebook. + """ + @spec new() :: t() + def new() do + %__MODULE__{ + metadata: %{ + name: "Untitled notebook", + version: @version + }, + sections: [] + } + end +end diff --git a/lib/live_book/notebook/cell.ex b/lib/live_book/notebook/cell.ex new file mode 100644 index 000000000..0db9b71a1 --- /dev/null +++ b/lib/live_book/notebook/cell.ex @@ -0,0 +1,41 @@ +defmodule LiveBook.Notebook.Cell do + @moduledoc """ + Data structure representing a single cell in a notebook. + + A cell is the smallest unit of work in a notebook. + It primarly consists of text content that the user can edit + and may potentially produce some output (e.g. during code execution). + """ + + defstruct [:id, :metadata, :type, :source, :outputs] + + alias LiveBook.Utils + + @type cell_id :: Utils.id() + @type cell_type :: :markdown | :elixir + + @type t :: %__MODULE__{ + id: cell_id(), + metadata: metadata(), + type: cell_type(), + source: String.t(), + # TODO: expand on this + outputs: list() + } + + @type metadata :: %{} + + @doc """ + Returns an empty cell of the given type. + """ + @spec new(cell_type()) :: t() + def new(type) do + %__MODULE__{ + id: Utils.random_id(), + metadata: %{}, + type: type, + source: "", + outputs: [] + } + end +end diff --git a/lib/live_book/notebook/section.ex b/lib/live_book/notebook/section.ex new file mode 100644 index 000000000..e99be3d3b --- /dev/null +++ b/lib/live_book/notebook/section.ex @@ -0,0 +1,39 @@ +defmodule LiveBook.Notebook.Section do + @moduledoc """ + Data structure representing a single section in a notebook. + + Each section contains a number of cells and is isolated + in the sense that cells don't interfere with cells in other sections. + """ + + defstruct [:id, :metadata, :cells] + + alias LiveBook.Notebook.Cell + alias LiveBook.Utils + + @type section_id :: Utils.id() + + @type t :: %__MODULE__{ + id: section_id(), + metadata: metadata(), + cells: list(Cell.t()) + } + + @type metadata :: %{ + name: String.t() + } + + @doc """ + Returns a blank section. + """ + @spec new() :: t() + def new() do + %__MODULE__{ + id: Utils.random_id(), + metadata: %{ + name: "Section" + }, + cells: [] + } + end +end