API Reference
deixis-attach
Wraps rendered content to attach pins, scan marked tokens, or register a selectable routing node.
Setup Required
Returns: content.
Example
deixis-attach(id: <card>)[A card]
id registers a routing frame with avoid behavior by default. Generated node ports are the four side midpoints. pins can define custom outlets. Explicit avoid/ignore/cut/cross also registers anonymous nodes. Pin-only attachments keep their native breakability.
deixis-attach
deixis-attach(body, id: none, behavior: auto, pins: (:), scope: none, prefix: auto, postfix: auto, pattern: auto, padding: auto, pin-padding: (:), inline: false)
Attaches geometric anchors and optional routing identity to live content.
This function does two things:
- It scans the
bodytext for your pin prefix (e.g.,deixispinTop) and converts them into physical inline pins. - It can place absolute overlay pins relative to the bounding box of the
body(e.g., placing a pin exactly atdx: 100%, dy: 100%). Optional id/behavior also registers the content frame for deixis-routing. Named frames offer top/bottom/left/right midpoint ports automatically; use connector.ports for side/percentage/sliding selection or one of these pins for an exact custom socket. pins accepts any number of named anchors.
- body (content): The content block to wrap and scan.
- pins (dictionary): A dictionary mapping pin names to overlay coordinates and padding. Example:
("my-pin": (dx: 100%, dy: 50%, padding: 2pt)). - scope (none, str, label, location): Optional namespace shared by this attachment’s scanned and coordinate pins.
- prefix (auto, str, none): Literal opening delimiter; auto uses “deixispin”. Set to none to disable delimiter scanning.
- pattern (auto, regex, none): An explicit scanning regex with exactly one capture for the pin name; overrides delimiters.
- padding (auto, str, length, dictionary): Padding for pins replaced with
prefix. It has no effect on pins defined withpins. - inline (bool): If
true, the wrapper uses an inlineboxinstead of ablock.
Parameters
| Name | Default | Types |
|---|---|---|
body | required | content |
id | none | none, str, label |
behavior | auto | auto, str |
pins | (:) | dictionary, array |
scope | none | none, str, label, location |
prefix | auto | auto, str, none |
postfix | auto | auto, str, none |
pattern | auto | auto, regex, none |
padding | auto | auto, str, length, dictionary |
pin-padding | (:) | dictionary |
inline | false | bool |
body
The content block to wrap and scan.
id
Optional routing-node identity. Strings and labels agree. A registered attachment is one nonbreaking native frame and can be selected with (node: id) by deixis-connect. Scope also namespaces this identity. Four side midpoints are automatic ports; no named pins are required. Independent of note IDs and pin names, including equal spellings. Wrapping an overlay note declaration captures its declaration, not its painted body.
behavior
Routing behavior: avoid, ignore, cut or cross. auto registers an avoid node when id is supplied; without an ID, auto preserves ordinary attach. An explicit behavior also registers an anonymous obstacle/decorative node.
pins
A dictionary mapping pin names to overlay coordinates and padding. Example: ("my-pin": (dx: 100%, dy: 50%, padding: 2pt)).
#deixis-attach(
pins: (
area-tl: (dx: 20%, dy: 20%, padding: 2pt),
area-br: (dx: 80%, dy: 80%, padding: 2pt),
),
)[
#rect(width: 160pt, height: 90pt, fill: luma(240))
]
#deixis-region-mark(
pins: ("area-tl", "area-br"),
stroke: red + 2pt,
)
Missing coordinates default to zero. Bottom pins (dy: 100%, optionally
plus an offset) follow the final fragment of a breakable block.
An alternative (anchor: top + right, offset: (2pt, 0pt)) uses native
alignment and an optional coordinate pair. Do not combine it with dx/dy.
Dictionary keys are strings. A pair array also accepts label-valued names,
e.g. ((<corner>, (anchor: top + left)),).
scope
Namespace for both scanned and coordinate pins. It does not affect other pin declarations in the body or change note/counter scopes.
prefix
Literal opening delimiter. If auto, uses "deixispin"; none/empty disables
delimiter scanning. Use pattern for intentional regular expressions.
Info.
Pins attached with regex scan will have padding: "text" by default. Use deixis-attach.padding for customization.
Usage:
#deixis-attach(prefix: "mypin")[
```typst
mypincode1#deixis-attachmypincode2(postfix: "deixis")[
deixispinp1deixisThis line will be pinned.deixispinp2deixis
]
// Now one can use pins "p1" and "p2"
```
]
#deixis-region-mark(pins: ("code1", "code2"), fill: red.transparentize(95%))
Tip.
Oftentimes, if prefix alone is not enough, you can also define a postfix.
The name of the pin attached with regex scan should also not contain any special character, depending on the raw language.
Set to none or an empty string to disable text scanning.
postfix
Literal closing delimiter. If auto, uses ""; none/empty omits it.
Python hello world program:
#deixis-attach(
prefix: "mypin",
postfix: "mypin")[
```python
mypincode3mypinprintmypincode4mypin("Hello world!")
```
]
#deixis-region-mark(pins: ("code3", "code4"), fill: red.transparentize(95%))
pattern
Explicit scanning regex with exactly one capture for the pin name.
auto builds a pattern from literal prefix/postfix; none disables scanning.
padding
Padding for pins replaced with deixis-attach.prefix. It has no effect on pins defined with deixis-attach.pins.
Pythagorean theorem:
#align(center)[
#deixis-attach(
prefix: "mypin",
pin-padding: ( // dict of pin names
eq1: (top: 1.2em, bottom: 0.5em, left: 1em),
eq2: (top: 1.2em, bottom: 0.5em, right: 1em),
),
)[
mypineq1$a^2 + b^2 = c^2$mypineq2
]
]
#deixis-region-mark(pins: ("eq1", "eq2"), stroke: orange, fill: orange.transparentize(95%))
pin-padding
Per-name padding for scanned pins. Names such as left/rest are literal names here. Unlisted names use padding; explicit coordinate pins keep their own padding. Prefer this to legacy per-name maps passed through padding.
inline
If true, the wrapper uses an inline box instead of a block.
#lorem(7)
#deixis-attach(
pins: (tl1: (dx: 0%, dy: 0%), br1: (dx: 100%, dy: 100%)),
inline: false)[
Block-level attached content.
]
#deixis-region-mark(pins: ("tl1", "br1"), stroke: teal)
#lorem(7)
#deixis-attach(
pins: (tl2: (dx: 0%, dy: 0%), br2: (dx: 100%, dy: 100%)),
inline: true)[
Inline attached content.
]
#deixis-region-mark(pins: ("tl2", "br2"), stroke: green)