Quick reference for Quillon's nodes, marks, and functions.
Node Types
Generic Constructor
Build a node of any type, including a custom type:
new(type, attrs) # => {:line, %{page: 2}, []}
new(type, attrs, children) # children list, or a string for text content
Container
| Type | Factory | Attrs |
|---|
:document | document(), document(children), document(attrs, children) | - |
Blocks
| Type | Factory | Attrs |
|---|
:paragraph | paragraph(), paragraph(content), paragraph(content, opts) | align, spacing, indent, font_size, line_height, color, background, border |
:heading | heading(level), heading(level, content), heading(level, content, opts) | level (required), align, spacing, indent, font_weight, color, background, border |
:divider | divider(), divider(style), divider(style, opts) | style (:solid, :dashed, :dotted), spacing, color, opacity |
:blockquote | blockquote(), blockquote(children), blockquote(children, citation_or_opts), blockquote(children, citation, opts) | citation, spacing, indent, color, background, border, border_color |
:callout | callout(type), callout(type, children), callout(type, children, title_or_opts), callout(type, children, title, opts) | type (required), title, spacing, background, border, rounded |
:code_block | code_block(code), code_block(code, language), code_block(code, language, opts) | code (required), language, width, spacing, font_size, background, border, rounded |
:image | image(src), image(src, alt), image(src, alt, opts) | src (required), alt, caption, width, align, spacing, background, border, rounded, shadow, opacity |
:video | video(src), video(src, opts) | src (required), poster, align, width, spacing, background, border, rounded, shadow |
:bullet_list | bullet_list(), bullet_list(items), bullet_list(items, opts) | spacing, indent |
:ordered_list | ordered_list(), ordered_list(items), ordered_list(items, start_or_opts), ordered_list(items, start, opts) | start (default: 1), spacing, indent |
:table | table(), table(rows), table(rows, opts) | width, spacing, border, rounded, shadow |
:row | row(), row(children), row(children, opts) | justify, items, wrap, gap |
:grid | grid(), grid(children), grid(children, opts) | columns, gap |
List Content
| Type | Factory | Attrs |
|---|
:list_item | list_item(), list_item(children) | - |
Table Content
| Type | Factory | Attrs |
|---|
:table_row | table_row(), table_row(cells), table_row(cells, opts) | header (default: false) |
:table_cell | table_cell(), table_cell(children), table_cell(children, opts) | colspan, rowspan (default: 1), align, valign, background, border |
Inline
| Type | Factory | Attrs |
|---|
:text | text(content), text(content, marks) | text (required), marks (default: []) |
Marks
Simple Marks (atoms)
| Mark | Description |
|---|
:bold | Bold text |
:italic | Italic text |
:underline | Underlined text |
:strike | Strikethrough text |
:code | Inline code |
:subscript | Subscript (H₂O) |
:superscript | Superscript (x²) |
Attributed Marks (tuples)
| Mark | Attrs | Example |
|---|
:link | href (required), title, target | {:link, %{href: "https://example.com"}} |
:highlight | color (required) | {:highlight, %{color: "yellow"}} |
:font_color | color (required) | {:font_color, %{color: "#ff0000"}} |
:mention | id, type, label (all required) | {:mention, %{id: "123", type: "user", label: "@alice"}} |
Mark Exclusions
:subscript and :superscript exclude each other:code excludes :link
block here means a :paragraph or :heading — the block types whose children are inline text. Passing any other node raises FunctionClauseError.
Simple Mark Toggles
toggle_bold(block, start, end)
toggle_italic(block, start, end)
toggle_underline(block, start, end)
toggle_strike(block, start, end)
toggle_code(block, start, end)
toggle_subscript(block, start, end)
toggle_superscript(block, start, end)
Attributed Mark Commands
set_link(block, start, end, href_or_attrs)
unset_link(block, start, end)
set_highlight(block, start, end, color)
unset_highlight(block, start, end)
set_font_color(block, start, end, color)
unset_font_color(block, start, end)
set_mention(block, start, end, attrs)
unset_mention(block, start, end)
Utility Commands
clear_formatting(block, start, end) # clears the default schema's marks
clear_formatting(block, start, end, schema) # also clears your own mark types
selection_has_mark?(block, start, end, mark_type)
The primitives the formatting commands are built from. block means a :paragraph or :heading, as above; normalize/1 has the same restriction.
apply_mark(block, start, end, mark)
remove_mark(block, start, end, mark_type)
toggle_mark(block, start, end, mark)
range_has_mark?(block, start, end, mark_type)
normalize(block) # merge adjacent text, drop empty
split_at_offset(children, offset) # => [node, node]
split_range(children, start, end)
offset_to_position(children, offset) # => {index, offset_in_node}
position_to_offset(children, position) # => offset
sort_marks(marks) # => [:bold, :italic]
Path Operations
Path-based
get(node, path) # {:ok, node} | {:error, :invalid_path}
update(node, path, fun) # {:ok, node} | {:error, :invalid_path}
insert(node, path, new_node) # {:ok, node} | {:error, :invalid_path}
delete(node, path) # {:ok, node} | {:error, :invalid_path}
move(node, from_path, to_path) # {:ok, node} | {:error, :invalid_path}
reorder(node, path, id_list) # {:ok, node} | {:error, :invalid_path}
ID-based
find_path(node, id) # {:ok, path} | {:error, :not_found}
get_by_id(node, id) # {:ok, node} | {:error, :not_found}
update_by_id(node, id, fun) # {:ok, node} | {:error, :not_found}
Node Inspection
Accessors
type(node) # => :paragraph
attrs(node) # => %{level: 1}
children(node) # => [...]
Predicates
node?(value) # Is it a valid node tuple?
block?(node) # Is it a block type? (default schema)
block?(node, schema) # ...according to your schema
inline?(node) # Is it an inline type?
inline?(node, schema)
container?(node) # Is it a container type?
container?(node, schema)
# Specific type checks
document?(node)
paragraph?(node)
heading?(node)
divider?(node)
blockquote?(node)
callout?(node)
code_block?(node)
image?(node)
video?(node)
bullet_list?(node)
ordered_list?(node)
list?(node) # bullet_list or ordered_list
list_item?(node)
table?(node)
table_row?(node)
table_cell?(node)
text?(node)
row?(node)
grid?(node)
Mark Utilities
mark?(value) # Is it a valid mark?
simple?(mark) # Is it a simple mark (atom)?
attributed?(mark) # Is it an attributed mark (tuple)?
mark_type(mark) # Get the type (:bold, :link, etc.)
mark_attrs(mark) # Get attrs (empty map for simple marks)
has_mark?(marks, type) # Does the list contain this mark type?
get_mark(marks, type) # Get the mark from the list
add_mark(marks, mark) # Add mark to list
remove_mark(marks, type) # Remove mark from list
toggle_mark(marks, mark) # Toggle mark in list
marks_equal?(m1, m2) # Compare two mark lists
JSON Serialization
to_json(node) # => %{"type" => "...", "attrs" => %{}, "children" => [...]}
from_json(json) # => {:ok, node} | {:error, message}
from_json(json, opts)
from_json!(json) # => node | raises ArgumentError
from_json!(json, opts)
opts accepts :schema, :extra_types and :extra_marks to decode custom node and mark types:
from_json(json, extra_types: [:line])
Custom Node Types
A custom node type decoded with :extra_types is first-class through the offset and mark layers: it is transparent to offset math, mark commands recurse into its :text descendants, and it is never split. Full rules: Extensibility.
{:ok, para} = from_json(json, extra_types: [:line])
# => {:paragraph, %{}, [{:line, %{page: 2}, [{:text, %{text: "Hello", marks: []}, []}]}]}
toggle_bold(para, 0, 5)
# => {:paragraph, %{}, [{:line, %{page: 2}, [{:text, %{text: "Hello", marks: [:bold]}, []}]}]}
Schema Validation
validate(node) # {:ok, node} | {:error, errors}
validate(node, schema) # with custom schema
validate!(node) # node | raises
validate!(node, schema) # with custom schema
Table Commands
add_row(table, index)
remove_row(table, index)
add_column(table, index)
remove_column(table, index)
List Commands
toggle_list_type(list) # bullet_list <-> ordered_list
Type Constants
container_types() # [:document]
block_types() # [:paragraph, :heading, ...]
inline_types() # [:text]
list_content_types() # [:list_item]
table_content_types() # [:table_row]
table_row_content_types() # [:table_cell]
node_types() # All node types
simple_marks() # [:bold, :italic, ...]
attributed_marks() # [:link, :highlight, ...]
all_marks() # All mark types
heading_levels() # 1..6
divider_styles() # [:solid, :dashed, :dotted]
callout_types() # [:info, :warning, :success, :error]
link_attrs() # [:href, :title, :target]
highlight_attrs() # [:color]
font_color_attrs() # [:color]
mention_attrs() # [:id, :type, :label]
# Layout property values
align_values() # [:left, :center, :right, :justify]
width_values() # [:narrow, :default, :wide, :full]
spacing_values() # [:none, :xs, :sm, :md, :lg, :xl]
indent_range() # 0..5
valign_values() # [:top, :middle, :bottom]
# Styling property values
font_size_values() # [:xs, :sm, :base, :lg, :xl, :"2xl", :"3xl"]
font_weight_values() # [:light, :normal, :medium, :semibold, :bold]
line_height_values() # [:tight, :snug, :normal, :relaxed, :loose]
color_values() # [:default, :muted, :accent, :success, :warning, :danger]
background_values() # [:none, :subtle, :muted, :accent, :success, :warning, :danger]
border_values() # [:none, :thin, :medium, :thick]
border_color_values() # [:default, :muted, :accent]
border_style_values() # [:solid, :dashed, :dotted]
opacity_values() # [:full, :high, :medium, :low, :faint]
shadow_values() # [:none, :sm, :md, :lg]
rounded_values() # [:none, :sm, :md, :lg, :full]
# Container layout property values
justify_values() # [:start, :center, :end, :between, :around, :evenly]
items_values() # [:start, :center, :end, :stretch, :baseline]
wrap_values() # [:nowrap, :wrap, :reverse]
gap_values() # [:none, :xs, :sm, :md, :lg, :xl]
columns_range() # 1..6