Quillon.Schema (Quillon v0.1.0)

Copy Markdown View Source

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

t()

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

attr_spec()

@type attr_spec() :: %{optional(:required) => boolean(), optional(:default) => any()}

Specification for an attribute

mark_spec()

@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

node_spec()

@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

t()

@type t() :: %Quillon.Schema{
  groups: %{required(atom()) => [atom()]},
  marks: %{required(atom()) => mark_spec()},
  nodes: %{required(atom()) => node_spec()}
}

A schema definition

Functions

allowed_marks(schema, node_type)

@spec allowed_marks(t(), atom()) :: :all | [atom()] | nil

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

default()

@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_group(schema, name)

@spec get_group(t(), atom()) :: [atom()]

Get the types in a group.

Examples

iex> schema = Quillon.Schema.default()
iex> :paragraph in Quillon.Schema.get_group(schema, :block)
true

get_mark_spec(schema, type)

@spec get_mark_spec(t(), atom()) :: mark_spec() | nil

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_node_spec(schema, type)

@spec get_node_spec(t(), atom()) :: node_spec() | nil

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*"

mark_allowed?(schema, node_type, mark_type)

@spec mark_allowed?(t(), atom(), atom()) :: boolean()

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

mark_type?(schema, type)

@spec mark_type?(t(), atom()) :: boolean()

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

marks_conflict?(schema, mark1, mark2)

@spec marks_conflict?(t(), atom(), atom()) :: boolean()

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(base, override)

@spec merge(t(), t()) :: t()

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

node_type?(schema, type)

@spec node_type?(t(), atom()) :: boolean()

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