@stesura/core/schema
The document schema. stesuraSchema() builds it; the node and mark specs, node names and the global-attribute system are exported for custom schemas.
The *_NODES lists are default bindings only: stesuraSchema’s globalAttributes.nodes can change them per schema. Gate runtime behaviour on the is*Type / get*NodeNames predicates, which read the constructed schema.
Functions & values
BLOCK_CONTENT_CLASS
Classes a textblock emits from its OWN content, so stylesheets can select on
content shape without :has(), whose invalidation checks on every DOM
insertion dominated mount time (~1100 forced recalcs on a 600-block
document; docs/executed/editor-load-perf-plan.md). toDOM is memoized on node
identity, so this costs one pass per CHANGED block.
blockContentClasses
The space-separated BLOCK_CONTENT_CLASS list for a textblock, or ""
when none apply. Emitted by the blockContentClasses global attribute, not
by node specs.
| Name | Type | Default |
|---|---|---|
node | Node |
buildCoreGlobalAttributes
The core global attribute definitions with their DEFAULT node bindings.
nodeSpecs feeds the shape-derived bindings (uniqueId,
blockContentClasses); resolveGlobalAttributes applies consumer config on top.
| Name | Type | Default |
|---|---|---|
nodeSpecs | Record<string, NodeSpec> |
{ trackChanges: { nodes: string[]; attrs: { trackChanges: { default: null; }; }; toDOM: (node: Node) => {}; getAttrs: (dom: HTMLElement) => { trackChanges: null; } | { trackChanges: { ...; }; }; }; ... 19 more ...; redactionRegions: { ...; }; }ENDNOTE_NODE_NAMES
Node names and ref attr of the endnote family.
| Name | Type | Default |
|---|---|---|
anchor | "endnote_anchor" | |
body | "endnote_body" | |
container | "endnotes" | |
refAttr | string |
FOOTNOTE_NODE_NAMES
Node names and ref attr of the footnote family.
| Name | Type | Default |
|---|---|---|
anchor | "footnote_anchor" | |
body | "footnote_body" | |
container | "footnotes" | |
refAttr | string |
getBlockTrackChangeNodeNames
Names of the schema’s node types carrying block track-changes attributes.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getCodeBlockSpec
Resolves the code_block node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getColumnBreakSpec
Resolves the column_break node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getCommentsSpecs
Resolves the comment marker node types, or false when the schema omits any of them.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getCounterNodeSpec
Resolves the counter_node node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getCrossReferenceSpec
Resolves the cross_reference node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getEndnotesSpecs
Resolves the endnote node types, or false when the schema omits any of them.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getFileSpec
Resolves the file node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getFloatingNodeNames
Names of the schema’s node types carrying the floating family.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getFootnotesSpecs
Resolves the footnote node types, or false when the schema omits any of them.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getFormattedNodeNames
Names of the schema’s node types carrying the formatting family.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getGlobalDOMAttributesMap
The DOM-attributes map for a schema, including custom definitions when it
was built by stesuraSchema. Prefer this over
buildGlobalDOMAttributesMap, which needs the original config.
Other schemas get a map rebuilt from their node specs, which covers core
attributes only.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getHighlightMarkSpec
The highlight mark type, or false (with a console warning) when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | EditorState | Schema<any, any> |
getHorizontalRuleSpec
Resolves the horizontal_rule node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getImageAnchoredSpec
Resolves the inline image_anchored node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getImageSpec
Resolves the block image node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getMathDisplaySpec
Resolves the math_display node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getMathInlineSpec
Resolves the math_inline node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getNumberedNodeNames
Names of the schema’s node types carrying numbering.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getPageBreakSpec
Resolves the page_break node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getPageNumberSpec
Resolves the page_number node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getPaginatedNodeNames
Names of the schema’s node types carrying pagination.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getProofreadIgnoreMarkSpec
The proofReadIgnore mark type, or false (with a console warning) when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | EditorState | Schema<any, any> |
getProofreadNodeNames
Names of the schema’s node types carrying proofingLanguage.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getSectionSpecs
Resolves the section node types (section, content, header, footer, header/footer content), or false when the input is nullish or the schema omits any of them.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
false | { sectionContentSpec: NodeType; sectionSpec: NodeType; sectionHeaderSpec: NodeType; sectionFooterSpec: NodeType; headerFooterContentSpec: NodeType; }getSpacedNodeNames
Names of the schema’s node types carrying spacing.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getStyledBlockNodeNames
Names of the schema’s node types carrying block styling.
| Name | Type | Default |
|---|---|---|
schema | Schema<any, any> |
getTableSpecs
Resolves the table, row and cell node types, or false when the schema omits any of them.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getTextStyleMarkSpec
The textStyle mark type, or false (with a console warning) when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | EditorState | Schema<any, any> |
getTocSpec
Resolves the toc node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
getUploadBlockSpec
Resolves the upload placeholder node type, or false when the schema omits it.
| Name | Type | Default |
|---|---|---|
stateOrSchema | StateOrSchema |
GLOBAL_ATTRIBUTE_MARKER
export const GLOBAL_ATTRIBUTE_MARKER = Symbol.for("stesura.globalAttribute");Tags an attr object as injected by the global-attribute pass, so
assertNoReservedAttrs accepts an already-processed spec fed back into
stesuraSchema (e.g. { ...schema.nodes.toc.spec, spacingRole: "passThrough" }).
isBlockTrackChangesType
Carries block-level track-changes attributes — trackChanges and
trackChangesModification (default list: BLOCK_TRACK_CHANGES_NODES).
Keys on trackChanges.
| Name | Type | Default |
|---|---|---|
type | NodeType |
isFloatingType
Carries the floating placement family: wrap / anchorPosition /
wrapDistance / zIndex (default list: FLOATING_NODES). Keys on
anchorPosition; wrap is too common a name to reserve (the block image
declares its own).
| Name | Type | Default |
|---|---|---|
type | NodeType |
isFormattedType
Carries the formatting family: formatting / textAlign / direction /
suppressLineNumbers (default list: FORMATTED_NODES). Keys on indent, the attr injected by the
formatting anchor attribute.
| Name | Type | Default |
|---|---|---|
type | NodeType |
isNumberedType
Carries the numbering attribute (default list: NUMBERED_NODES).
A custom node granted numbering also needs a content expression accepting
a counter_node first child (as paragraph/heading declare), or the
numbering plugin cannot materialize its counter.
| Name | Type | Default |
|---|---|---|
type | NodeType |
isPaginatedType
Carries the pagination attribute (default list: PAGINATED_NODES).
| Name | Type | Default |
|---|---|---|
type | NodeType |
isProofreadType
Carries the proofingLanguage attribute (default list: PROOFREAD_NODES).
| Name | Type | Default |
|---|---|---|
type | NodeType |
isSpacedType
Carries the spacing attribute (default list: SPACED_NODES).
| Name | Type | Default |
|---|---|---|
type | NodeType |
isStyledBlockType
Carries block styling: styleId and blockStyling (bgColor / borders)
(default list: STYLED_BLOCK_NODES). Keys on styleId; the doc’s stylesheet
definitions live under a different name (styleSheet), so no topNode
carve-out is needed.
| Name | Type | Default |
|---|---|---|
type | NodeType |
marks
mathStyleFromMarks
What the stored marks actually render as — MATH_TEXT_STYLE_ATTRS and highlight.
| Name | Type | Default |
|---|---|---|
stored | readonly MathMarkJSON[] |
NODE_NAMES
Node type names as constants. Prefer these over string literals.
nodes
The core node specs, before the global-attribute pass.
resolveGlobalAttributes
Core + custom global attributes, with node bindings = defaults adjusted by the consumer’s delta. Invalid config only logs; a reserved gate attr on a node spec or custom definition throws a RangeError.
| Name | Type | Default |
|---|---|---|
nodeSpecs | Record<string, NodeSpec> | |
config | GlobalAttributesConfig<Record<string, GlobalAttributeDefinition>> | |
options | { assertReservedNames?: boolean; excludedNodes?: ReadonlySet<string>; } |
stesuraSchema
Builds the Stesura schema: core nodes/marks merged with the given
overrides, minus excludeNodes, then run through the global-attribute
pipeline.
| Name | Type | Default |
|---|---|---|
props | StesuraSchemaProps<D> |
withGlobalAttributes
Resolves the global attributes and applies them to every node spec.
| Name | Type | Default |
|---|---|---|
nodes | T | |
config | GlobalAttributesConfig |
Types
GlobalAttributesConfig
The globalAttributes option of stesuraSchema:
definitionsregisters custom global attributes. Keys colliding with a core attribute are discarded with an error.nodesbinds attributes to node types as a DELTA on the defaults, keyed by core or custom attribute name, so configs stay valid when core defaults evolve.
uniqueId is not configurable (pagination requires an id on every block
node); a delta for it is ignored with an error.
| Name | Type | Default |
|---|---|---|
definitions | D | |
nodes | Partial<Record<GlobalAttributeKey | (keyof D & string), GlobalAttributeNodesDelta>> |
GlobalDOMAttributesMap
export type GlobalDOMAttributesMap = Map<string, (node: Node) => Record<string, string>>;MathMarkJSON
An equation’s whole-node styling, stored as mark JSON in its mathMarks attr
rather than as real marks.
ProseMirror disallows marks inside non-inline content by default, so block
containers refuse marks on math_display: Node.check() throws and a DOM
round trip drops the node. Inline math could take real marks, but one shape
for both is simpler, and the command, toolbar and DOCX layers still speak
Mark, converting only at this boundary.
| Name | Type | Default |
|---|---|---|
type | string | |
attrs | Attrs |
MathStyle
The CSS an equation’s stored marks resolve to.
| Name | Type | Default |
|---|---|---|
color | string | |
fontSize | numberPoints, matching the | |
bgColor | string |
NoteKindNodeNames
Node names + ref attribute of one note kind (footnote/endnote), for kind-generic note code.
| Name | Type | Default |
|---|---|---|
anchor | NodeNameValue | |
body | NodeNameValue | |
container | NodeNameValue | |
refAttr | stringAnchor/body attribute holding the note ref (not “id” — the uniqueId plugin owns that). |
StesuraSchemaProps
What stesuraSchema takes.
StesuraNodeSpec
NodeSpec plus the Stesura-specific keys Stesura reads (cf. tableRole in
prosemirror-tables), typed so custom nodes get completion. Add new spec keys
here rather than reading untyped properties at the call site.
| Name | Type | Default |
|---|---|---|
spacingRole | SpacingRoleSpacing-plugin role. When absent, an unspaced wrapper-shaped node (block
node with block content, not an atom) is | |
measureAs | "atomic"
| |
keepTogether | booleanA wrapper (block node with block content) that pagination places whole when it fits a page: pushed to the next page rather than split. One taller than a page still splits between its children. | |
defaultSpacing | { before?: number; after?: number; }Spacing (px) for a spaced node with neither its own | |
directFormatting | Partial<Record<"indent", boolean>>
| |
content | stringThe content expression for this node, as described in the schema guide . When not given, the node does not allow any content. | |
marks | stringThe marks that are allowed inside of this node. May be a
space-separated string referring to mark names or groups, | |
group | stringThe group or space-separated groups to which this node belongs, which can be referred to in the content expressions for the schema. | |
inline | booleanShould be set to true for inline nodes. (Implied for text nodes.) | |
atom | booleanCan be set to true to indicate that, though this isn’t a leaf node , it doesn’t have directly editable content and should be treated as a single unit in the view. | |
attrs | { [name: string]: AttributeSpec; }The attributes that nodes of this type get. | |
selectable | booleanControls whether nodes of this type can be selected as a node selection . Defaults to true for non-text nodes. | |
draggable | booleanDetermines whether nodes of this type can be dragged without being selected. Defaults to false. | |
code | booleanCan be used to indicate that this node contains code, which causes some commands to behave differently. | |
whitespace | "pre" | "normal"Controls way whitespace in this a node is parsed. The default is
| |
definingAsContext | booleanDetermines whether this node is considered an important parent node during replace operations (such as paste). Non-defining (the default) nodes get dropped when their entire content is replaced, whereas defining nodes persist and wrap the inserted content. | |
definingForContent | booleanIn inserted content the defining parents of the content are preserved when possible. Typically, non-default-paragraph textblock types, and possibly list items, are marked as defining. | |
defining | booleanWhen enabled, enables both
| |
isolating | booleanWhen enabled (default is false), the sides of nodes of this type count as boundaries that regular editing operations, like backspacing or lifting, won’t cross. An example of a node that should probably have this enabled is a table cell. | |
toDOM | (node: Node) => DOMOutputSpecDefines the default way a node of this type should be serialized
to DOM/HTML (as used by
For text nodes, the default is to create a text DOM node. Though it is possible to create a serializer where text is rendered differently, this is not supported inside the editor, so you shouldn’t override that in your text node spec. | |
parseDOM | readonly TagParseRule[]Associates DOM parser information with this node, which can be
used by | |
toDebugString | (node: Node) => stringDefines the default way a node of this type should be serialized to a string representation for debugging (e.g. in error messages). | |
leafText | (node: Node) => stringDefines the default way a leaf node of
this type should be serialized to a string (as used by
| |
linebreakReplacement | booleanA single inline node in a schema can be set to be a linebreak
equivalent. When converting between block types that support the
node and block types that don’t but have
|
Other exports
| Export | Type | Description |
|---|---|---|
BLOCK_TRACK_CHANGES_NODES | string[] | Default nodes carrying block-level track changes (trackChanges and trackChangesModification). |
FLOATING_NODES | string[] | Default nodes carrying the floating placement family (wrap, anchorPosition, wrapDistance, zIndex): positioned objects anchored in a textblock. |
FORMATTED_NODES | string[] | Default nodes carrying the formatting global attributes (formatting, which injects indent, plus textAlign / direction / suppressLineNumbers). |
GATE_ATTRS | readonly ["numbering", "pagination", "indent", "spacing", "styleId", "proofingLanguage", "trackChanges"] | The attrs the predicates key on, one per predicate. Reserved: a node spec or custom global attribute declaring one throws a RangeError. |
GateAttr | "numbering" | "pagination" | "indent" | "spacing" | "styleId" | "proofingLanguage" | "trackChanges" | |
GlobalAttributeKey | "numbering" | "proofingLanguage" | "formatting" | "textAlign" | "spacing" | "styleId" | "blockStyling" | "uniqueId" | "direction" | "trackChanges" | "trackChangesModification" | "suppressLineNumbers" | "nodeComment" | "pagination" | "blockContentClasses" | Names of the core global attributes. |
GlobalAttributeNodesDelta | GlobalAttributeNodesDelta | Node-binding delta for one global attribute: true grants it to the node type, false revokes a default binding, absent keeps the default. |
NodeNameValue | "doc" | "paragraph" | "heading" | "counter_node" | "toc" | "horizontal_rule" | "page_break" | "image" | "image_anchored" | "math_inline" | "math_display" | "table" | "table_row" | "table_cell" | "code_block" | "hard_break" | "boundary_open_node" | "boundary_close_node" | "page_number" | "comment_open" | "comment_close" | "upload_block" | "file" | "header_footer_content" | "section" | "section_header" | "section_footer" | "section_content" | "footnotes" | "footnote_anchor" | "footnote_body" | "endnotes" | "endnote_anchor" | "endnote_body" | "cross_reference" | |
NUMBERED_NODES | string[] | Default nodes carrying the numbering attr. |
PAGINATED_NODES | string[] | Default nodes carrying the pagination attr (keepWithNext / keepLines / widowOrphan / pageBreakBefore). |
PROOFREAD_NODES | string[] | Default nodes carrying the proofingLanguage attr. |
SPACED_NODES | string[] | Default nodes carrying the spacing attr. |
SPAN_COLUMNS_NODES | string[] | Default nodes carrying spanColumns: titles and wide figures in a column section. |
SpacingRole | "passThrough" | "boundary" | How a non-spaced block container takes part in the spacing plugin’s margin-collapse chains: "passThrough": its children join the surrounding chain, so margins collapse across its edges. The inferred default for wrapper nodes (block nodes with block content). "boundary": its children form an isolated chain (like a table cell). |
STYLED_BLOCK_NODES | string[] | Default nodes carrying block styling (styleId and blockStyling). |
Redaction attribute
REDACTED_LEAF_NODES lists the core block leaves that take the redaction global attribute (a
picture, an equation, an embedded file); a package’s own (Mermaid’s diagram) grants it through
globalAttributes. Inline content takes the redaction mark instead. REDACTION_REGION_NODES
lists the pictures that take redactionRegions, their redacted areas.