Skip to content
PostScript language

PostScript language

PostScript is a stack-based, Turing-complete page description language. Numbers and names are pushed onto the stack; operators consume and produce stack items.


Hello world

%!PS
/Helvetica 20 selectfont
70 700 moveto
(Hello world!) show
showpage

% starts a comment. Names are preceded by /. Strings are in ().


Arithmetic (reverse Polish notation)

780 120 sub 2 div       % (780-120)/2 = 330
/a 4 def /b 3 def
a b mul                 % 4*3 = 12
a dup mul b dup mul add sqrt  % sqrt(a^2+b^2) = 5

Stack operators

pop           % A B C  →  A B
2 copy        % A B C  →  A B C B C
exch          % A B C  →  A C B
5 2 roll      % A B C D E F  →  A E F B C D  (5 elements, 2 right-shifts)
dup ==        % duplicate top and print it (for debugging)

User-defined functions

/polar2xy {    % r phi  |  x y
  /phi exch def
  /r   exch def
  r phi cos mul
  r phi sin mul
} def

7 36 polar2xy  % yields 7*cos(36°)  7*sin(36°)

Note: PostScript has a single global namespace. Name clashes in functions require unique prefixes (e.g. polar2xy_phi), or revert to stack operations to avoid defining variables.


Drawing

PostScript drawing examples — rectangle, rotated text, arcs, filled shape
% A rectangle
20 20 moveto 400 0 rlineto 0 120 rlineto -400 0 rlineto stroke

% Colored rotated text
1 0 0 setrgbcolor
/Helvetica 24 selectfont
30 30 moveto
gsave 30 rotate (Hello world!) show grestore

% Arcs
0 .5 0 setrgbcolor  10 setlinewidth
newpath
210 80 45   0 270 arc     % clockwise arc
210 80 30 270   0 arcn    % counter-clockwise arc
stroke

% Filled shape
0 0 1 setrgbcolor
340 80 2 copy moveto 40 20 340 arc closepath fill

Conditionals and loops

x 0 gt { (positive) show } { (non-positive) show } ifelse
5 { (hello) show } repeat
0 1 9 { 2 mul = } for       % prints 0 2 4 6 8 10 12 14 16 18

Plot frame (axis definitions)

After ecu, Frida writes the coordinate transforms:

0 -20 20 xSetCoord     % log=0, lower=-20, upper=20
0   0 40 ySetCoord

The axis definitions follow:

/xPlotFrame {
  [ 1.875 {(-20)}  5.0 {(0)}  8.125 {(20)} ] SetTacVec
  -1.25 11.25 5 4 SetTicVecLin
  {(E  (ueV))} % axis label
  0 10 0  0  0  90 OneAxx Axx Tic Tac xNumL   %% bottom x axis
  0 10 0 10  0 270 OneAxx Axx Tic Tac          %% top x axis
  xCL
} def
  • SetTacVec — major tick positions and number labels
  • SetTicVecLin — minor and major tick spacing (here: 5 major × 4 minor)
  • OneAxx — defines one axis (internal coords, origin, length, angle)
  • Axx Tic Tac — draw axis, small ticks, large ticks
  • xNumL — number labels below bottom axis
  • xCL / yCL — axis labels

Extended string format

Frida’s PostScript macros use an extended string format for axis labels, legends, and annotations. Strings are wrapped in curly braces: {(text)}.

String operators

Operator Effect Example Output
g switch to Symbol font (Greek) {(x=2)(p)g(/3)} x=2π/3
sb subscript {(E)(f)sb( - E)(i)sb()} E_f − E_i
sp superscript {(mc)(2)sp()} mc²
sbgr Greek subscript {(K)(a)sbgr()} K_α
spgr Greek superscript {(n)(3-)sp()(h)spgr()} n^(3−η)

The Symbol font maps Latin letters to Greek: a→α, b→β, g→γ, d→δ, e→ε, h→η, p→π, q→θ, w→ω, etc.

Latin characters (top) and corresponding Greek characters in Symbol font (bottom)

Some characters occupy the same position in both fonts — digits, punctuation, and basic operators — so they need no font switch:

Characters at equal positions in Helvetica and Symbol font

A few keyboard symbols map to different characters in the Symbol font — watch out for these:

Keyboard symbols in Helvetica (top) that differ in the Symbol font (bottom)

Many more Symbol-font characters are reachable via octal codes, e.g. \261 for ±, \260 for °:

Symbol-font characters accessible through octal codes

Standard latin-encoded fonts also contain accented letters and extra symbols via octal codes, e.g. \265 for μ, \305ngstr\366m for Ångström:

Helvetica characters accessible through octal codes

QENS macros

Macro Output
hbar
hbarw ℏω
Sqw S(q,ω)
ueV μeV
inueV (μeV)
inueVr (μeV)⁻¹
inmeVr (meV)⁻¹
Angr Å⁻¹
inAngr (Å⁻¹)
taumean τ̄

Combine macros: {()Sqw( )inueVr()} → S(q,ω) (μeV)⁻¹

Escaping parentheses

Unmatched parentheses must be escaped with \:

  • To typeset f(Δx): {(f \()(D)g(x\))}

Text placement

21 setown                              % set font size
x y {(centered text)} textCM          % center-middle aligned
x y {(left text)} textLB              % left-bottom aligned
x y 60 {(rotated 60deg)} rtextCM      % rotated

Alignment codes: first letter = horizontal (L, C, R); second letter = vertical (B, M, T).


Legends

2 8 21 1.8 NewList              % x y fontsize linespacing
{(q = 1.2 )Angr()} TxLine      % comment line
1 {(  4 K)} PtTxLine            % data line with plot symbol 1
2 {(200 K)} PtTxLine
3 {(240 K)} PtTxLine

TxLine inserts a text-only line; PtTxLine adds a plot-style sample.

Plot legend with rounded-corner frame

Frames

.5 [] lset
1.8 4.4 4.4 8.6 .1 { stroke } execOval2    % rounded-corner frame
1.8 4.4 4.4 8.6    { stroke } execRectangle2  % sharp-corner frame

Arguments: x_bottom x_top y_left y_right [corner_radius] procedure.