# `EEx.Engine`
[🔗](https://github.com/elixir-lang/elixir/blob/7ff272706afc522e74121493b7166719985cb099/lib/eex/lib/eex/engine.ex#L5)

Basic EEx engine that ships with Elixir.

An engine needs to implement all callbacks below.

This module also ships with a default engine implementation
you can delegate to. See `EEx.SmartEngine` as an example.

# `state`

```elixir
@type state() :: term()
```

# `handle_begin`

```elixir
@callback handle_begin(state()) :: state()
```

Invoked at the beginning of every nesting.

It must return a new state that is used only inside the nesting.
Once the nesting terminates, the current `state` is resumed.

# `handle_body`

```elixir
@callback handle_body(state()) :: Macro.t()
```

Called at the end of every template.

It must return Elixir's quoted expressions for the template.

# `handle_end`

```elixir
@callback handle_end(state()) :: Macro.t()
```

Invokes at the end of a nesting.

It must return Elixir's quoted expressions for the nesting.

# `handle_expr`

```elixir
@callback handle_expr(state(), marker :: String.t(), expr :: Macro.t()) :: state()
```

Called for the dynamic/code parts of a template.

The marker is what follows exactly after `<%`. For example,
`<% foo %>` has an empty marker, but `<%= foo %>` has `"="`
as marker. The allowed markers so far are:

  * `""`
  * `"="`
  * `"/"`
  * `"|"`

Markers `"/"` and `"|"` are only for use in custom EEx engines
and are not implemented by default. Using them without an
appropriate implementation raises `EEx.SyntaxError`.

It must return the updated state.

# `handle_text`

```elixir
@callback handle_text(
  state(),
  [line: pos_integer(), column: pos_integer()],
  text :: String.t()
) :: state()
```

Called for the text/static parts of a template.

It must return the updated state.

# `init`

```elixir
@callback init(opts :: keyword()) :: state()
```

Called at the beginning of every template.

It receives the options during compilation, including the
ones managed by EEx, such as `:line` and `:file`, as well
as custom engine options.

It must return the initial state.

# `handle_assign`

```elixir
@spec handle_assign(Macro.t()) :: Macro.t()
```

Handles assigns in quoted expressions.

A warning will be printed on missing assigns.
Future versions will raise.

This can be added to any custom engine by invoking
`handle_assign/1` with `Macro.prewalk/2`:

    def handle_expr(state, token, expr) do
      expr = Macro.prewalk(expr, &EEx.Engine.handle_assign/1)
      super(state, token, expr)
    end

# `handle_begin`

Default implementation for `c:handle_begin/1`.

# `handle_body`

Default implementation for `c:handle_body/1`.

# `handle_end`

Default implementation for `c:handle_end/1`.

# `handle_expr`

Default implementation for `c:handle_expr/3`.

# `handle_text`

Default implementation for `c:handle_text/3`.

# `init`

Default implementation for `c:init/1`.

---

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