Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

crap.richtext

Register custom ProseMirror node types for the rich text editor and render rich text content to HTML.

Functions

crap.richtext.register_node(name, spec)

Register a custom rich text node type.

Parameters:

  • name (string) — Node name (alphanumeric + underscores only).
  • spec (table) — Node specification.

Spec fields:

FieldTypeDefaultDescription
labelstringnameDisplay label in the editor toolbar
inlinebooleanfalseWhether this is an inline node (vs block)
attrsFieldDefinition[]{}Node attributes via crap.fields.* (scalar types only)
searchable_attrsstring[]{}Attribute names included in full-text search
renderfunctionnilCustom HTML render function (attrs) -> string

Node attributes use crap.fields.* factory functions (same as collection fields). Only scalar types are allowed: text, number, textarea, select, radio, checkbox, date, email, json, code.

Supported attribute features:

  • Admin display hints: admin.hidden, admin.readonly, admin.width, admin.step, admin.rows, admin.language, admin.placeholder, admin.description
  • Validation bounds: required, validate, min/max, min_length/max_length, min_date/max_date, picker_appearance
  • Lifecycle hooks: hooks.before_validate (normalize values before validation)

Features that have no effect on node attrs (unique, index, localized, has_many, access, hooks.before_change/after_change/after_read, mcp, admin.condition) produce a warning at registration time but do not error.

crap.richtext.register_node("callout", {
    label = "Callout",
    attrs = {
        crap.fields.select({ name = "type", options = {
            { label = "Info", value = "info" },
            { label = "Warning", value = "warning" },
        }}),
        crap.fields.text({ name = "body", admin = { rows = 4 } }),
    },
    searchable_attrs = { "body" },
    render = function(attrs)
        return string.format(
            '<div class="callout callout-%s">%s</div>',
            attrs.type or "info",
            attrs.body or ""
        )
    end,
})

crap.richtext.render(content)

Render a rich text JSON string to HTML, including any registered custom nodes.

Parameters:

  • content (string) — ProseMirror JSON content string.

Returns: string — Rendered HTML.

local html = crap.richtext.render(doc.body)

Notes

  • Register nodes in init.lua so they’re available to all VMs.
  • Custom nodes appear in the rich text editor toolbar for fields that include them.
  • The render function is called during crap.richtext.render() to convert custom nodes to HTML.