Skip to content

12 Snippets

Snippets are short calls that PnPInk expands into reusable text or DSL fragments before it renders a dataset cell. They keep repeated patterns readable and let a project build its own compact vocabulary.

Before defining snippets

This reference assumes you know how dataset headers and cells (connect data to SVG) work. For the built-in rich-text helpers, first read Text (style text with helpers). You can use those helpers without learning how to define a snippet.

12.1 What Snippets Are

Snippets are a compact mini-language inside PnPInk. A short alias can expand into plain text, SVG-rich text, a path, a source URL, a style fragment, or another reusable token pattern.

Snippets are always processed first, immediately after DeckMaker reads dataset values and before normal variable substitution.

PnPInk tip: start with a real repetition

Do not create snippets for every short expression. Start with a pattern repeated across several rows, give it a clear name, and keep its call easier to read than the fragment it replaces.

12.2 Syntax

This section defines the only supported definition format in the current engine.

Define snippets in comment lines:

# :Name(arg1 arg2=default) = template text

Rules from the current engine:

  • No space is allowed between snippet name and (.
  • Parameters are space-separated.
  • Defaults use name=value.
  • The replacement template is plain text after =.
  • Old -> definitions are not supported.

Call syntax:

:Name(value1 value2)

12.3 Arguments and Expansion

Argument mapping rules are what make snippets usable in real datasets.

Snippets support positional args, named args, defaults, and nesting.

# :Join(a b) = ${a}/${b}
# :TF(text font size) = <tspan font-family='${font}'${size? font-size='${size}'}>${text}</tspan>

:Join(cards heroes)                -> cards/heroes
:TF(Title Noto 16px)               -> <tspan font-family='Noto' font-size='16px'>Title</tspan>
:TF(Title Noto)                    -> <tspan font-family='Noto'>Title</tspan>
:TF(text=Title font=Noto size=12)  -> named arguments are valid

Conditional blocks use ${var? true} and render only when var is non-empty. They can also use ${var? true : false} for fallback text.

If a snippet has exactly one parameter, that parameter captures the full inner text:

# :Bold(text) = <b>${text}</b>
:Bold(This is bold text) -> <b>This is bold text</b>

12.4 Defaults and Optional Parts

Default values are used when a parameter is omitted.

# :Box(text color=black) = <rect stroke='${color}'/><text>${text}</text>

:Box(Title)     -> <rect stroke='black'/><text>Title</text>
:Box(Title red) -> <rect stroke='red'/><text>Title</text>

12.5 Quoting, Spaces, and Escaping

  • Parameters containing spaces must use quotes.
  • Use \: to keep a call literal.
  • If a snippet does not exist, the call stays literal.
  • If a call is malformed, it stays literal.
:Join("My Folder" file.svg) -> My Folder/file.svg
\:Join(a b)                  -> :Join(a b)

12.6 Nesting

Snippets can call other snippets and are expanded inside-out.

# :B(text) = <b>${text}</b>
# :C(text color) = <span fill='${color}'>${text}</span>

:C(:B(Name) red) -> <span fill='red'><b>Name</b></span>

12.7 SVG Text Helpers

PnPInk's default rich-text helpers turn calls such as :TB(...), :TC(...) and :TM(...) into normal SVG <tspan> markup. Their purpose, combinations and expanded forms are documented with the rest of the text workflow in Text. This page remains the reference for defining your own snippets, passing bracketed multi-value arguments, nesting calls and using conditionals.

12.8 Processing Order

Processing order matters when snippets and ${var} are combined in the same cell.

For each dataset cell:

  1. Snippets are expanded.
  2. ${var} replacements are applied.
  3. DSL placement and rendering run.

12.9 Variable Expressions

${...} placeholders are resolved after snippets. The expression may contain any text except nested braces, so the syntax remains open for future extensions.

Currently supported forms are intentionally small and predictable:

${name}
${name[0]}
${name[0].field}

This is mostly useful with internal variables created by sources, such as Wikimedia Commons category catalogs:

${_wkmcc1[0].title}
${_wkmcc1[0].url}
${_wkmcc1[0].thumburl}

Unsupported expressions resolve to an empty string instead of stopping the render.

12.10 Summary Table

Concept Syntax Example Result
Definition # :Name(a b=def) = text # :Hello(name) = Hi ${name} defines snippet
Use :Hello(World) Hi World
Default param=value # :Box(t color=red) uses red if omitted
Conditional ${p? text} ${size? font-size='${size}'} adds only if defined
Escape \Name() prevents expansion
Nested :A(:B(x)) inner first
One parameter :Bold(any text) captures all
Quoted values :Join("My Folder" file) handles spaces

12.11 Design Principles

  • Consistent: follows the same spacing and escaping rules as the rest of PnPInk.
  • Readable: complex SVG text becomes short and maintainable.
  • Composable: snippets can be nested and combined incrementally.
  • Deterministic: plain text substitution rules, no runtime scripting.