From 464e30fa98d34896fb129f9012451ff6cc196b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Fri, 8 Jan 2021 15:24:13 +0100 Subject: [PATCH] Add initial notebook data structure (#4) * Add initial notebook data structure * Move required frields out of metadata --- lib/live_book/notebook.ex | 39 +++++++++++++++++++++++++++++++ lib/live_book/notebook/cell.ex | 39 +++++++++++++++++++++++++++++++ lib/live_book/notebook/section.ex | 35 +++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 lib/live_book/notebook.ex create mode 100644 lib/live_book/notebook/cell.ex create mode 100644 lib/live_book/notebook/section.ex diff --git a/lib/live_book/notebook.ex b/lib/live_book/notebook.ex new file mode 100644 index 000000000..d7f927339 --- /dev/null +++ b/lib/live_book/notebook.ex @@ -0,0 +1,39 @@ +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 [:name, :version, :sections, :metadata] + + alias LiveBook.Notebook.Section + + @type t :: %__MODULE__{ + name: String.t(), + version: String.t(), + sections: list(Section.t()), + metadata: %{atom() => term()} + } + + @version "1.0" + + @doc """ + Returns a blank notebook. + """ + @spec new() :: t() + def new() do + %__MODULE__{ + name: "Untitled notebook", + version: @version, + sections: [], + metadata: %{} + } + end +end diff --git a/lib/live_book/notebook/cell.ex b/lib/live_book/notebook/cell.ex new file mode 100644 index 000000000..210c0ba1b --- /dev/null +++ b/lib/live_book/notebook/cell.ex @@ -0,0 +1,39 @@ +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, :type, :source, :outputs, :metadata] + + alias LiveBook.Utils + + @type cell_id :: Utils.id() + @type cell_type :: :markdown | :elixir + + @type t :: %__MODULE__{ + id: cell_id(), + type: cell_type(), + source: String.t(), + # TODO: expand on this + outputs: list(), + metadata: %{atom() => term()} + } + + @doc """ + Returns an empty cell of the given type. + """ + @spec new(cell_type()) :: t() + def new(type) do + %__MODULE__{ + id: Utils.random_id(), + type: type, + source: "", + outputs: [], + metadata: %{} + } + end +end diff --git a/lib/live_book/notebook/section.ex b/lib/live_book/notebook/section.ex new file mode 100644 index 000000000..7fe788b15 --- /dev/null +++ b/lib/live_book/notebook/section.ex @@ -0,0 +1,35 @@ +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, :name, :cells, :metadata] + + alias LiveBook.Notebook.Cell + alias LiveBook.Utils + + @type section_id :: Utils.id() + + @type t :: %__MODULE__{ + id: section_id(), + name: String.t(), + cells: list(Cell.t()), + metadata: %{atom() => term()} + } + + @doc """ + Returns a blank section. + """ + @spec new() :: t() + def new() do + %__MODULE__{ + id: Utils.random_id(), + name: "Section", + cells: [], + metadata: %{} + } + end +end