API Overview

Everything CallioText exports comes from the single entry point @project-callio/calliotext, and there are over a hundred exports. This page sorts them into five groups by module, describing each group's responsibility and boundaries. For item-level detail, use the TypeDoc reference alongside.

Module layers

The source is organized in layers, more fundamental toward the bottom:

default_implementation
Ready-to-use defaults: DefaultEditorComponent, DefaultPrinterComponent, the get_default_ factories, the contexter family, printing typography widgets
editor
Editing core: EditorCore, EditorComponent, the plugin system, tree operations
printer
Printing core: Printer, PrinterComponent, PrinterRenderer, Env and Context
implbase + uibase
React infrastructure: hooks, the style configuration system, button kits, general UI utilities, error classes
core
Concept model and the document tree: FirstClassConcept, SecondClassConcept, the seven node kinds, validate, type guards

Reading from the bottom up: the lowest layer, core, is pure data. It holds the classes for first- and second-class concepts, the type definitions of the seven node kinds, and the tree validation functions. It has no React dependency and no notion of an interface, so any environment can import it, validating a document on a server for instance.

One layer up sit implbase and uibase, a body of React infrastructure: hooks for reading the current node and its parameters, the style configuration system, button components with keyboard navigation support, and the error classes used throughout the library. They do not form an editor by themselves, but both layers above are built on them.

Above that, editor and printer stand side by side as the cores of the editing side and the output side. Side by side means mutually independent: the editor does not know how the document will eventually be typeset, the printer does not know how it was edited, and the two share only the document tree that core defines. The compiler front-end and back-end analogy from tutorial chapter 1 describes exactly this structure. editor owns the Slate wrapper, the tree operations and the plugin system; printer owns two-phase rendering and the renderer protocol.

The top layer, default_implementation, assembles everything below into ready-to-use products: the complete editor and printer components, the renderer factory functions, the contexter family. This is the layer the tutorial works with throughout.

Day-to-day use tends to follow the same order, top down: start with the components and factories of default_implementation; when a concept's appearance needs customizing, use the factories' customization points together with the implbase hooks; drop down to editor when modifying documents programmatically or writing plugins; deal with printer's preprocessing machinery when numbering and cross references come in; and core is present all along, since concepts and node types run through everything. The table below is a quick lookup of each layer's responsibilities:

LayerResponsibilityTypical use
core The pure data layer: concept classes, node type definitions, tree validation. No React dependency. Defining concepts, persistence, typing
editor The editing side: the Slate wrapper, renderer registration and dispatch, tree operations, the plugin system, editor state hooks. Custom plugins, custom buttons, programmatic document edits
printer The output side: two-phase rendering (preprocessing plus rendering), the renderer protocol, the types of the preprocessing products. Custom printer renderers, reference features
default_implementation The defaults: complete editor and printer components, the renderer factory functions, the contexter family. Where most applications start
implbase / uibase Infrastructure: hooks like useNode and useParameters, the style configuration system, small UI components, error classes. Inside custom renderers

The typical assembly

The structure the tutorial builds in chapters 3 through 5, condensed:

import {
    // core: define concepts
    FirstClassConcept, SecondClassConcept,
    // printer: printing core
    Printer,
    // editor: editing core
    EditorCore,
    // default_implementation: components and factories
    DefaultEditorComponent, DefaultPrinterComponent,
    get_default_editors, get_default_group_renderer,
} from "@project-callio/calliotext"

const printer = new Printer(first_concepts, second_concepts,
                            printer_renderers, printer_defaults)
const core    = new EditorCore({renderers, default_renderers: get_default_editors(), printer})

<DefaultEditorComponent editorcore={core} />
<DefaultPrinterComponent printer={printer} root={tree} />

These few lines condense the wiring between the layers: the concepts defined with core are handed to the Printer for keeping; the Printer is handed to the EditorCore so the editing side can query it; finally the two default components each take the core object of their own side and start working. Every CallioText application has this same skeleton; what varies is the content of the concept lists and the renderers.

Conventions used throughout the library

These conventions recur in every module; keeping them in mind makes the following pages easier to read: