NestedLines (nested_lines v0.1.6)

Documentation for NestedLines.

Summary

Functions

Returns true if the line can be indented, false otherwise. Lines are 1-indexed.

Returns true if the line can be outdented, false otherwise. Lines are 1-indexed.

Returns a boolean indicating if the line at the given position has children

Indents a line based on its index, raises if the line cannot be indented. Child lines are also indented by one position. Lines are 1-indexed.

Output a string representation of the line numbers.

Construct a nested line representation from a list of string values. Returns {:ok, %NestedLines{}} if the input is valid, otherwise returns {:error, :invalid_inputs_empty} if the input list is empty, {:error, :invalid_initial_line_nesting} if the first line is indented, or {:error, :invalid_list} if the input is not a list.

Construct a nested line representation from a list of string values.

Outdents a line based on its index, raises if the line cannot be outdented. Child lines are also outdented by one position. Lines are 1-indexed.

Returns a tree representation of the input lines.

Types

@type line() :: [line_number()]
Link to this type

line_number()

@type line_number() :: 0..1
@type t() :: %NestedLines{lines: [line()]}

Functions

Link to this function

can_indent?(nested_lines, position)

@spec can_indent?(t(), pos_integer()) :: boolean()

Returns true if the line can be indented, false otherwise. Lines are 1-indexed.

Examples

iex> NestedLines.new!(["1", "1.1", "1.2"]) |> NestedLines.can_indent?(1)
false

iex> NestedLines.new!(["1", "1.1", "1.2"]) |> NestedLines.can_indent?(3)
true

iex> NestedLines.new!(["1", nil, "1.1", "1.2"]) |> NestedLines.can_indent?(2)
false

iex> NestedLines.new!(["1", nil, "1.1", "1.2"]) |> NestedLines.can_indent?(4)
true
Link to this function

can_outdent?(nested_lines, position)

@spec can_outdent?(t(), pos_integer()) :: boolean()

Returns true if the line can be outdented, false otherwise. Lines are 1-indexed.

Examples

iex> NestedLines.new!(["1", "1.1", "1.1.1"]) |> NestedLines.can_outdent?(2)
true

iex> NestedLines.new!(["1", "1.1", "2"]) |> NestedLines.can_outdent?(3)
false

iex> NestedLines.new!(["1", "2", "2.1", "3"]) |> NestedLines.can_outdent?(3)
true

iex> NestedLines.new!(["1", nil, "2", "2.1"]) |> NestedLines.can_outdent?(4)
true

iex> NestedLines.new!(["1", nil, "2", "2.1"]) |> NestedLines.can_outdent?(2)
false
Link to this function

has_children?(nested_lines, position)

@spec has_children?(t(), pos_integer()) :: boolean()

Returns a boolean indicating if the line at the given position has children

Examples:

iex> NestedLines.new!(["1", "1.1", "1.1.1"]) |> NestedLines.has_children?(1)
true

iex> NestedLines.new!(["1", "1.1", "1.1.1"]) |> NestedLines.has_children?(2)
true

iex> NestedLines.new!(["1", "1.1", "1.1.1"]) |> NestedLines.has_children?(3)
false

iex>  NestedLines.new!(["1", "2", "2.1"]) |> NestedLines.has_children?(1)
false

iex> NestedLines.new!(["1", "1.1", "1.2"]) |> NestedLines.has_children?(2)
false
Link to this function

indent!(nested_lines, position)

@spec indent!(t(), pos_integer()) :: t()

Indents a line based on its index, raises if the line cannot be indented. Child lines are also indented by one position. Lines are 1-indexed.

Examples

iex> NestedLines.new!(["1", "2", "2.1", "3"]) |> NestedLines.indent!(4) |> NestedLines.line_numbers()
["1", "2", "2.1", "2.2"]

iex> NestedLines.new!(["1", "2", "2.1", nil, "2.2"]) |> NestedLines.indent!(5) |> NestedLines.line_numbers()
["1", "2", "2.1", nil, "2.1.1"]

iex> NestedLines.new!(["1", "2", "3", nil, "3.1"]) |> NestedLines.indent!(3) |> NestedLines.line_numbers()
["1", "2", "2.1", nil, "2.1.1"]
Link to this function

line_numbers(nested_lines, starting_number \\ 1)

@spec line_numbers(t(), pos_integer()) :: [String.t()]

Output a string representation of the line numbers.

nil values in the input list are preserved in the output and do not affect the line numbering of subsequent lines.

Examples

iex> NestedLines.new!(["1", "1.1", "1.2", "2", "2.1", "2.1.1"]) |> NestedLines.line_numbers()
["1", "1.1", "1.2", "2", "2.1", "2.1.1"]

iex> NestedLines.new!(["1", "1.1", nil, "1.3", "2", "2.1"]) |> NestedLines.line_numbers()
["1", "1.1", nil, "1.2", "2", "2.1"]
Link to this function

new(line_input)

@spec new([String.t() | non_neg_integer()]) :: {:ok, t()} | {:error, atom()}

Construct a nested line representation from a list of string values. Returns {:ok, %NestedLines{}} if the input is valid, otherwise returns {:error, :invalid_inputs_empty} if the input list is empty, {:error, :invalid_initial_line_nesting} if the first line is indented, or {:error, :invalid_list} if the input is not a list.

Examples

iex> NestedLines.new(["1", "1.1", "1.2", "2", "2.1"])
{:ok, %NestedLines{lines: [[1], [0, 1], [0, 1], [1], [0, 1]]}}

iex> NestedLines.new(["1.1", "1.2", "2.0", "2.1"])
{:error, :invalid_initial_line_nesting}

iex> NestedLines.new([])
{:error, :invalid_inputs_empty}

iex> NestedLines.new("1.1")
{:error, :invalid_list}
Link to this function

new!(line_input)

@spec new!([String.t() | non_neg_integer()]) :: t()

Construct a nested line representation from a list of string values.

nil values in the input list do not have line numbers nor do they affect the line numbering of subsequent lines.

Examples

iex> NestedLines.new!(["1", "1.1", "1.2", "2", "2.1"])
%NestedLines{lines: [[1], [0, 1], [0, 1], [1], [0, 1]]}

iex> NestedLines.new!(["1", "1.1", nil, "1.2", "2"])
%NestedLines{lines: [[1], [0, 1], [], [0, 1], [1]]}
Link to this function

outdent!(nested_lines, position)

Outdents a line based on its index, raises if the line cannot be outdented. Child lines are also outdented by one position. Lines are 1-indexed.

Examples

iex> NestedLines.new!(["1", "2", "2.1", "2.1.1"]) |> NestedLines.outdent!(3) |> NestedLines.line_numbers()
["1", "2", "3", "3.1"]

iex> NestedLines.new!(["1", "2", "2.1", nil, "2.1.1"]) |> NestedLines.outdent!(3) |> NestedLines.line_numbers()
["1", "2", "3", nil, "3.1"]
Link to this function

tree(nested_lines)

@spec tree(t()) :: [map()]

Returns a tree representation of the input lines.

Examples

iex> NestedLines.new!(["1", "1.1", "2", "2.1", "2.1.1", "2.2", "2.2.1"]) |> NestedLines.tree()

[
  %{
    line: "1",
    children: [
      %{line: "1.1", children: []}
    ]
  },
  %{
    line: "2",
    children: [
      %{line: "2.1", children: [
          %{line: "2.1.1", children: []}
      ]},
      %{line: "2.2", children: [
          %{line: "2.2.1", children: []}
        ]
      }
    ]
  }
]