Quillon.Transform.Position (Quillon v0.1.0)

Copy Markdown View Source

Position mapping between flat offsets and node paths.

Converts between:

  • Flat offset: single integer counting characters from start
  • Node position: {node_index, offset_within_node} tuple

Summary

Types

List of inline children (text nodes)

Position as {node_index, offset_within_node}

A text node tuple

Functions

Get the text length of a single text node.

Get nodes fully contained within a given offset range.

Get all text nodes that overlap with a given offset range.

Convert a flat offset to a node position {node_index, offset_within_node}.

Convert a node position to a flat offset.

Calculate the total text length of a list of text nodes.

Types

children()

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

List of inline children (text nodes)

position()

@type position() :: {non_neg_integer(), non_neg_integer()}

Position as {node_index, offset_within_node}

text_node()

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

A text node tuple

Functions

node_length(arg)

@spec node_length(text_node()) :: non_neg_integer()

Get the text length of a single text node.

Examples

iex> Quillon.Transform.Position.node_length({:text, %{text: "Hello", marks: []}, []})
5

iex> Quillon.Transform.Position.node_length({:text, %{text: "", marks: []}, []})
0

nodes_fully_in_range(children, start_offset, end_offset)

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

Get nodes fully contained within a given offset range.

A node is fully contained if its entire text falls within [start_offset, end_offset].

Examples

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

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " ", marks: []}, []},
...>   {:text, %{text: "world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.nodes_fully_in_range(children, 0, 11)
[
  {:text, %{text: "Hello", marks: []}, []},
  {:text, %{text: " ", marks: []}, []},
  {:text, %{text: "world", marks: []}, []}
]

nodes_in_range(children, start_offset, end_offset)

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

Get all text nodes that overlap with a given offset range.

A node overlaps if any part of it falls within [start_offset, end_offset).

Examples

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

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.nodes_in_range(children, 3, 8)
[
  {:text, %{text: "Hello", marks: []}, []},
  {:text, %{text: " world", marks: []}, []}
]

offset_to_position(children, offset)

@spec offset_to_position(children(), non_neg_integer()) :: position()

Convert a flat offset to a node position {node_index, offset_within_node}.

If offset is at a node boundary, returns the end of the previous node. If offset is beyond content, returns the end of the last node.

Examples

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

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.offset_to_position(children, 3)
{0, 3}

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.offset_to_position(children, 7)
{1, 2}

position_to_offset(children, arg)

@spec position_to_offset(children(), position()) :: non_neg_integer()

Convert a node position to a flat offset.

Examples

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.position_to_offset(children, {0, 3})
3

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.position_to_offset(children, {1, 2})
7

total_length(children)

@spec total_length(children()) :: non_neg_integer()

Calculate the total text length of a list of text nodes.

Examples

iex> children = [
...>   {:text, %{text: "Hello", marks: []}, []},
...>   {:text, %{text: " world", marks: []}, []}
...> ]
iex> Quillon.Transform.Position.total_length(children)
11

iex> Quillon.Transform.Position.total_length([])
0