Text and expressions

What an attribute’s text becomes: rich text and its footnotes, live values, symbol names, measured and wrapped labels, and a compiled expression.

@internote/canvas-sdk37 exports

#Functions

applyTextFunction
packages/canvas-sdk/src/content/text-functions.ts:164
Applies one text function, such as format or upper, to a plain string.
(
    name: TextFunctionName,
    text: string,
    attributes?: Record<string, unknown>,
): string
balancedWrap
packages/canvas-sdk/src/text/index.ts:158
Words wrapped the way the BROWSER will wrap them — balanced, not greedy.
(text: string, px: number, cap: number, family?: string): {
    width: number;
    wrapAt: number;
    lines: number;
}

wrapWidths fills each line to the limit, which is what CSS does by default; a label given a hard width carries text-wrap: balance, and the browser then breaks it into lines of even length instead. The two disagree badly: "what adding them would predict" wrapped greedily at a 260px cap is a 250px line and a 40px one, so 250px of gutter gets reserved — and the browser then sets two 130px lines, leaving 120px of empty air between the words and whatever stands beyond them.

So the balance is computed here too: the NARROWEST width that still sets the words in the same number of lines, found by bisection, which is what balancing amounts to. width is then the ink as it will actually appear, and wrapAt the box to hand the browser — the ink plus a hair, so a measurement a fraction out cannot tip a line over.

compileComplexExpression
packages/canvas-sdk/src/maths/complex.ts:185
A complex expression compiled once — its formals fixed — for the samplers that call it thousands of times over a window.
(
    js: string,
    variables: string[],
    params: Record<string, number>,
): ((...args: Array<number | Complex>) => Complex | null) | null
compileSafeExpression
packages/canvas-sdk/src/maths/safe-function.ts:113
Compile an expression to a function of formals, or null where the formals or the body fail the checks above, or JavaScript refuses the result (a repeated formal, unbalanced brackets).
<F extends (
    ...args: never[],
) => unknown>(js: unknown, formals: readonly string[], namespaces?: ExpressionNamespaces): F | null
evaluateComplexExpression
packages/canvas-sdk/src/maths/complex.ts:156
Evaluate a compiled complex expression.
(js: string, values: Record<string, number | Complex>): Complex | null
evaluateExpression
packages/canvas-sdk/src/maths/index.ts:26
Safely evaluate a mathematical expression with injected parameters.
(expr: string, params: Record<string, number>): number
expr
JavaScript expression string (e.g., "t+1", "sin(x)")
params
Record of parameter names to numeric values

Returns The numeric result, or NaN if evaluation fails

expressionItemOf
packages/canvas-sdk/src/content/expressions.ts:89
The payload of an inline expression item, or null for any other item.
(item: unknown): ChalkExpression | null
flatten
packages/canvas-sdk/src/text/index.ts:243
Converts inline content to a plain string with its formatting dropped, as a maths run's text is handed to KaTeX.
(items: unknown): string
formatLiveValue
packages/canvas-sdk/src/content/live-value-store.ts:265
Formats a live value for display in text: about four significant figures, or an em dash when there is no value yet.
(value: number | undefined, options?: LiveValueFormatOptions): string
hasLabel
packages/canvas-sdk/src/text/index.ts:212
Whether a label value has anything to draw.
(value: unknown): boolean
isComplexValue
packages/canvas-sdk/src/maths/complex.ts:141
Whether a value is a Complex: an object with numeric re and im.
(value: unknown): value is Complex
isSafeCompiledExpression
packages/canvas-sdk/src/maths/safe-function.ts:73
Whether js is an expression the compilers could have emitted over these formals — see the module remarks for exactly what that admits.
(
    js: unknown,
    formals: readonly string[],
    namespaces?: ExpressionNamespaces,
): js is string
formals
The names the function will declare; the only bare names the body may use.
namespaces
The namespaces reachable as ns.member, defaulting to Math.
isSafeFormalName
packages/canvas-sdk/src/maths/safe-function.ts:62
Whether name may be a formal of a compiled expression: an ASCII identifier, and not a reserved word.
(name: unknown): name is string
isSymbolName
packages/canvas-sdk/src/content/symbol-names.ts:81
Whether name is a symbol the language has a drawing for.
(name: unknown): name is SymbolName

