Expresso.Element.Tree (expresso v0.1.0)

Copy Markdown View Source

The walks over a tree of elements

A container, such as a text box, a column or a list, holds its children under the key :elements. Each function of this module reads the children of an element with children/1, so each walk reads them in the same way. An element without the key, such as a pause, has no children, and nil is an empty list.

Each function visits the elements in document order: an element comes before its children, and its children come before the next element. A function that changes the elements calls the function of the caller on an element first, and then it walks the children of the result.

The overlay expansion, the overlay check, Expresso.Overlay.Render.identify/1 and Expresso.Placement keep their own walks, because they carry the context of the parent or they have their own rules. The first three read the children with children/1 too. Expresso.Placement also reads the key :timeline of a chart.

Summary

Types

An element struct, or a different map with the key :elements

Functions

Return the children of an element

Return each element of a list and each element under it, in document order

Change each element of a list and each element under it

Change each element of each slide of a deck, as map/2 does

Change each element of a list and each element under it, and stop at the first error

Change each element of a list and each element under it, with a value that goes from one element to the next

Change each element of each slide of a deck, with a value that goes from one element to the next, as map_reduce/3 does

Types

element()

@type element() :: map()

An element struct, or a different map with the key :elements

Functions

children(element)

@spec children(element()) :: [element()]

Return the children of an element

The function returns [] for an element without the key :elements, and for the value nil.

iex> Expresso.Element.Tree.children(%{elements: [%{text: "a"}]})
[%{text: "a"}]
iex> Expresso.Element.Tree.children(%{elements: nil})
[]
iex> Expresso.Element.Tree.children(%{text: "a"})
[]

descendants(elements)

@spec descendants([element()] | nil) :: [element()]

Return each element of a list and each element under it, in document order

iex> tree = [%{name: "a", elements: [%{name: "b"}]}, %{name: "c"}]
iex> tree |> Expresso.Element.Tree.descendants() |> Enum.map(& &1.name)
["a", "b", "c"]

map(elements, fun)

@spec map([element()] | nil, (element() -> element())) :: [element()]

Change each element of a list and each element under it

The function calls fun on an element, and then it changes the children of the result. An element without the key :elements stays without it.

map_deck(deck, fun)

@spec map_deck(deck, (element() -> element())) :: deck when deck: map()

Change each element of each slide of a deck, as map/2 does

The function takes a deck or a different map with the key :slides.

map_ok(elements, fun)

@spec map_ok([element()] | nil, (element() -> {:ok, element()} | {:error, reason})) ::
  {:ok, [element()]} | {:error, reason}
when reason: term()

Change each element of a list and each element under it, and stop at the first error

fun returns {:ok, element} or {:error, reason}. The function returns {:ok, elements}, or the first error in document order.

map_reduce(elements, acc, fun)

@spec map_reduce([element()] | nil, acc, (element(), acc -> {element(), acc})) ::
  {[element()], acc}
when acc: term()

Change each element of a list and each element under it, with a value that goes from one element to the next

fun takes an element and the value, and it returns the changed element and the next value, as for Enum.map_reduce/3.

map_reduce_deck(deck, acc, fun)

@spec map_reduce_deck(deck, acc, (element(), acc -> {element(), acc})) :: {deck, acc}
when deck: map(), acc: term()

Change each element of each slide of a deck, with a value that goes from one element to the next, as map_reduce/3 does

The value goes from the last element of a slide to the first element of the next slide.