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

Makes the list of each step of a deck for the presenter

The renderer writes the list into the document as JSON, in the element
`script#expresso-deck`. The presenter script reads it at load. The script
holds the index of the current step in the list, and it reads each other
value from the list. It calculates nothing from the deck.

The JSON object has three keys:

  * `"steps"` - one entry for each step of each slide, in sequence. An entry
    is `[slide, step, fraction, done, position]`. `entries/1` tells what each
    value is.
  * `"slides"` - one object for each slide, in sequence. `slides/1` tells
    what each key is.
  * `"duration_ms"` - the length of the talk in milliseconds, or `null`.
    `duration/1` gives it.

`docs/research/elixir-presenter-report.md` gives the reason for the list.

# `entry`

```elixir
@type entry() :: %{
  slide: pos_integer(),
  step: pos_integer(),
  fraction: float(),
  done: float(),
  position: String.t()
}
```

One step of a deck

# `slide`

```elixir
@type slide() :: %{
  first: non_neg_integer(),
  steps: pos_integer(),
  transition: String.t()
}
```

One slide of a deck

# `duration`

```elixir
@spec duration(Expresso.Deck.t()) :: pos_integer() | nil
```

Return the length of the talk in milliseconds, or nil

The `duration` option of the deck gives the length in minutes. A value that
is not a positive integer gives nil. The address parameter `?duration=`
replaces the length in the browser.

# `entries`

```elixir
@spec entries(Expresso.Deck.t()) :: [entry()]
```

Return one entry for each step of each slide, in sequence

The first slide is slide 1, and the first step is step 1. An entry holds:

  * `fraction` - the part of the deck before the step, from 0 at the first
    step to 1 at the last step. The progress bar shows it. A deck with one
    step gets 0.
  * `done` - the part of the steps before the step. The last step also has
    its part, so the value is less than 1. The speaker view compares it with
    the time of the talk.
  * `position` - the text of the speaker view, such as
    `"Slide 4 of 13, step 2 of 3"`. A slide with one step gets no step part.
    A step with a label gets the label after a colon, such as
    `"Slide 4 of 13, step 2 of 3: The restart"`.

The presenter adds ", black screen" or ", white screen" to the position
while the screen is black or white.

# `json`

```elixir
@spec json(Expresso.Deck.t()) :: String.t()
```

Return the list of the steps as JSON for the `script` element

`Expresso.Json.for_script/1` writes the text, so it has no `<`, and a value
cannot close the `script` element.

The keys of each object are in alphabetical order, so each render of a deck
gives the same text.

# `kind`

```elixir
@spec kind(atom()) :: String.t()
```

Give the kind of a transition, as the presenter and the style sheet write it

The kind is the name of the atom with a hyphen for each underscore, as for
an effect. The style sheet then gives the rule for
`html[data-transition="wipe-down"]`.

    iex> Expresso.Steps.kind(:wipe_down)
    "wipe-down"

# `slides`

```elixir
@spec slides(Expresso.Deck.t()) :: [slide()]
```

Return one map for each slide, in sequence

A map holds:

  * `first` - the index of step 1 of the slide in the list of `entries/1`.
  * `steps` - the number of steps of the slide.
  * `transition` - the kind of the transition into the slide, such as
    `"fade"` or `"wipe-down"`. The option of the slide comes first, then the
    option of the deck, then `"fade"`. `kind/1` gives the name.

---

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