Asked of the NAMES rather than of the glyph table, which is the same question — the table is keyed by them — and does not need the drawings to answer it.

isTextFunction
packages/canvas-sdk/src/content/text-functions.ts:152
Whether a micronode identifier names one of the text functions.
(identifier: string): identifier is TextFunctionName
labelPx
packages/canvas-sdk/src/text/index.ts:204
Converts an element's text-size: (or size:) to pixels at the environment's scale factor u.
(points: unknown, u: number): number
latexContent
packages/canvas-sdk/src/text/index.ts:232
A LaTeX string as inline content — a label that IS one maths run.
(source: string): unknown

The axis numbers under x-format: radians are written as TeX rather than authored as chalk, and they still want everything a label has: the halo, the KaTeX rendering, the fallback to the source when the maths does not parse. Wrapping the string in the micronode the compiler would have emitted hands it all of that instead of a second, parallel way to draw maths.

renderedText
packages/canvas-sdk/src/text/index.ts:286
What a label will look like, near enough to count and to measure.
(items: unknown): string

flatten gives the SOURCE, and for maths the source is not the picture: $\theta$ is six characters of chalk and one letter on the page. Anything asking how long a label is — whether an axis name is a single letter, how much room to leave for it — has to ask about the letter. So each maths run is reduced to its atoms: a symbol macro stands for the one glyph it draws, an accent or a face for none, and braces and spacing for nothing.

The glyph a macro stands in as is an m, which is no narrower than the Greek letters this is nearly always used for — the answer is a margin's width, so erring wide is erring safe.

safeHref
packages/canvas-sdk/src/content/safe-href.ts:45
The link target as it may be rendered, or undefined when it may not.
(raw: unknown): string | undefined
textWidth
packages/canvas-sdk/src/text/index.ts:90
How wide text is at px in family, measured by the browser where there is one and estimated from an average glyph where there is not.
(text: string, px: number, family?: string): number

Cached, except while the face is still downloading — a measurement taken against the fallback must not be remembered as the answer.

wrapWidths
packages/canvas-sdk/src/text/index.ts:122
Greedy word wrap at a width, measured in the face the text will be set in.
(text: string, px: number, maxWidth: number, family?: string): number[]

#Classes

LiveValueStore
packages/canvas-sdk/src/content/live-value-store.ts:84
The document's live numbers, keyed by node id and member: what a derived attribute publishes and a {{#id.member}} reads.
typeof LiveValueStore

A construct that computes something (a fit's slope, an integral's area) publishes it with publish; prose and labels read it with read and subscribe, or through useLiveValue. One store serves a whole document, above both the narrative column and the canvas, so a number in prose follows the environment the reader is manipulating. A read of an id that names a @define invocation resolves through the calls map given to setCalls, following bindings and bound expressions on every read. Free names go under the $free scope, lowercased. Publishing undefined clears a slot; clear empties them all.

#Constants

ACADEMIC
packages/canvas-sdk/src/text/index.ts:57
The CSS font stack labels are set in: the site's academic serif, falling back to Georgia.
string
LABEL_POINTS
packages/canvas-sdk/src/text/index.ts:193
The text-size: value that gives a label the standard size, LABEL_SIZE; it is the schema default.
number
LABEL_SIZE
packages/canvas-sdk/src/text/index.ts:191
The default label size in pixels, before the environment's scale factor u is applied.
number
MATH_NAMESPACES
packages/canvas-sdk/src/maths/safe-function.ts:35
The namespaces a real expression reaches: Math alone.
ExpressionNamespaces
SYMBOL_LABELS
packages/canvas-sdk/src/content/symbol-names.ts:37
What each symbol is called, in words — the alt text for a drawing, and the fallback reading for the speech layer.
Record<SymbolName, string>

