58.9 Formula Assemblies and Named Parts
A formula-assembly stores manually placed, named formula parts. Use formula-select to obtain a part’s scene path, styling operations to change selected parts immutably, and a formula-correspondence to record a mapping between endpoint assemblies. Joint TeX layout is documented separately in Tagged Formula Layouts.
See also Formula Construction and Layout, Formula Source Selection and Matching.
58.9.1 Named Formula Parts and Correspondence
A formula assembly is a composite Visual made from independently typeset LaTeX formula parts. Each part has a symbol name. That name is local to one assembly and is also the identity of the part’s formula Visual.
Part order is significant back-to-front drawing order. Part positions are local to the assembly anchor. The library does not ask TeX to lay out several parts as one document. The caller chooses each local position explicitly. Parts can overlap when their local anchors are placed too close together.
struct
(struct formula-part (name formula) #:transparent) name : symbol? formula : formula-visual?
The name field is local to one formula assembly. The formula field contains the complete semantic formula Visual used to render the fragment. The structure guard requires (eq? name (visual-id formula)). This rule gives each local name one stable formula identity.
The formula transform and opacity are local to its containing assembly. The structure is immutable and transparent.
procedure
(latex-formula-part source #:name name [ #:center center #:rotation rotation #:scale scale #:opacity opacity #:mode mode #:font-size font-size #:preamble preamble #:document-class-options document-class-options #:preview-options preview-options #:horizontal-alignment horizontal-alignment #:vertical-alignment vertical-alignment]) → formula-part? source : string? name : symbol? center : vec2? = origin rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1 mode : formula-mode? = 'display font-size : (and/c finite-real? positive?) = 1 preamble : string? = "" document-class-options : (listof latex-option?) = '() preview-options : (listof latex-option?) = '() horizontal-alignment : text-horizontal-alignment? = 'center vertical-alignment : text-vertical-alignment? = 'center
The center value is local to the formula assembly that will contain the part. Formula source, preamble, and string options are copied into immutable model storage.
Example:
(latex-formula-part "n(n+1)" #:name 'numerator #:center (vec2 0 1/2) #:mode 'inline #:font-size 1/3)
procedure
(formula-assembly parts #:id id [ #:center center #:rotation rotation #:scale scale #:opacity opacity]) → formula-assembly-visual? parts : (listof formula-part?) id : symbol? center : vec2? = origin rotation : finite-real? = 0 scale : scale-factor? = 1 opacity : opacity? = 1
Part names must be unique within the assembly. Because every part name is also its formula Visual identity, id must differ from every part name. Part names are local: two different assemblies may use the same names.
The assembly center is its reference position in the containing coordinate system. The assembly rotation is measured counter-clockwise in radians. Its own scale must be uniform after normalization. This is the same restriction used by group; a non-uniform parent scale followed by a rotated part can require shear, which the current transform model cannot represent. Individual formula parts may still use non-uniform local scales.
The assembly implements gen:visual, gen:affine-visual, and gen:opacity-visual. Existing movement, rotation, uniform scale, opacity, fade-in, and fade-out operations therefore work on the complete assembly.
Every nonempty part is typeset separately. The caller is responsible for local part spacing. The Pict adapter passes the same explicit renderer list to every part. A custom renderer placed before the defaults may instead support and replace the complete assembly. An empty assembly renders as stable transparent one-pixel local geometry without running TeX.
procedure
(formula-assembly-visual? value) → boolean?
value : any/c
procedure
(formula-assembly-visual-parts assembly)
→ (listof formula-part?) assembly : formula-assembly-visual?
procedure
(formula-assembly-visual-with-parts assembly parts) → formula-assembly-visual? assembly : formula-assembly-visual? parts : (listof formula-part?)
procedure
(formula-assembly-visual-part-names assembly)
→ (listof symbol?) assembly : formula-assembly-visual?
procedure
(formula-assembly-visual-has-part? assembly name) → boolean? assembly : formula-assembly-visual? name : symbol?
procedure
(formula-assembly-visual-ref assembly name) → formula-part?
assembly : formula-assembly-visual? name : symbol?
procedure
(formula-select formula name) → visual-path?
formula : formula-assembly-visual? name : symbol?
A selected named part is an ordinary nested scene path.
> (define equation (formula-assembly (list (latex-formula-part "x" #:name 'x)) #:id 'equation)) > (formula-select equation 'x) '(equation x)
procedure
(formula-style formula selection [ #:color color #:opacity opacity]) → formula-assembly-visual? formula : formula-assembly-visual? selection : (or/c symbol? (and/c pair? (listof symbol?))) color : (or/c false/c color-spec?) = #f opacity : (or/c false/c opacity?) = #f
The new assembly preserves its identity, part order, formula source, TeX/SVG artifact, and ordinary transforms. Its selected formula leaves implement the existing fill-colour and opacity protocols. Equal styles therefore retain normal rigid matching motion; a paint change between formula-rewrite endpoints uses the established cross-fade fallback.
procedure
(formula-color formula selection color)
→ formula-assembly-visual? formula : formula-assembly-visual? selection : (or/c symbol? (and/c pair? (listof symbol?))) color : color-spec?
procedure
(formula-color-map formula color-map) → formula-assembly-visual?
formula : formula-assembly-visual? color-map : (hash/c symbol? color-spec?)
struct
(struct formula-part-match (source-name destination-name) #:transparent) source-name : symbol? destination-name : symbol?
source-name names a part in a source assembly. destination-name names a part in a destination assembly. The structure itself checks only that both fields are symbols. A formula-correspondence checks that the names exist and are used one-to-one.
struct
(struct formula-correspondence (source destination matches) #:transparent) source : formula-assembly-visual? destination : formula-assembly-visual? matches : (listof formula-part-match?)
The source and destination fields store the exact immutable assembly values used when the correspondence is created. The matches field is stored in significant caller order.
Construction checks all of the following:
Every source name exists in source.
Every destination name exists in destination.
A source name appears at most once.
A destination name appears at most once.
The match list may be empty. Equal names are not matched automatically. Parts omitted from matches remain explicitly unmatched. The list order is also the order of matched transition layers created by transform-formula-parts.
procedure
(formula-correspondence-auto source destination) → formula-correspondence? source : formula-assembly-visual? destination : formula-assembly-visual?
procedure
(formula-correspondence-unmatched-source-names correspondence)
→ (listof symbol?) correspondence : formula-correspondence?
procedure
(formula-correspondence-unmatched-destination-names correspondence)
→ (listof symbol?) correspondence : formula-correspondence?
A formula correspondence stores endpoint templates. It does not store sampled transition layers. Those layers are compiled when transform-formula-parts is passed to scene-play, so the operation can use the current formulas, local transforms, and local opacities from the scene.