The schema Coelho ships with.
It covers what an application typically needs out of the box — paragraphs, headings, lists, quotes, code blocks, images, and as marks bold, italic, strike, underline, highlight, subscript, superscript, code and link — and is meant to be copied and adapted rather than extended in place.
What the link mark emits
An href and a title, and nothing else. In particular no target and
no rel: a document is not necessarily rendered into a page where
opening a new tab makes sense, and a target="_blank" without
rel="noopener" hands the opened page a handle on the opener. Rather than
guess, the shipped renderer emits neither.
An application that wants them says so per render, and must set both:
Coelho.to_html(document,
marks: %{
link: fn mark, inner ->
Coelho.Render.tag(
"a",
[
{"href", Coelho.Render.safe_url(Coelho.Render.attr(mark, "href"))},
{"target", "_blank"},
{"rel", "noopener noreferrer"}
],
inner
)
end
}
)The href still goes through Coelho.Render.safe_url/1 there, because a
stored document is not re-validated on the way out.
Alignment
paragraph, heading and list_item carry an align attribute, one of
left, center, right or justify, rendered as a text-align style
and read back from either a style or an align attribute on import. It
is absent from the document when unset, and re-checked against the closed
list at render time.
How it renders is part of the attribute's declaration — :render_as,
see Coelho.Schema.Attr — rather than a render function, so the browser
applies the same answer and an application can change it without writing
any JavaScript. An inline style is what ships because it needs no
stylesheet: the HTML works in an email, a feed, an export. It is also what
a page's own CSS cannot override, so an application that would rather own
alignment in its stylesheet asks for a class map instead — once, for the
three blocks that carry the attribute:
Coelho.Schema.Default.build(
align: {:class, %{"center" => "text-center", "right" => "text-right"}}
)The schema is built once and kept in :persistent_term, since it is
immutable and read on every render.
Summary
Functions
Builds the default schema without consulting the cache.
Returns the default schema, building it on first use.
Functions
@spec build(keyword()) :: Coelho.Schema.t()
Builds the default schema without consulting the cache.
Options
:align— how thealignattribute reaches the DOM, in the formCoelho.Schema.Attrtakes for:render_as. Defaults to{:style, "text-align"}.:tables— declarestable,table_row,table_cellandtable_header, withcolspanandrowspanon the two kinds of cell and blocks rather than text inside one.falseby default: everything a stored table needs is here, and it survives an import that would otherwise drop it, but the editor has no cell navigation and no row or column commands yet.
An inline style is unanswerable by a stylesheet, so an application that would rather own alignment in CSS says so once, here, rather than redeclaring the three blocks that carry the attribute:
Coelho.Schema.Default.build(
align: {:class, %{"center" => "text-center", "right" => "text-right"}}
)The result is not cached — schema/0 caches the default one. Build yours
once at compile time, as an application with any custom schema already
does.
@spec schema() :: Coelho.Schema.t()
Returns the default schema, building it on first use.