Reusable Blocks with use(name)

use(name) allows you to define a visual or interactive structure once and reuse it anywhere in the score or on any page. This avoids copy/paste in Inkscape and keeps layouts consistent.

Defining a Reusable Block

Any SVG group whose ID begins with:

reuse-

is treated as a reusable block.

Example:

<g id="reuse-mainMenu">
   <!-- Buttons, text, shapes, animations -->
</g>

This block is registered automatically when its SVG is loaded.


Using the Block Elsewhere

To insert the reusable block somewhere else, place a placeholder group:

<g id="use(mainMenu)"></g>

When the score initializes, the placeholder is replaced with a cloned instance of the reusable block, preserving:

The placeholder itself is removed.


Placement Modes

There are two placement modes depending on how use() is written:

Syntax Placement Behaviour
use(name) Inserts the block at its original authored coordinates (as designed in its source SVG).
use(name)@self Inserts the block at the location of the placeholder, inheriting the placeholder’s transform.

Example (@self Placement)

<g transform="translate(300,200)">
  <g id="use(mainMenu)@self"></g>
</g>

Result: mainMenu appears exactly at (300,200).


Behaviour and Guarantees


Summary

Define once:

<g id="reuse-name">…</g>

Use anywhere:

<g id="use(name)"></g>

Or place at placeholder position:

<g id="use(name)@self"></g>

This system keeps Oscilla scores modular, clean, and visually authored directly in Inkscape—no handwritten layout code required.


Folders of fragments — use(path:...)

A block does not have to live inside a score. use(path:...) pulls whole SVG files out of the project's blocks/ folder and inlines them:

use(path:gestures)                          the first file
use(path:gestures, index:2)                 the third file (0-based)
use(path:gestures, index:rand(0,3))         a different one every load
use(path:gestures, index:Pseq(0,1,2,inf))   stepped across placeholders

Put the files anywhere under blocks/ in the project directory:

myscore/
  score.svg
  blocks/
    gestures/
      spin.svg
      pulse.svg
      turn.svg

The files are listed in name order, and index: selects one. An index past the end wraps rather than failing, so removing a file cannot blank a score that indexed past it.

The fragments are score, not pictures

This is the difference from image(path:...), which also accepts a folder of SVGs. image() renders a file through <image href> — a replaced element, whose content never enters the document. Any cue DSL inside it is invisible and nothing in it can animate.

use() inlines the file. Its cues are ordinary cues from that moment on:

<!-- blocks/gestures/spin.svg -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="160" viewBox="0 0 200 160">
  <rect id="fragSpin" data-oscilla="rotate(uid:fragSpin, dur:4)"
        x="70" y="40" width="60" height="60" fill="#2980b9"/>
</svg>

Dropped into a score with use(path:gestures), that rectangle spins like any other rotate().

Note where the cue lives. Typing it into the id is the Inkscape shortcut and Oscilla still reads it, but a fragment is written once and inlined many times — so an id carrying the DSL is repeated verbatim into every copy, and ids are meant to be unique. Anything generated by a tool should write data-oscilla and leave the id as the plain uid:. See authoring.

Expansion happens before cue assignment, so a fragment's cues are picked up on the same pass as the rest of the score.

Each fragment is inserted as a nested <svg> sized to the placeholder, so it keeps its own coordinate system — author the file at whatever size suits it and its viewBox scales it into the slot.

A trailing bare number is a repeat count, not an index. Prand(0,1,2) means "0 and 1, twice" in every pattern in the DSL, and quietly drops the 2. Write Prand(0,1,2,inf) to choose between all three. Oscilla warns when it sees a repeat count on a use() index, since it is almost never meant.

Limits


Demo

See demo-reuse — one navigation menu written once and injected into every page.

http://localhost:8001/?project=demo-reuse

Tip: use ← → or ↑ ↓ to navigate the docs