Text splitting operations at offset boundaries.
Splits text nodes so that mark operations can be applied to precise ranges.
Summary
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
Functions
@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
@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: []}, []}]
@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: []}, []}]