Variables & macros
pic is a real little language: variables, arithmetic, macros, loops and conditionals — all in service of describing pictures.
Environment variables
Every default is a variable you can set: boxwid, boxht, circlerad,
linewid, arrowht, textht, linethick, fillval, scale and
friends. Assignments take effect for everything drawn afterwards.
.PS
boxht = 0.4
box "default"
move
boxwid = 0.62; linethick = 1.8
box "custom"
move
box "same"
.PEVariables are global — an assignment inside a block or macro propagates out, exactly as in dpic.
Expressions
Full arithmetic with + - * / %, comparisons, and the builtin functions
sqrt sin cos atan2 log exp int max min rand:
.PS
n = 6
for i = 0 to n-1 do {
circle rad 0.09 at (0.55*cos(i*6.2832/n), 0.55*sin(i*6.2832/n))
}
.PEdefine
Macros take up to nine arguments ($1…$9) and expand inline — they are
the reuse mechanism for geometry and for styles:
.PS
define node { circle rad 0.2 $1 shaded "honeydew" outlined "darkgreen" }
define warn { outlined "firebrick" dashed }
node("a"); arrow; node("b"); arrow
box "c" wid 0.45 ht 0.4 warn()
.PEfor and if
.PS
for i = 1 to 4 do {
box wid 0.4 ht 0.3 sprintf("%g", i)
if i < 4 then { arrow right 0.35 }
}
.PEfor … by * step multiplies instead of adding — handy for log scales.
sprintf and print
sprintf formats numbers into strings for labels; print writes to the
diagnostic stream (stderr in the CLI) — the classic debugging tool.
.PS
x = sqrt(2)
box sprintf("sqrt(2) = %.4f", x) wid 1.5
.PEcopy
copy "file.pic" includes another file — how the circuit corpus shares its
macro shim. Paths resolve relative to the source file.
Where to go next
- Blocks — grouping a sub-picture into a single object