# `Expresso.Overlay`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/overlay.ex#L1)

An overlay specification, which tells the compiler which steps show an element

A specification is an Elixir term. `new/1` accepts each form and puts it
into this struct. The struct holds one pair for each item of the term: the
first step and the last step. In a pair, `:next` stands for the counter of the
slide, and `:max` stands for the maximum step number of the slide. The
transformer resolves both with `resolve_next/2` and `steps/2`.

`docs/overlays.md` gives the forms and the rules.

# `first`

```elixir
@type first() :: pos_integer() | :next
```

The first step of a pair

# `last`

```elixir
@type last() :: pos_integer() | :next | :max
```

The last step of a pair

# `pair`

```elixir
@type pair() :: {first(), last()}
```

One item of a specification

# `t`

```elixir
@type t() :: %Expresso.Overlay{pairs: [pair()]}
```

The struct of a specification

# `fields`

```elixir
@spec fields() :: [atom() | {:on, []}]
```

Return the overlay fields of an element struct

Each element with the `at` option adds these fields to its own fields, as
in `defstruct [:src] ++ Expresso.Overlay.fields()`. The fields are these:

- `at`, `effect`, `speed`, `easing` and `morph` hold the overlay options of
  the DSL.
- `steps` holds the step numbers that the transformer resolves from `at`.
- `el` holds the identity that `Expresso.Overlay.Render.identify/1` writes.
- `signature` holds the signature that `Expresso.Morph.sign/1` writes.
- `on` holds the `on` entities. Its default is an empty list.

The overlay code reads each field by name. A new overlay option needs its
field in this list and its schema in `Expresso.Extension`.
`test/expresso/overlay_fields_test.exs` makes sure that each entity and each
struct agree on the options and on the fields.

# `first_step`

```elixir
@spec first_step(t()) :: pos_integer() | nil
```

Give the first step of a specification

The function gives the smallest first step of the pairs. It ignores a pair
that starts with `:next`, and it gives `nil` when each pair does. The
`reveal` option of an element reads this step from an absolute
specification. See `Expresso.Overlay.Expand`.

# `from_next`

```elixir
@spec from_next() :: t()
```

Give the specification `[from: :next]`

This specification shows an element from the current value of the counter to
the maximum step number of the slide. The `auto_reveal` option of a slide
gives it to each element of the slide that has no `at` option.

# `max_step`

```elixir
@spec max_step(t()) :: pos_integer() | nil
```

Give the largest explicit step number of a specification

The function ignores `:max`, and it gives `nil` for a specification with no
explicit step. Call `resolve_next/2` first, because a `:next` is not an
explicit step.

# `new`

```elixir
@spec new(term()) :: {:ok, t()} | {:error, String.t()}
```

Make a specification from a term

This function is the custom type of the `at` option and of the `on` entity.
It accepts a struct, a positive integer, a range with a step of 1, `:next`,
or a list of those and of `from:` items. A different term gives an error
tuple with a message that lists the forms.

# `relative?`

```elixir
@spec relative?(t()) :: boolean()
```

Tell whether a specification reads the counter

A specification with a `:next` is relative, and `resolve_next/2` gives it a
step from the counter. A specification without a `:next` is absolute, and it
does not move the counter.

# `resolve_next`

```elixir
@spec resolve_next(t(), pos_integer()) :: {t(), pos_integer()}
```

Replace each `:next` with the value of the counter

Each `:next` in one specification takes the same value. The function
increments the counter one time when the specification holds a `:next`, and
it returns the counter unchanged otherwise. This is the rule of `+` in Beamer.

# `steps`

```elixir
@spec steps(t(), pos_integer()) :: {:ok, [pos_integer()]} | {:error, String.t()}
```

Give the step numbers of a specification, with `max` as the maximum step

The function replaces each `:max` with `max`, and it gives the steps in order
with no repeat. It gives an error when a step is more than `max`, or when a
specification holds a `:next`. Call `resolve_next/2` first.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
