8.11 Source¶
@{...} creates a source object from an external resource (file, icon, or URL), then uses it as a renderable object in the document.
Use Source when content comes from outside the template and must be resolved at generation time.
8.11.1 Syntax¶
All three forms below are equivalent entry points into the same source resolver pipeline.
Source{source_ref} or S{source_ref} or @{source_ref}
The source_ref can be:
- a path to a local file,
- an iconify reference,
- a web URL,
- or a virtual source (Wikimedia Commons, Pixabay, Openclipart, PnPInk Assets, Google Drive).
8.11.2 Local File Sources¶
Use local files for stable, reproducible builds where assets are versioned with the project.
| Meaning | |
|---|---|
| @{ relative/or/absolute/path.png } | # Relative or absolute path |
| @{ C:\path\to\image.png } | # Windows path |
| @{ ~/images/token.png } | # Linux/macOS home path |
Equivalent local-source forms accepted in dataset cells:
| Source{path/file.ext} |
| @{path/file.ext} |
| @{file.ext} |
| @file.ext |
| file.ext |
Notes:
file.extis accepted only for known source extensions (png,jpg,jpeg,gif,bmp,webp,svg,svgz,pdf,tif,tiff).@{file.ext}orSource{file.ext}is accepted as the standard Source module form..webpinputs are converted to cached.pngfiles before SVG placement, because not every Inkscape/export pipeline handles WebP reliably.
When no path is provided (file.ext), lookup order is:
- Same folder as the SVG template.
- Asset folders beside it:
assets/,images/,img/,imgs/. - Template-named asset folders beside it:
template_name*assets/,template_name*images/,template_name*img/,template_name*imgs/. - Parent asset folders:
../assets/,../images/,../img/,../imgs/. - Runtime Python asset folders:
python_dir/assets/,python_dir/images/,python_dir/img/,python_dir/imgs/.
Local sources support environment/home expansion:
- Windows:
%USERPROFILE% - Linux/macOS:
$HOME,${HOME},~
Inline text tokens¶
Inline icons can also use local shorthand directly inside text:
| description |
|---|
| :bola.png: |
Behavior:
- If the file is found by the same lookup rules above, it is treated as a source token.
- If not found, the token is kept as normal literal text (
:bola.png:).
For complete inline-icon syntax, shared holes, Fit-Anchor placement and text transforms, see Text.
8.11.3 SVG Node Import (Optional)¶
For SVG sources only, you can target a specific node with #id:
| @{ assets/icons.svg#heart_group } |
| @{ https://example.com/icons.svg#token_1 } |
Behavior:
- without
#id: the whole SVG is linked as a final image source, - with
#id: that node is imported and embedded (including required defs/references).
8.11.4 Iconify Sources¶
Use icon sources for semantic symbols (costs, resources, status icons) without managing local files manually.
| @{ icon://icon_set/icon_name } |
Examples:
| Meaning | |
|---|---|
| @{ icon://noto/heart-suit } | # Icon from the noto set |
| @{ icon://mdi/account } | # Icon from the mdi set |
| @{ icon://cat } | # Uses default set, noto |
There is a default snippet definition mapping to the noto icon set:
:Ic(icon) -> @{ icon://noto/icon }
Notes:
- Icons are cached as SVG symbols in
<defs>. - If
iconify.pyis not available, a placeholder is created. - To force a re-download, remove the symbol from
Object > Symbols(Shift+Ctrl+Y).
Icon color¶
Add an optional color source parameter to a monochrome Iconify source:
@{icon://material-symbols-light/star?color=ffbf00}
@{icon://material-symbols-light/star?color=#ffbf00}
@{icon://material-symbols-light/star?color=darkred}
The color may be a 3, 4, 6 or 8-digit hexadecimal value, with or without its
leading #, or a CSS color name. PnPInk reuses the cached base icon and creates
the colored variant locally; it does not download the same icon again.
Multicolor sets such as noto contain explicit fills for their individual
shapes and preserve those original colors. They cannot generally be recolored
as one monochrome icon with this method.
8.11.5 Web Sources (HTTP/HTTPS)¶
Use web sources when assets are remote and can be cached at generation time.
| @{ https://... } |
| @{ http://... } |
Web sources are downloaded and cached into the assets folder next to the SVG (or project root).
If the download fails, a placeholder symbol is created.
8.11.6 Virtual Sources¶
Virtual sources map high-level search expressions to real downloadable URLs. They are useful for exploratory workflows and rapid prototyping.
PnPInk supports virtual sources that resolve to real URLs:
| @{ wkmc://query/size } |
| @{ pxby://query/size } |
| @{ oclp://query/size } |
| @{ pnp://asset_path } |
| @{ gdrive://file/file_id } |
| @{ gdrive://folder/folder_id/*.png } |
PnPInk also supports dedicated map sources:
| @{ osm://[...] } |
| @{ ofm://[...] } |
| @{ osm://madrid } |
| @{ ofm://spain/z4 } |
| @{ ofm://shikoku/t1 } |
| @{ ofm://shikoku/z8/t1 view=all-labels+water_name[bay lake] } |
| @{ ofm://asturias view=mountains smooth=3 } |
These sources generate maps from simple URLs. Map sources support /zN to force zoom and /tN to limit the automatic tile grid per axis. Use view= to choose rendered layers/features and smooth=/s= to control configured line smoothing. See Maps for details.
Placed sources can also be adjusted afterwards with Transform, for example to reduce opacity or soften edges.
wkmc://(Wikimedia Commons) supports:- search text:
wkmc://query/size - specific file:
wkmc://File:Name.ext/size - category files:
wkmc://Category:Name/size pxby://(Pixabay) supports:- normal search list:
pxby://query/size - direct lookup for no-space query when possible (single hit / id).
oclp://(Openclipart) supports:- normal search list:
oclp://query/size - specific image by id/detail:
oclp://id:12345/size(resolved internally viahttps://openclipart.org/detail/12345/...) pnp://(PnPInk Assets) supports:- direct asset path:
pnp://birds/egg1 - default
.pngextension when omitted - friendly numeric fallback:
pnp://birds/egg-> first matching numbered asset such asegg1.png - optional global lookup when the name is unambiguous:
pnp://egg gdrive://(Google Drive) supports public shared files/folders:- file by id:
gdrive://file/file_id - folder listing by id:
gdrive://folder/folder_id/*.png - folder paths:
gdrive://folder/folder_id/Artworks/used/card.png - real Drive URLs:
https://drive.google.com/file/d/file_id/...andhttps://drive.google.com/drive/folders/folder_id - folder listing requires
gdrive_api_keyinpreferences.ini
Size accepts:
- presets:
tiny,small,medium,large,xlarge,largest - vector mode:
svg(when available from the provider) - minimum side:
N(example:1000) - minimum width+height:
WxH(example:1000x1000)
Examples:
| @{ wkmc://"The Ancestral Homes of Britain"/large } |
| @{ wkmc://"File:Complete_Saxonian_deck.jpg"/1000 } |
| @{ wkmc://"Category:Complete_decks_of_playing_cards_laid_out"/1000x1000 } |
| @{ pxby://castle/1200 } |
| @{ oclp://wolf/large } |
| @{ oclp://id:24829/largest } |
| @{ pnp://birds/egg } |
| @{ pnp://IA/icons/crown1 } |
| @{ gdrive://file/1AbCdEf... } |
| @{ gdrive://folder/1AbCdEf.../*.png } |
| @{ gdrive://folder/1AbCdEf.../Artworks/used/card.png } |
Multiple-result virtual sources can be selected outside the source with a 1-based selector:
| @{ wkmc://"The Ancestral Homes of Britain"/medium }[2 4..12 15..26] |
| *@{ pxby://castle/large }[1..20] |
| @{ gdrive://folder/1AbCdEf.../.png }[1..20] |
Selector notes:
- indices are 1-based,
- out-of-range indices are ignored with warning,
- without selector, if multiple results exist, the first one is used (warning in log).
- for
wkmc://, category/search results keep the API order after size filtering; PnPInk does not reorder them by image dimensions.
Google Drive notes:
- Only public/shared resources are supported. Private folders require OAuth and are not handled here.
gdrive://file/...downloads a single file and caches it locally.gdrive://folder/...lists the public folder, filters by name/glob, then downloads selected files.- Folder path segments are resolved as real Drive folders, not as slash characters in the file name.
- Cached downloads are stored in the same
assetscache used by other web sources. - Folder listings are cached per run, and file downloads are prefetched in parallel using
network_workers_gdrivefrompreferences.ini(default:8).
Wikimedia Commons category catalogs:
- each
wkmc://Category:...source found in the dataset creates an internal 0-based catalog variable: - first category:
_wkmcc1 - second category:
_wkmcc2 - each item exposes the useful fields returned by Commons:
titleurlthumburl
| ${_wkmcc1[0].title} |
| ${_wkmcc1[0].url} |
| ${_wkmcc1[0].thumburl} |
| @{ wkmc://${_wkmcc1[0].title}/1000 } |
| @{ ${_wkmcc1[0].thumburl} } |
pnp:// PnPInk Assets¶
pnp:// resolves against the public pnpink-assets index generated on push.
It is meant for small reusable art pieces that can be placed automatically from a dataset without downloading them into every project.
Resolution rules are intentionally simple:
- if you provide a full asset stem, it is used directly,
- if you omit the extension,
.pngis assumed, - if you omit the numeric suffix, PnPInk tries the lowest matching numbered asset,
- if you omit the folder, PnPInk tries a global lookup and warns if the name is ambiguous.
Examples:
| Meaning | |
|---|---|
| @{ pnp://egg } | # May resolve to birds/egg1.png |
| @{ pnp://birds/egg } | # Resolves within the birds collection |
| @{ pnp://IA/icons/crown1 } | # Direct asset path |
The source behaves like any other image source, so it can be combined with Fit-Anchor and Transform:
| @{ pnp://egg }~i7 |
| @{ pnp://birds/egg3 }.T{o=80%}~[110%]8! |
8.11.7 Fit and Placement Behavior¶
After resolution, a source behaves like any other placeable target in Fit/Anchor terms.
A Source is treated as a final placeable object, so you can apply Fit/Anchor operations exactly as with other objects.
8.11.8 Internal Model¶
This internal model is important for performance and file size on large projects.
Sources are instantiated as clones of symbols (<use>), not inline geometry copies.
This keeps the SVG compact and avoids repeating heavy geometry.
8.11.9 Spritesheets (@)¶
Spritesheets allow one asset to provide many addressable frames. This is useful for token sheets, icon atlases, and catalog-like image packs.
The Layout module can also be applied to composite sources, such as spritesheets.
Example definition inside a comment block (before the dataset):
| Comment/directive row |
|---|
| # @sp1 = @{sheet.png}.Layout{p=3x2^ s=poker g=[4 3]} |
This creates a spritesheet from sheet.png with a 3x2 grid of poker-sized cards, spaced 4 mm horizontally and 3 mm vertically.
Then, you can reference any frame in the dataset as:
| Meaning | |
|---|---|
| @sp1[5] | # Linear frame 5 on page 1 |
| @sp1[B3] | # Column B, row 3 on page 1 |
| @sp1[3!B4] | # PDF page 3, column B, row 4 |
| @sp1[B3:C5] | # Rectangular range |
| @sp1[B4..C6] | # Linear walk following the spritesheet layout order |
| @sp1[A4 B2 A1] | # Explicit unordered list selector |
| @sp1[2!B2:C4 3!C4] | # Combined rectangle and cell selectors on specific PDF pages |
| @sp1[2!B2..5!C1] | # Linear walk across PDF pages, including both endpoints |
(^ in the grid reverses numbering direction: first rows, then columns.)
Selectors separated by spaces are combined in the written order. Prefix the complete
source with * to generate one dataset instance per selected frame, for example
*@sp1[2!B2:C4 3!C4 5!A2..6!D4]. A : range is rectangular and stays on one page;
a .. range follows layout order and may cross page boundaries.
This spritesheet can be used as a source in any dataset, positioned with Fit parameters (e.g. ~i6) as any other target.
For PDF spritesheets, keep the PDF itself in the definition. PnPInk creates and reuses
<pdf-name>.page-N.png files under the project assets when a referenced page is needed.
Each page PNG uses the highest effective DPI of the raster images placed on that PDF
page, and never less than 300 DPI. The page prefix is optional: B4 means 1!B4.
Notes:
- Alias definitions are read from comment lines before dataset rows.
- Frame selectors are 1-based.
- If a frame is out of range, a warning is logged and placement is skipped.