Quillon.Transform.Split (Quillon v0.1.0)

Copy Markdown View Source

Text splitting operations at offset boundaries.

Splits text nodes so that mark operations can be applied to precise ranges.

Summary

Types

List of inline children (text nodes)

A text node tuple

Functions

Find the node at a given offset.

Split text nodes at a given offset within the children list.

Split text nodes at both start and end offsets for a range.

Types

children()

@type children() :: [text_node()]

List of inline children (text nodes)

text_node()

@type text_node() :: {:text, %{text: String.t(), marks: list()}, []}

A text node tuple

Functions

find_node_at_offset(children, offset)

@spec find_node_at_offset(children(), non_neg_integer()) ::
  {children(), text_node() | nil, children(), non_neg_integer()}

Find the node at a given offset.

Returns {before_nodes, target_node, after_nodes, offset_in_node}.

Examples

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> {before, target, after_nodes, offset_in_node} = Quillon.Transform.Split.find_node_at_offset(children, 7)
iex> before
[{:text, %{text: "Hello", marks: []}, []}]
iex> target
{:text, %{text: " world", marks: []}, []}
iex> after_nodes
[]
iex> offset_in_node
2

split_at_offset(children, offset)

@spec split_at_offset(children(), non_neg_integer()) :: children()

Split text nodes at a given offset within the children list.

Returns unchanged list if offset falls on a node boundary. Preserves marks when splitting a node.

Examples

iex> children = [{:text, %{text: "Hello world", marks: []}, []}]
iex> Quillon.Transform.Split.split_at_offset(children, 5)
[
  {:text, %{text: "Hello", marks: []}, []},
  {:text, %{text: " world", marks: []}, []}
]

iex> children = [{:text, %{text: "Hello world", marks: [:bold]}, []}]
iex> Quillon.Transform.Split.split_at_offset(children, 5)
[
  {:text, %{text: "Hello", marks: [:bold]}, []},
  {:text, %{text: " world", marks: [:bold]}, []}
]

iex> children = [{:text, %{text: "Hello", marks: []}, []}]
iex> Quillon.Transform.Split.split_at_offset(children, 0)
[{:text, %{text: "Hello", marks: []}, []}]

iex> children = [{:text, %{text: "Hello", marks: []}, []}]
iex> Quillon.Transform.Split.split_at_offset(children, 5)
[{:text, %{text: "Hello", marks: []}, []}]

split_range(children, start_offset, end_offset)

@spec split_range(children(), non_neg_integer(), non_neg_integer()) :: children()

Split text nodes at both start and end offsets for a range.

Splits at END first, then START to preserve start offset position. This is crucial for correct mark application.

Examples

iex> children = [{:text, %{text: "Hello world", marks: []}, []}]
iex> Quillon.Transform.Split.split_range(children, 2, 7)
[
  {:text, %{text: "He", marks: []}, []},
  {:text, %{text: "llo w", marks: []}, []},
  {:text, %{text: "orld", marks: []}, []}
]

iex> children = [{:text, %{text: "Hello", marks: []}, []}]
iex> Quillon.Transform.Split.split_range(children, 0, 5)
[{:text, %{text: "Hello", marks: []}, []}]