# `Mailglass.Renderer`
[🔗](https://github.com/szTheory/mailglass/blob/v0.1.0/lib/mailglass/renderer.ex#L1)

Pure-function render pipeline: HEEx → plaintext → CSS inlining → data-mg-* strip.

All functions are side-effect free. No processes, no DB, no HTTP calls.

## Pipeline (D-15 — plaintext runs BEFORE CSS inlining)

1. `render_html/2` — calls `Mailglass.TemplateEngine.HEEx.render/3`, returns HTML iodata
2. `to_plaintext/1` — custom Floki walker on the pre-VML logical HTML
3. `inline_css/1` — `Premailex.to_inline_css/2` (preserves MSO conditionals per D-14)
4. `strip_mg_attributes/1` — removes all `data-mg-*` from the final HTML wire

Plaintext MUST run on step-1 output (pre-CSS-inlining HTML), NOT on step-3 output.
Premailex adds VML wrappers; the plaintext walker must not see them.

## Performance Target

< 50ms end-to-end for a typical template (AUTHOR-03).

## Boundary

`Mailglass.Renderer` cannot depend on `Mailglass.Outbound`, `Mailglass.Repo`,
or any process. This is enforced by the `:boundary` compiler (CORE-07).

# `render`
*since 0.1.0* 

```elixir
@spec render(
  Mailglass.Message.t(),
  keyword()
) :: {:ok, Mailglass.Message.t()} | {:error, Mailglass.TemplateError.t()}
```

Renders a `Mailglass.Message` through the full pipeline.

Takes a Message whose `swoosh_email.html_body` is either a HEEx function
component (`fn assigns -> ~H"..." end`) or a pre-rendered HTML string. Runs
the configured pipeline and returns a Message with `swoosh_email.html_body`
replaced by the final inlined HTML and `swoosh_email.text_body` populated
with the auto-generated plaintext.

The entire pipeline is wrapped in `Mailglass.Telemetry.render_span/2`.
Metadata is whitelisted to `%{tenant_id, mailable}` — no PII per D-31.

## Examples

    component = fn _assigns -> ~H|<p>Hello</p>| end
    email = %Swoosh.Email{html_body: component}
    message = Mailglass.Message.new(email, mailable: MyMailer)
    {:ok, rendered} = Mailglass.Renderer.render(message)

# `to_plaintext`
*since 0.1.0* 

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

Extracts plaintext from HTML using `data-mg-plaintext` strategy attributes.

Strategies (D-22):
  * `"skip"` — excludes the element and its children (preheader)
  * `"link_pair"` — emits `"Label (url)"` (button, link)
  * `"divider"` — emits `"\n---\n"` (hr)
  * `"heading_block_1"` — uppercase + blank lines (h1)
  * `"heading_block_2"` / `"_3"` / `"_4"` — title case + blank lines
  * `"text"` — raw text content; for `<img>`, uses the alt attribute
  * anything else (including missing) — recurses into children

Runs on the pre-VML logical HTML tree so VML artifacts never leak into
plaintext output.

---

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