Schema definitions for Quillon documents.
A schema defines the valid structure of a document:
- Which node types are allowed
- What children each node type can contain (content expressions)
- Which marks can be applied to each node type
- Required and optional attributes for nodes and marks
- Mark behavior (inclusive, keep_on_split, excludes)
Example
schema = Quillon.Schema.default()
# Validate a document against the schema
{:ok, doc} = Quillon.Schema.Validator.validate(doc, schema)Custom Schemas
custom = %Quillon.Schema{
groups: %{
block: [:paragraph, :heading, :code_block],
inline: [:text]
},
nodes: %{
document: %{content: "block+"},
paragraph: %{content: "inline*", group: :block, marks: :all},
heading: %{content: "inline*", group: :block, marks: [:bold, :italic]},
code_block: %{content: nil, group: :block, marks: nil}
},
marks: %{
bold: %{},
italic: %{}
}
}
Summary
Types
Specification for an attribute
Specification for a mark type
Specification for a node type
A schema definition
Functions
Get allowed marks for a node type.
Returns the default schema for Quillon documents.
Get the types in a group.
Get the mark specification for a given type.
Get the node specification for a given type.
Check if a mark is allowed on a node type.
Check if a mark type exists in the schema.
Check if two marks conflict (via excludes).
Merge two schemas, with the second schema taking precedence.
Check if a node type exists in the schema.
Types
Specification for an attribute
@type mark_spec() :: %{ optional(:inclusive) => boolean(), optional(:keep_on_split) => boolean(), optional(:excludes) => [atom()] | nil, optional(:attrs) => %{required(atom()) => attr_spec()} }
Specification for a mark type
@type node_spec() :: %{ optional(:content) => String.t() | nil, optional(:group) => atom() | nil, optional(:marks) => [atom()] | :all | nil, optional(:attrs) => %{required(atom()) => attr_spec()} }
Specification for a node type
@type t() :: %Quillon.Schema{ groups: %{required(atom()) => [atom()]}, marks: %{required(atom()) => mark_spec()}, nodes: %{required(atom()) => node_spec()} }
A schema definition
Functions
Get allowed marks for a node type.
Returns :all if all marks are allowed, a list of allowed mark types,
or nil if no marks are allowed.
Examples
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.allowed_marks(schema, :paragraph)
:all
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.allowed_marks(schema, :divider)
nil
@spec default() :: t()
Returns the default schema for Quillon documents.
The default schema includes:
- Node types: document, paragraph, heading, divider, blockquote, callout, code_block, image, video, text
- Marks: bold, italic, underline, strike, code, link
- Groups: block, inline
Examples
iex> schema = Quillon.Schema.default()
iex> :blockquote in Map.keys(schema.nodes)
true
Get the types in a group.
Examples
iex> schema = Quillon.Schema.default()
iex> :paragraph in Quillon.Schema.get_group(schema, :block)
true
Get the mark specification for a given type.
Examples
iex> schema = Quillon.Schema.default()
iex> spec = Quillon.Schema.get_mark_spec(schema, :bold)
iex> spec.inclusive
true
Get the node specification for a given type.
Examples
iex> schema = Quillon.Schema.default()
iex> spec = Quillon.Schema.get_node_spec(schema, :paragraph)
iex> spec.content
"inline*"
Check if a mark is allowed on a node type.
Examples
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.mark_allowed?(schema, :paragraph, :bold)
true
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.mark_allowed?(schema, :divider, :bold)
false
Check if a mark type exists in the schema.
Examples
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.mark_type?(schema, :bold)
true
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.mark_type?(schema, :unknown)
false
Check if two marks conflict (via excludes).
Examples
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.marks_conflict?(schema, :code, :link)
true
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.marks_conflict?(schema, :bold, :italic)
false
Merge two schemas, with the second schema taking precedence.
Examples
iex> base = Quillon.Schema.default()
iex> custom = %Quillon.Schema{marks: %{highlight: %{}}}
iex> merged = Quillon.Schema.merge(base, custom)
iex> Map.has_key?(merged.marks, :highlight)
true
Check if a node type exists in the schema.
Examples
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.node_type?(schema, :paragraph)
true
iex> schema = Quillon.Schema.default()
iex> Quillon.Schema.node_type?(schema, :unknown)
false