Structured rich text for Elixir.
Coelho stores a rich text document as a validated tree — the same shape ProseMirror produces — rather than as a blob of HTML. A schema, written once in Elixir, says which nodes and marks exist; validating a document against it is the sanitisation step, and rendering it is a pure function the application can override node by node.
This module is the convenience surface over the three that do the work:
Coelho.Schema— declaring the schema and exporting it to the browserCoelho.Document— validating, normalising, extracting plain textCoelho.Render— turning a validated document into HTML
Every function here defaults to Coelho.Schema.default/0; applications
with their own schema call the underlying modules directly.
iex> document = %{
...> "type" => "doc",
...> "content" => [
...> %{"type" => "paragraph", "content" => [%{"type" => "text", "text" => "hello"}]}
...> ]
...> }
iex> {:ok, document} = Coelho.validate(document)
iex> Coelho.to_html(document)
"<p>hello</p>"
Summary
Functions
A byte-for-byte stable serialisation of a validated document.
The empty document of a schema.
Converts existing HTML into a validated document, and says what it left behind.
The hex digest of a validated document, or nil when it holds nothing.
Moves a document from one schema version to the next.
Folds a document into any term at all, for a target that is not HTML.
Turns any term into a document the schema accepts, without failing.
The number of characters a writer typed, counted the way the editor counts.
Renders a validated document to HTML.
Extracts the plain text of a document, for full text search.
Validates and normalises a document against a schema.
Functions
A byte-for-byte stable serialisation of a validated document.
@spec empty(Coelho.Schema.t()) :: map()
The empty document of a schema.
The child is derived from the top node's content expression rather than
assumed to be a paragraph, so a schema that calls its block node something
else still gets a document its own validate/2 accepts.
@spec from_html(String.t(), Coelho.Schema.t()) :: {:ok, map(), [Coelho.HTML.warning()]} | {:error, term()}
Converts existing HTML into a validated document, and says what it left behind.
The migration path for content already stored as HTML. Requires the
optional :floki dependency; see Coelho.HTML.from_html/2 for what the
import does with markup the schema does not know, and for the shape of the
warnings.
The hex digest of a validated document, or nil when it holds nothing.
Moves a document from one schema version to the next.
A schema that declares a :version stamps it on every document it
validates, and refuses a document stamped with another — which is the
whole point: when a node is renamed or an attribute retired, there is
otherwise no way to tell a document written under the old vocabulary from
one that is simply wrong.
Coelho.migrate(document, from: 1, to: 2, with: &MyApp.RichText.v1_to_v2/1):with takes the document and returns the rewritten one. Crossing more
than one version at a time takes a map of the step to run into each
version:
Coelho.migrate(document, from: 1, to: 3, with: %{2 => &v1_to_v2/1, 3 => &v2_to_v3/1})The result is stamped with :to and is not validated: run it through
validate/2 with the new schema, which is where a migration that missed
something says so.
@spec reduce( map(), Coelho.Schema.t(), Coelho.Render.callbacks(), Coelho.Render.opts() ) :: term()
Folds a document into any term at all, for a target that is not HTML.
@spec sanitize(term(), Coelho.Schema.t()) :: map()
Turns any term into a document the schema accepts, without failing.
The counterpart of validate/2 for the way out: see
Coelho.Document.sanitize/2 for what it removes and why a stored document
needs it at all.
@spec text_length(term()) :: non_neg_integer()
The number of characters a writer typed, counted the way the editor counts.
Renders a validated document to HTML.
The schema may be left out, in which case the render options can be passed straight as the second argument.
@spec to_html(map(), Coelho.Schema.t() | Coelho.Render.opts()) :: String.t()
@spec to_html(map(), Coelho.Schema.t(), Coelho.Render.opts()) :: String.t()
@spec to_text(map(), Coelho.Schema.t()) :: String.t()
Extracts the plain text of a document, for full text search.
@spec validate(term(), Coelho.Schema.t()) :: {:ok, map()} | {:error, [Coelho.Document.Error.t()]}
Validates and normalises a document against a schema.