# `Delta`
[🔗](https://github.com/slab/delta-elixir/blob/main/lib/delta.ex#L1)

# `t`

```elixir
@type t() :: [Delta.Op.t()]
```

# `compact`

```elixir
@spec compact(t()) :: t()
```

Compacts Delta to satisfy [compactness](https://quilljs.com/guides/designing-the-delta-format/#compact) requirement.

## Examples
    iex> delta = [Op.insert("Hel"), Op.insert("lo"), Op.insert("World", %{"bold" => true})]
    iex> Delta.compact(delta)
    [%{"insert" => "Hello"}, %{"insert" => "World", "attributes" => %{"bold" => true}}]

# `compose`

```elixir
@spec compose(t(), t()) :: t()
```

Returns a new Delta that is equivalent to applying the operations of one Delta, followed by another Delta

## Examples
    iex> a = [Op.insert("abc")]
    iex> b = [Op.retain(1), Op.delete(1)]
    iex> Delta.compose(a, b)
    [%{"insert" => "ac"}]

# `compose_all`

```elixir
@spec compose_all([t()]) :: t()
```

Returns a new Delta that is equivalent to applying Deltas one by one

## Examples
    iex> a = [Op.insert("ac")]
    iex> b = [Op.retain(1), Op.insert("b")]
    iex> c = [Op.delete(1)]
    iex> Delta.compose_all([a, b, c])
    [%{"insert" => "bc"}]

# `concat`

```elixir
@spec concat(t(), t()) :: t()
```

Concatenates two Deltas.

## Examples
    iex> a = [Op.insert("Hel")]
    iex> b = [Op.insert("lo")]
    iex> Delta.concat(a, b)
    [%{"insert" => "Hello"}]

# `diff`
*since 0.4.0* 

```elixir
@spec diff(t(), t()) :: t()
```

Returns a delta representing the difference between two documents.

## Examples
    iex> a = [Op.insert("Hello")]
    iex> b = [Op.insert("Hello!")]
    iex> diff = Delta.diff(a, b)
    [
      %{"retain" => 5},
      %{"insert" => "!"}
    ]
    iex> Delta.compose(a, diff) == b
    true

# `get_handler`

```elixir
@spec get_handler(atom()) :: module() | nil
```

# `get_handler!`

```elixir
@spec get_handler!(atom()) :: module()
```

# `invert`

```elixir
@spec invert(t(), t()) :: t()
```

Returns an inverted delta that has the opposite effect of against a base document delta.

That is base |> Delta.compose(change) |> Delta.compose(inverted) == base.

## Examples
    iex> base = [Op.insert("Hello\nWorld")]
    iex> change = [
    ...>   Op.retain(6, %{"bold" => true}),
    ...>   Op.delete(5),
    ...>   Op.insert("!"),
    ...> ]
    iex> inverted = Delta.invert(change, base)
    [
      %{"retain" => 6, "attributes" => %{"bold" => nil}},
      %{"insert" => "World"},
      %{"delete" => 1},
    ]
    iex> base |> Delta.compose(change) |> Delta.compose(inverted) == base
    true

# `push`

```elixir
@spec push(t(), false) :: t()
@spec push(t(), Delta.Op.t()) :: t()
```

Pushes an operation to a reversed Delta honouring semantics.

Note: that reversed delta does not represent a reversed text, but rather a list
of operations that was naively reversed during programmatic manipulations.
This function is normally only used by other functions which reverse the list
back in the end.

## Examples
    iex> delta = [Op.insert("World", %{"italic" => true}), Op.insert("Hello", %{"bold" => true})]
    iex> op = Op.insert("!")
    iex> Delta.push(delta, op)
    [%{"insert" => "!"}, %{"insert" => "World", "attributes" => %{"italic" => true}}, %{"insert" => "Hello", "attributes" => %{"bold" => true}}]

    iex> delta = [Op.insert("World"), Op.insert("Hello", %{"bold" => true})]
    iex> op = Op.insert("!")
    iex> Delta.push(delta, op)
    [%{"insert" => "World!"}, %{"insert" => "Hello", "attributes" => %{"bold" => true}}]

# `size`

```elixir
@spec size(t()) :: non_neg_integer()
```

Returns the size of delta.

## Examples
    iex> delta = [Op.insert("abc"), Op.retain(2), Op.delete(1)]
    iex> Delta.size(delta)
    6

# `slice`

```elixir
@spec slice(t(), non_neg_integer(), non_neg_integer()) :: t()
```

Attempts to take `len` characters starting from `index`.

Note: note that due to the way it's implemented this operation can potentially
raise if the resulting text isn't a valid UTF-8 encoded string

## Examples
    iex> delta = [Op.insert("Hello World")]
    iex> Delta.slice(delta, 6, 3)
    [%{"insert" => "Wor"}]

    iex> delta = [Op.insert("01🙋45")]
    iex> Delta.slice(delta, 1, 2)
    ** (RuntimeError) Encoding failed in take_partial {"1🙋45", %{"insert" => "1🙋45"}, 2, {:incomplete, "1", <<216, 61>>}, {:error, "", <<222, 75, 0, 52, 0, 53>>}}

# `slice_max`
*since 0.2.0* 

```elixir
@spec slice_max(t(), non_neg_integer(), non_neg_integer()) :: t()
```

Takes `len` or fewer characters from `index` position. Variable `len` allows
to not cut things like emojis in half.

## Examples
    iex> delta = [Op.insert("Hello World")]
    iex> Delta.slice_max(delta, 6, 3)
    [%{"insert" => "Wor"}]

    iex> delta = [Op.insert("01🙋45")]
    iex> Delta.slice_max(delta, 1, 2)
    [%{"insert" => "1"}]

# `split`

```elixir
@spec split(t(), non_neg_integer() | fun(), Keyword.t()) :: {t(), t()}
```

Splits delta at the given index.

## Options

  * `:align` - when `true`, allow moving index left if
    we're likely to split a grapheme otherwise.

## Examples
    iex> delta = [Op.insert("Hello World")]
    iex> Delta.split(delta, 5)
    {[%{"insert" => "Hello"}], [%{"insert" => " World"}]}

    iex> delta = [Op.insert("01🙋45")]
    iex> Delta.split(delta, 3, align: true)
    {[%{"insert" => "01"}], [%{"insert" => "🙋45"}]}

    iex> delta = [Op.insert("a"), Op.insert("b", %{"bold" => true})]
    iex> Delta.split(delta, 3)
    {[%{"insert" => "a"}, %{"insert" => "b", "attributes" => %{"bold" => true}}], []}

# `transform`

```elixir
@spec transform(t(), t(), boolean()) :: t()
```

Transforms given delta against another's operations.

This accepts an optional priority argument (default: false), used to break ties.
If true, the first delta takes priority over other, that is, its actions are considered to happen "first."

## Examples
    iex> a = [Op.insert("a")]
    iex> b = [Op.insert("b"), Op.retain(5), Op.insert("c")]
    iex> Delta.transform(a, b, true)
    [
      %{"retain" => 1},
      %{"insert" => "b"},
      %{"retain" => 5},
      %{"insert" => "c"},
    ]
    iex> Delta.transform(a, b)
    [
      %{"insert" => "b"},
      %{"retain" => 6},
      %{"insert" => "c"},
    ]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
