Function

--name(), $name()

Define a function of your own, then call it anywhere in the doodle. A call is replaced by the function's body, with the arguments in place of the parameters.

Syntax

  • --<name>(<param>, ...): <body>;
  • --<name>(<param> = <default>, ...): <body>;
  • --<name>(): { <body> }
  • $<name>(<argument>, ...)
name
Letters, digits, _, and - between words, starting with a letter or _. A call reads the whole name, so $rand-int() does not call a function named rand.
param
A name such as x, size or a_b. = value gives it a default, used when a call passes fewer arguments.
body
One statement, up to its ; or through the block it opens, or any text inside braces. In the body, $p is the argument passed for p. Inside $() and its unit forms a bare p works too, wrapped in parentheses.

A definition is a statement at the top level of the doodle, outside any block, and emits nothing. It can come before or after its calls. Each call is replaced by the body before the code is read, so a function can stand for a value, a few declarations, or elements inside @svg. Calls work in nested @doodle code too, but not inside quotes.

Without parentheses, $name is still the custom property --name, and $name(…) with no function of that name still appends a unit, as in $px(…).

Arguments are pasted as written. $f(@r(5)) draws a new random number at each place the parameter is used, so store a shared value in a custom property first. The arguments of a call are not an expression: to pass a parameter on to another function, write $p. Code inserted with @use can call the functions of the doodle, and the functions it defines stay inside it. A function that calls itself, directly or through another, is reported, and the call expands to nothing.

Examples

A value with two parameters, the second with a default:

@grid: 6 / 60vmin _2px;
--dot(r, c = #000): radial-gradient($c $r, #0000 0);
background: $dot(30%), $dot(60%, #e6437d);

Inside $() the parameter can be written without $:

@grid: 9 / 60vmin;
--wave(k): $(sin(@i / k) / 2 + .5);
background: #000;
border-radius: 50%;
scale: $wave(3);
opacity: $wave(7);

A body in braces can hold several declarations:

@grid: 7 / 60vmin _2px;
--fill(c, r): {
  background: $c;
  border-radius: $r;
}
@even { $fill(#000, 50%) }
@odd { $fill(#e6437d, 10%) }

The same works for @svg elements:

@grid: 1 / 60vmin;
--dot(r, c = #000): circle { r: $r; fill: $c }
background: @svg(
  viewBox: -10 -10 20 20;
  $dot(8) $dot(5, #e6437d) $dot(2)
);

See also