# `MishkaCmsCore.Runtime.PageBuilder.Markup`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/page_builder/markup.ex#L5)

Every Elixir expression a HEEx template contains, found by tokenising it.

## Why it exists

Because the questions worth asking about a template — does it read this assign, does it call that
helper — are questions about its EXPRESSIONS, and a pattern over the source cannot tell an
expression from the text around it. `@flash` in a comment, in a string, in a `<pre>` showing
somebody a code sample: a pattern finds all three, and a tokeniser finds none of them.

What comes back is source, one string per expression, for `Code.string_to_quoted/1` to turn into
something walkable — see `MishkaCmsCore.Runtime.PageBuilder.CodeReads`.

    iex> MishkaCmsCore.Runtime.PageBuilder.Markup.expressions(~S|<div id={@id}>{@flash}</div>|)
    ["@id", "@flash"]

## Tokens, not the tree

`EEx.tokenize/1` and `Phoenix.LiveView.TagEngine.Tokenizer` directly, rather than the tree
`MishkaCmsCore.Runtime.PageBuilder.LiveView.HtmlTokenizer` builds on top of them. Nesting is a
question this module does not ask, and asking it fails on templates this one can answer for: a
fragment like `<div class={paint(@tone)}>` has no closing tag, so the tree is an error — while the
attribute was tokenised perfectly well on the way to finding that out.

## What it does with a template it cannot read

Answers `[]`, which every caller has to read as "nothing found" rather than "nothing there".
`component_arguments/1` is the exception: its caller decides what a component can reach from the
answer, so an unreadable template there is `:dynamic` rather than an empty list.

# `component_arguments`

```elixir
@spec component_arguments(String.t() | nil) :: {:ok, [String.t()]} | :dynamic
```

Every expression a template HANDS TO a `<.component …/>` tag — the values a runtime component can
be given, as source.

A literal attribute is not among them. `component_name="card"` is a string written in the
template, so it can carry nothing the template does not already say itself.

`:dynamic` when what a tag hands over cannot be read off the template at all: a tag that spreads a
map built while the page renders, or a template that cannot be tokenised. A caller must read that
as "anything could have been handed over", never as "nothing was" — which is the opposite of what
`expressions/1` promises for the same unreadable template, and the reason the two answers have
different shapes.

    iex> MishkaCmsCore.Runtime.PageBuilder.Markup.component_arguments(~S|<.component component_name="card" bag={assigns} />|)
    {:ok, ["assigns"]}

    iex> MishkaCmsCore.Runtime.PageBuilder.Markup.component_arguments(~S|<.component {@attrs} />|)
    :dynamic

# `expressions`

```elixir
@spec expressions(String.t() | nil) :: [String.t()]
```

Every Elixir expression in a template: attribute values, interpolations and EEx tags.

---

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