#Interfaces

Complex
packages/canvas-sdk/src/maths/complex.ts:22
A complex number; also the compiled value of a complex literal.
imRequired
The imaginary part.
number
reRequired
The real part.
number
InlineNode
packages/canvas-sdk/src/text/index.ts:34
A compiled inline item as this module reads it: a text run, or a micronode.
attributes
The micronode's own attributes, already refined.
Array<{ identifier: string; value: unknown }>
body
What the micronode wraps: further inline content, or a string.
unknown
content
The characters, on a text run.
string
identifier
The micronode's name — bold, latex, a hue.
string
type
'text' for a plain run, 'expression' for a bound {{…}} value.
string
LiveValueFormatOptions
packages/canvas-sdk/src/content/live-value-store.ts:247
Options for formatLiveValue.
digits
Significant figures; absent = about four.
number
RichTextFootnoteArgs
packages/canvas-sdk/src/content/types.ts:54
What RichTextOptions' renderFootnote receives for one footnote.
contentRequired
The rendered trigger content.
React.ReactNode
context
Where the footnote is shown.
narrativecanvas
keyRequired
The React key the returned node must carry.
React.Key
noteRequired
The footnote note text.
string
RichTextNode
packages/canvas-sdk/src/content/types.ts:27
One item of inline content: a text run, a micronode such as bold or link, or a block produced by parseMarkdownToRichText.

renderRichText renders text runs and micronodes; it renders nothing for a list or a block break, and a block equation renders inline.

attributes
A micronode's attributes, such as a link's href.
Array<{ identifier: string; value: unknown }>
body
A micronode's body: nested inline content, or a plain string.
RichTextNode[] | string
content
A text run's text.
string
identifier
The micronode's kind, such as bold, latex or footnote.
string
isBlockBreak
Whether the node marks the break between two paragraphs.
boolean
isBlockEquation
Whether a latex node came from $$…$$, a display equation.
boolean
isList
Whether the node is a list, whose items are in listItems.
boolean
listItems
A list's items, each its own inline content.
RichTextNode[][]
listType
Whether a list is bulleted or numbered.
ulol
type
'text' for a text run; 'expression' for a bound expression; absent for a micronode.
string
RichTextOptions
packages/canvas-sdk/src/content/types.ts:79
How renderRichText renders: where the text is shown, and the host's own renderers for the nodes that need app data.

Each renderer left out falls back to a self-contained rendering.

context
Where the text is shown, which picks the context variant of some classes.
narrativecanvas
renderCitation
Render a cite marker. Injected by the host because the number it shows comes from the document's citations key, which the SDK cannot see. Falls back to a raised dot.
(args: RichTextCitationArgs) => React.ReactNode
renderFootnote
Render a footnote node. Injected by the host to use a richer popover. Falls back to an underlined trigger with a native title tooltip.
(args: RichTextFootnoteArgs) => React.ReactNode
renderInternoteRef
Render an internote cross-reference node. Injected by the host because it needs app data/loading. Falls back to a plain link to /{id}.
(id: string | undefined, key: React.Key) => React.ReactNode

#Types

ExpressionNamespaces
packages/canvas-sdk/src/maths/safe-function.ts:29
A namespace an expression may reach members of, by name: Math, or a runtime such as the complex cx.
Readonly<Record<string, ReadonlySet<string>>>
LiveValueEntry
packages/canvas-sdk/src/content/live-value-store.ts:244
One live value to publish, as [nodeId, member, value]; a value of undefined removes it.
readonly [string, string, number | undefined]
RichTextContext
packages/canvas-sdk/src/content/types.ts:51
Where rich text is shown, which picks the context variant of some classes (bold, code, links, footnotes).
narrativecanvas
TextFunctionName
packages/canvas-sdk/src/content/text-functions.ts:149
A text function a renderer can apply to a micronode's text.
formatupperlowertitletruncatepad

Last updated