# `Expresso.Presenter.Program`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/presenter/program.ex#L1)

Makes the program of the presenter for one deck

`compile/2` takes a definition from `Expresso.Presenter.Definition` and a
deck. The result holds numbers where the definition holds symbols, so the
interpreter calculates almost nothing. For example, `ArrowDown` in the
overview becomes `{:select_by, 3}` for a deck of 7 slides, because such a deck
has 3 columns.

`compile/2` also puts the `each` commands of a mode in front of each binding,
and it makes a map from each event to its commands. A key with two bindings
in one mode raises an error, because the list of keys would show two
functions for it. `Expresso.Presenter.Verifier` refuses such a definition
when it compiles.

A mode with the option `element` gets its `each` commands in `element`, and
each other mode gets `nil`. The interpreter puts these commands in front of
the commands of an element under a click.

# `mode`

```elixir
@type mode() :: %{
  name: atom(),
  when: keyword(),
  any: [Expresso.Presenter.Definition.command()] | nil,
  keys: %{required(String.t()) =&gt; [Expresso.Presenter.Definition.command()]},
  click: %{required(atom()) =&gt; [Expresso.Presenter.Definition.command()]},
  swipe: %{required(atom()) =&gt; [Expresso.Presenter.Definition.command()]},
  element: [Expresso.Presenter.Definition.command()] | nil,
  other: [Expresso.Presenter.Definition.command()] | nil
}
```

The commands for each event in one mode

# `t`

```elixir
@type t() :: %Expresso.Presenter.Program{
  modes: [mode()],
  project: Expresso.Presenter.Projection.t(),
  reset: [Expresso.Presenter.Definition.field()],
  slides: tuple(),
  state: map(),
  steps: tuple(),
  sync: [Expresso.Presenter.Definition.field()]
}
```

The program of one deck

`steps` holds `{slide, step}` for each step. `slides` holds a map for each
slide: the index of its step 1, its number of steps and its transition. Both
are tuples, so the interpreter reads an entry by its index.

# `columns`

```elixir
@spec columns(non_neg_integer()) :: pos_integer()
```

Return the number of columns in the overview for a number of slides

The result is the square root of the slide count, rounded up to an integer.
The number of rows is then not more than the number of columns.

    iex> Expresso.Presenter.Program.columns(7)
    3

    iex> Expresso.Presenter.Program.columns(0)
    1

# `commands_value`

```elixir
@spec commands_value([Expresso.Presenter.Definition.command()]) :: [list()]
```

Return a list of commands as a value for JSON, such as `[["goto", 7]]`

`json_commands/1` encodes this value. A caller that puts the commands into a
larger value, such as `Expresso.Goto.json/1`, uses this function.

    iex> Expresso.Presenter.Program.commands_value([{:goto, 7}])
    [["goto", 7]]

# `compile`

```elixir
@spec compile(Expresso.Presenter.Definition.t(), Expresso.Deck.t()) :: t()
```

Make the program of a deck from a definition

The first value of the field `progress` comes from the deck: the deck option
`progress false` hides the progress bar at the start. A deck from the
imperative API with no such key in its metadata shows the bar.

# `element`

```elixir
@spec element(pos_integer()) :: [Expresso.Presenter.Definition.command()]
```

Return the commands that a page in the overview holds for a slide

A click on the page goes to step 1 of the slide, and it closes the overview.

# `json`

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

Return the program as JSON for the `script` element

The JSON object has five keys:

  * `"state"` - the first value of each field of the state.
  * `"sync"` - the fields that a message to the other window holds, after
    the slide and the step.
  * `"reset"` - the fields that take their first value again at each change
    of the step.
  * `"modes"` - the modes, in the order that the interpreter examines them.
    A mode holds its `"name"`, its condition `"when"`, its `"any"` commands
    or `null`, its `"other"` commands or `null`, and its `"element"` commands
    or `null`.
    `"keys"`, `"click"` and `"swipe"` hold pairs of events and commands. Each
    pair holds each event that has the same commands.
  * `"project"` - the projections, as `Expresso.Presenter.Projection.json/1`
    returns them.

A command is a JSON array, such as `["step", 1]`, as `json_commands/1`
shows. The steps and the slides are not in the program, because
`Expresso.Steps.json/1` writes them. `Expresso.Json.for_script/1` writes
the text, as for the list of the steps.

# `json_commands`

```elixir
@spec json_commands([Expresso.Presenter.Definition.command()]) :: String.t()
```

Return a list of commands as JSON, such as `[["step",1]]`

The first element of each array is the name of the command. A field, a view
and a built-in function become strings.

    iex> Expresso.Presenter.Program.json_commands([{:goto_slide, 2}, {:set, :overview, false}])
    ~s([["goto_slide",2],["set","overview",false]])

# `link`

```elixir
@spec link(non_neg_integer()) :: [Expresso.Presenter.Definition.command()]
```

Return the commands of a link to the step at an index, for `Expresso.Goto`

    iex> Expresso.Presenter.Program.link(7)
    [{:goto, 7}]

# `menu`

```elixir
@spec menu(non_neg_integer()) :: [Expresso.Presenter.Definition.command()]
```

Return the commands that a row of the menu holds for the step at an index

A click on the row goes to the step, and it closes the menu.

    iex> Expresso.Presenter.Program.menu(4)
    [{:goto, 4}, {:set, :menu, false}]

---

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