---
url: /reference/formatters.md
---
# Formatters

## TypographyFormatter

`Trek::TypographyFormatter` applies French typography rules to strings **and** ProseMirror documents (only `text` nodes are modified):

* non-breaking spaces before `»`, after `«`, `n°`, and on both sides of dashes (`–`, `—`)
* before `: % € $`, a non-breaking space, and before `; ! ?` a narrow one (U+202F): only when the sign ends a word (followed by a space, punctuation or the end of the text), so a time (`10:30`) or a URL is left alone
* non-breaking spaces before units (km, kg, h, min, °C…) and between digit groups
* `...` → `…`, ASCII apostrophes → typographic `'`
* removes double spaces and spaces before periods/commas

Wire it to attributes with [Formattable](/reference/concerns/formattable):

```ruby
include Trek::Formattable
format_attributes Trek::TypographyFormatter, :title
```

## Rich text rendering

`formatted_content` (from [Contentable](/reference/concerns/contentable)) renders the content editor's ProseMirror JSON to HTML with the [`prosemirror`](https://github.com/etaminstudio/prosemirror) gem, through `Trek::Content.schema`: HTML is escaped as it is built, attributes are typed, links and images only allow safe URLs, and links to pages are resolved. See [Rendering on the site](/content-editor#rendering-on-the-site) for what the HTML contains, and how invalid content is reported.

### Custom blocks

Trek's node types (`Trek::Content::ImageBlock`, `PromptsBlock`…) can be subclassed to render the app's own components, and registered with `Trek::Content.schema = Trek::Content.default_schema.with(…)`: see [Customizing the rendering](/content-editor#customizing-the-rendering).
