# `Html`

HTML that's always safe to put in a page or an email.

Use it for formatted content you send to a browser. Building one from text keeps only safe elements and removes the rest, so a script can't get in. For the writer's own text, store [`Markdown`](/docs/types/type-markdown.md) or [`RichText`](/docs/types/type-rich-text.md), and convert it when you show it.

## Shape

One value, held as text in one set form, with no parts: `<a href="https://example.com/" rel="noopener noreferrer nofollow">our site</a>`.

## Example

```jadpo
Html("<p>Fresh <strong>soup</strong> daily.</p>")
```

`Html(raw)` checks the text, and text that isn't one breaks the `format` rule.

`text.parse(raw, as: Html)` reads one from text that comes from outside. Text that isn't one at all fails `malformed`.

These operations give one: `markup.rich_to_html` and `markup.to_html`.

## Good to know

- Building one from text never fails. Unsafe parts are removed instead, and links keep only `https:` and `mailto:`.
- `markup.to_plain_text` gives the text without its tags.
- `==` tells you whether two are the same. `<` and `list.sort_by` don't take it.

## In JSON

A string, in a request, a response or `json.write`:

```json
"<p>Fresh <strong>soup</strong> daily.</p>"
"Tom &amp; Jerry"
"<ul><li>Leek</li><li>Tomato</li></ul>"
```

## Details

<details>
<summary>Text form, storage, how it is shown, and operations</summary>

`Html` is in the group Text formats, and has been in Jadpo since 0.1.0.

### Text form

`text.from` writes one standard text form, the same form `text.parse` reads back: `<p>Fresh <strong>soup</strong> daily.</p>`, `Tom &amp; Jerry` and `<ul><li>Leek</li><li>Tomato</li></ul>`.

### How it is stored

It is stored in one column named for the field, of type `text`. `<ul><li>Leek</li><li>Tomato</li></ul>` is stored as `'<ul><li>Leek</li><li>Tomato</li></ul>'`.

### How it is shown to people

`text.format(value, locale:)` shows it to people in their locale.

With `locale: Locale.en_gb`:

| Value | Shown |
|---|---|
| `<p>Fresh <strong>soup</strong> daily.</p>` | `Fresh soup daily.` |
| `Tom &amp; Jerry` | `Tom & Jerry` |
| `<ul><li>Leek</li><li>Tomato</li></ul>` | `"Leek\nTomato"` |
| `<a href="https://example.com/" rel="noopener noreferrer nofollow">our site</a>` | `our site` |

### Operations

- `markup.rich_to_html(rich: RichText) -> Html`: `rich` written as HTML, each block its element and each mark its element inside its link, then made safe as every `Html` is, which changes nothing: a `RichText` holds only what the sanitiser keeps.
- `markup.to_html(markdown: Markdown) -> Html`: `markdown` rendered as CommonMark (0.31.2), then made safe as every `Html` is: raw HTML inside it is kept only where the sanitiser keeps it, and an image is shown as its description, since `Html` keeps no images.
- `markup.to_plain_text(html: Html) -> Text`: The text people read in `html`: each block (a paragraph, a heading, a list item, a quote, a code block) on its own line, `<br>` a line break, white space run together as a browser shows it, kept as written in a code block.

It also takes `text.parse`, `text.from`, `text.format`, `json.read`, `json.write` and `==`. [How every standard type behaves](/docs/every-standard-type-meets-one-contract.md) says how they work.

</details>
