# `Otera.Evaluator`
[🔗](https://github.com/georgeguimaraes/otera/blob/v0.1.0/lib/otera/evaluator.ex#L1)

Renders the syntax tree of `Otera.Parser` with the semantics of Python Jinja2.

The evaluator keeps a stack of scopes. The last scope holds the variables of the render and the top-level assignments. A `for` iteration, a macro call, a `with` block and the body of a `set`, `filter` or `generation` block run in a new scope, so their assignments do not leak out, as in Jinja2. A macro reads the top-level scope as it is at call time. Namespaces are the one way to change state across scopes.

`break` and `continue` stop the rest of a loop body. As in Jinja2, the `else` block of a loop runs when no iteration reached the end of the body.

# `call_filter`

```elixir
@spec call_filter(
  %Otera.Evaluator{
    filters: term(),
    frames: term(),
    globals: term(),
    tests: term()
  },
  String.t(),
  term(),
  list(),
  Otera.Dict.t()
) :: term()
```

Applies the filter `name`: a custom filter of `ctx`, or else a builtin filter. `Otera.Filters` calls it for `map`.

# `call_test`

```elixir
@spec call_test(
  %Otera.Evaluator{
    filters: term(),
    frames: term(),
    globals: term(),
    tests: term()
  },
  String.t(),
  term(),
  list(),
  Otera.Dict.t()
) :: boolean()
```

Applies the test `name`: a custom test of `ctx`, or else a builtin test. `Otera.Filters` calls it for `select`.

# `render`

```elixir
@spec render(list(), map(), keyword()) :: String.t()
```

Renders `ast` with `variables`, a map with string keys. Raises `Otera.Error`.

Options: `:filters`, `:tests` and `:globals`, maps from names to Elixir functions or values.

---

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