5.4 Fit-Anchor¶
Fit-Anchor is one of the most important modules in PnPInk. It is the placement engine that lets you position objects relative to placeholders without manual coordinates and without hardcoding object/template sizes.
In practice, Fit-Anchor lets you place one or many objects on a placeholder and then align, scale, rotate, mirror, shift, and clip them with compact syntax.
5.4.1 Dataset Mental Model¶
Fit-Anchor is easier to understand if you keep this model in mind:
- the dataset header points to a placeholder object in the SVG,
- each row cell provides one or many source objects,
- Fit-Anchor defines how those source objects are positioned relative to that placeholder for each generated card/instance.
5.4.2 What Is an "Object" Here?¶
In this documentation, we call IDs "objects" (not "elements") from the DSL/user point of view.
An object can be:
- an existing SVG object by ID (rect, path, group, text, image, etc.),
- a dynamic object created by
Source(local file, spritesheet frame, internet URL, Wikimedia/Pixabay, icon library), - a multivalue object list in one cell:
id1~7 id2~9 id3~3, - an explicit object array:
[id1 id2 id3](optionally with local array layout).
Representative examples:
main_art-8
heart_icon
@{assets/picture.png}~i5
@sp1[14]~m5
@{wkmc://File:Example.svg/svg#nodeX}~i5
id1~7 id2~9 id3~3
[id_a id_b id_c].L{3x1 g=2}~i5
5.4.3 Syntax and Style¶
Fit-Anchor follows the same DSL conventions as other modules:
Module{ key=value ... }long form,- short aliases (
a,b,s, etc.), - default parameters can be omitted,
- compact shorthand with
~is available and heavily used in real datasets.
Long form:
object_id.Fit{ border fitmode anchor shift clip rotate mirror }
Compact form:
object_id~...
Compact Example (Explained)¶
Example:
id1~[10%]i7^^[-50% 0]!
Read it left to right:
[10%]-> border (resize context around placeholder),i-> fit modeinside,7-> anchor top-left,^^-> rotate 180 deg,[-50% 0]-> shift left by half placeholder width,!-> clip to the placeholder shape.
This compact style is very expressive once you know the token order.
5.4.4 Fit-Anchor Parameters¶
The following subsections describe each Fit-Anchor parameter and what it changes in final placement. Order matters conceptually.
Border (b=)¶
Border changes the usable fit area around the placeholder.
- positive values expand,
- negative values shrink.
Important behavior:
bordermodifies placeholder size only for Fit Mode scaling.anchor,shift, andclipstill use the original placeholder as geometric reference.
In other words:
- border adjusts the fit area,
- fit mode computes object scale in that adjusted area,
- anchor/shift/clip are evaluated against the original placeholder.
This is why defining border first is conceptually important: it controls object size before final positioning.
Examples:
border=[-2]
border=[2 3]
border=[2 3 4 5]
object_id~[-2]i
Percent and absolute-size forms are supported:
border=[50%]
border=[125%]
border=[40x60]
border=[50%x20]
border=[23x?]
border=[?x12]
Negative WxH components can flip orientation:
border=[100%x-100%]
border=[-100%x100%]
Fit Mode¶
Fit mode defines scaling behavior relative to the (possibly border-adjusted) fit area.
If omitted, inside is the practical default.
Examples:
object_id.Fit{fitmode=inside}
object_id~i
Fit Mode Reference¶
| Code | Name | Description |
|---|---|---|
| i | inside / contain | Scales proportionally to fit entirely within the rect (default). |
| o | original / none | Keeps original size. |
| w | width-fit | Scales proportionally to match rect width. |
| h | height-fit | Scales proportionally to match rect height. |
| m | max / cover | Scales proportionally until it covers the rect, possibly overflowing. |
| x | x-stretch | Stretches width to match rect (non-proportional). |
| y | y-stretch | Stretches height to match rect (non-proportional). |
| a | all-stretch | Scales independently in X/Y to fill rect exactly. |
| t | tile | Tiles the object as a pattern within the rect. |
| b | best-fit | Smart mode that mixes m, a, and clipping for balance. |
| ? | auto-fit | Alias of b (best-fit). |
Anchor¶
Anchor selects the reference point used to align an object to the placeholder. Think of it as: "which point of the object goes to which point of the placeholder."
Anchor uses the original placeholder (not the border-adjusted fit area).
This makes anchor behavior stable and predictable while border only affects scale.
anchor = 1..9 follows numeric keypad:
7 8 9
4 5 6
1 2 3
Examples:
object_id.Fit{anchor=7}
object_id~7

If no explicit anchor is provided, center (5) is used as default.
Shift (shift= / s=)¶
Shift offsets final position after anchor/fit.
object_id.Fit{anchor=7 shift=[-100% -100%]}
object_id~i8[0 %]
object_id~i8[-50% 0]
Notes:
%is relative to placeholder size,%means100%,-%means-100%,- mixed expressions are valid (
shift=[25%+2 0]). - shift uses the original placeholder frame as reference.
Rotate (r= / ^)¶
Rotates the target object.
object_id.Fit{rotate=-42.4}
object_id~^^^
object_id~^-45i7
Mirror (m= / |)¶
Mirrors the target.
|horizontal,||vertical.
object_id.Fit{mirror=v}
object_id~||
Clip (c / !)¶
Clips outside the original placeholder shape.
object_id~i8![0 %] # pre-clip then shift
object_id~i8[0 %]! # shift then post-clip
Position of ! matters.
5.4.5 Compact Token Order (Reference)¶
When using shorthand ~, tokens are parsed in this order:
- Optional border list (
[t r b l],[x],[x y]) - Fit mode + anchor (
i7,m5,a9, etc.) - Optional shift list (
[dx dy]) - Optional clip (
!) - Optional rotation (
^deg,^^,^^^) - Optional mirror (
|,||)
5.4.6 Priority and Overrides¶
When multiple Fit-Anchor layers apply, use this precedence:
- Header defaults/global ops
- Iterator/global ops
- Item-local ops
Later layers override earlier ones for conflicting properties.
Example:
Header:
main_art-8=~[10x10]
Cell:
*[:fig(g918)~^^ :fig(g1720) :fig(g1264) :fig(g13590)]~[0%]5
Effective merge:
- start from header border,
- apply iterator-level defaults,
- apply item-level overrides last.
5.4.7 Practical Examples¶
This section intentionally groups compact real-life patterns.
5.4.8 Compact Notation (Clarifications)¶
This section consolidates the compact syntax details that usually cause confusion.
With ~ and without ~¶
For simple rotate/mirror/clip operations, ~ can be omitted:
id~^15andid^15are equivalent.id~!andid!are equivalent.id~|andid|are equivalent.id~||andid||are equivalent.
Use the ~ form when you want the full compact chain in one expression (border + fit/anchor + shift + clip + rotate + mirror).
Combined compact operations¶
You can combine these operators in one token, for example:
id~i5^^!
id^90|
id~m7[0 5%]!
Parsing and precedence reminder¶
- The compact parser still applies the same Fit-Anchor merge precedence: header defaults -> iterator/global ops -> item-local ops.
- For conflicting properties, the last layer overrides previous ones.
Example 1: Simple inside-center¶
art_id~i5
Places object inside placeholder, centered.
Example 2: Cover and clip¶
art_id~m5!
Covers placeholder area, then clips overflow to placeholder shape.
Example 3: Corner icon with offset¶
icon_id~i7[2 -2]
Inside fit, top-left anchor, then fine offset.
Example 4: Multiple objects in one cell¶
id1~7 id2~9 id3~3
Places three objects in one placeholder flow, each with its own anchor.
Example 5: Array group with local layout¶
[id1 id2 id3].L{3x1 g=2}~i5
Builds an array object, lays it out locally, then applies Fit-Anchor as one grouped target.