# `Statifier.Lowering.Attributes`
[🔗](https://github.com/riddler/statifier-ex/blob/v2.0.0/lib/statifier/lowering/attributes.ex#L1)

The four attribute operations every builder in `Statifier.Lowering.Builders`
needs: read a raw value, split a whitespace-separated value into a list,
map a value onto a known atom with a default, and record a value span into
`attribute_locations`.

The `attribute_locations` rule lives here in one place
(`lib/statifier/document.ex:22-44`): a key is added **only** when the
attribute was written in the source **and** its `value_location` is
non-nil. A written attribute whose `value_location` is `nil` (the
handler's short-scan tolerance, `lib/statifier/parser/handler.ex:162-175`)
still lowers its value - it is only the span that is absent.

# `atom`

```elixir
@spec atom(
  element :: Statifier.Parser.DOM.Element.t(),
  name :: binary(),
  mapping :: %{optional(String.t()) =&gt; atom()},
  default :: atom()
) :: atom()
```

`element`'s `name` attribute mapped through `mapping` onto a known atom,
or `default` when the attribute is absent or its value is not a key of
`mapping`.

An out-of-range value (`mapping` misses it) still lowers to `default`
rather than erroring - an enumerated value outside its range is the
validator's job to check, not lowering's.

# `list`

```elixir
@spec list(element :: Statifier.Parser.DOM.Element.t(), name :: binary()) :: [
  String.t()
]
```

`element`'s `name` attribute, whitespace-split into a list.

An absent attribute becomes `[]`, and so does one written as `""` - the
two are told apart, when it matters, by `attribute_locations`, never by
the list itself.

# `put_location`

```elixir
@spec put_location(
  locations :: Statifier.Document.attribute_locations(),
  key :: atom(),
  element :: Statifier.Parser.DOM.Element.t(),
  name :: binary()
) :: Statifier.Document.attribute_locations()
```

Adds `key => value_location` to `locations` when `element`'s `name`
attribute was written and carries a non-nil `value_location`; returns
`locations` unchanged otherwise.

# `value`

```elixir
@spec value(element :: Statifier.Parser.DOM.Element.t(), name :: binary()) ::
  String.t() | nil
```

The raw, entity-expanded value of `element`'s `name` attribute, or `nil`
when the attribute was not written.

---

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