Skip to content

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.ext is accepted only for known source extensions (png, jpg, jpeg, gif, bmp, webp, svg, svgz, pdf, tif, tiff).
  • @{file.ext} or Source{file.ext} is accepted as the standard Source module form.
  • .webp inputs are converted to cached .png files before SVG placement, because not every Inkscape/export pipeline handles WebP reliably.

When no path is provided (file.ext), lookup order is:

  1. Same folder as the SVG template.
  2. Asset folders beside it: assets/, images/, img/, imgs/.
  3. Template-named asset folders beside it: template_name*assets/, template_name*images/, template_name*img/, template_name*imgs/.
  4. Parent asset folders: ../assets/, ../images/, ../img/, ../imgs/.
  5. 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.py is 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 via https://openclipart.org/detail/12345/...)
  • pnp:// (PnPInk Assets) supports:
  • direct asset path: pnp://birds/egg1
  • default .png extension when omitted
  • friendly numeric fallback: pnp://birds/egg -> first matching numbered asset such as egg1.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/... and https://drive.google.com/drive/folders/folder_id
  • folder listing requires gdrive_api_key in preferences.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 assets cache used by other web sources.
  • Folder listings are cached per run, and file downloads are prefetched in parallel using network_workers_gdrive from preferences.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:
  • title
  • url
  • thumburl
${_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, .png is 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.