text_delta v1.0.2 TextDelta.Delta
Delta is a format used to describe documents and changes.
Delta can describe any rich text changes or a rich document itself, preserving all the formatting.
At the baseline level, delta is an array of operations (constructed via
TextDelta.Operation
). Operations can be either
TextDelta.Operation.insert/0
, TextDelta.Operation.retain/0
or
TextDelta.Operation.delete/0
. None of the operations contain index,
meaning that delta aways describes document or a change staring from the very
beginning.
Delta can describe both changes to and documents themselves. We can think of a
document as an artefact of all the changes applied to it. This way, newly
imported document can be thinked of as simply a sequence of insert
s applied
to an empty document.
Deltas are composable. This means that a document delta can be composed with another delta for that document, resulting in a shorter, optimized delta.
Deltas are also transformable. This attribute of deltas is what enables Operational Transformation - a way to transform one operation against the context of another one. Operational Transformation allows us to build optimistic, non-locking collaborative editors.
The format for deltas was deliberately copied from Quill - a rich text editor for web. This library aims to be an Elixir counter-part for Quill, enabling us to build matching backends for the editor.
Example
iex> alias TextDelta.Delta
iex> delta = Delta.new() |> Delta.insert("Gandalf", %{bold: true})
[%{insert: "Gandalf", attributes: %{bold: true}}]
iex> delta = delta |> Delta.insert(" the ")
[%{insert: "Gandalf", attributes: %{bold: true}}, %{insert: " the "}]
iex> delta |> Delta.insert("Grey", %{color: "#ccc"})
[%{insert: "Gandalf", attributes: %{bold: true}}, %{insert: " the "},
%{insert: "Grey", attributes: %{color: "#ccc"}}]
Summary
Types
A document represented as delta. Any rich document can be represented as a set
of TextDelta.Operation.insert/0
operations
Delta is a list of TextDelta.Operation.retain/0
,
TextDelta.Operation.insert/0
, or TextDelta.Operation.delete/0
operations
Functions
Appends given operation to the delta
Creates and appends new delete operation to the delta
Creates and appends new insert operation to the delta
Creates new delta
Creates and appends new retain operation to the delta
Trims trailing retains from the end of a given delta
Types
A document represented as delta. Any rich document can be represented as a set
of TextDelta.Operation.insert/0
operations.
Delta is a list of TextDelta.Operation.retain/0
,
TextDelta.Operation.insert/0
, or TextDelta.Operation.delete/0
operations.
Functions
Appends given operation to the delta.
Before adding operation to the delta, this function attempts to compact it by applying 2 simple rules:
- Delete followed by insert is swapped to ensure that insert goes first.
- Same operations with the same attributes are merged.
These two rules ensure that our deltas are always as short as possible and canonical, making it easier to compare, compose and transform them.
Example
iex> operation = TextDelta.Operation.insert("hello")
iex> TextDelta.Delta.new() |> TextDelta.Delta.append(operation)
[%{insert: "hello"}]
Creates and appends new delete operation to the delta.
TextDelta.Delta.append/2
is used undert the hood to add operation to the
delta after construction. So all append
rules apply.
Example
iex> alias TextDelta.Delta
iex> Delta.new() |> Delta.delete(3)
[%{delete: 3}]
Creates and appends new insert operation to the delta.
Same as with underlying TextDelta.Operation.insert/2
function, attributes
are optional.
TextDelta.Delta.append/2
is used undert the hood to add operation to the
delta after construction. So all append
rules apply.
Example
iex> alias TextDelta.Delta
iex> Delta.new() |> Delta.insert("hello", %{bold: true})
[%{insert: "hello", attributes: %{bold: true}}]
Creates new delta.
Creates and appends new retain operation to the delta.
Same as with underlying TextDelta.Operation.retain/2
function, attributes
are optional.
TextDelta.Delta.append/2
is used undert the hood to add operation to the
delta after construction. So all append
rules apply.
Example
iex> alias TextDelta.Delta
iex> Delta.new() |> Delta.retain(5, %{italic: true})
[%{retain: 5, attributes: %{italic: true}}]