pic

Created: 08 Apr 2025
Updated: 23 Apr 2025
1984 pic wiki doc ps Brian Kernighan(42)
1995 gpic source pdf html png James J. Clark
2008 dpic home source doc online svg Dwight Aplevich
2020 pikchr home source doc online svg Richard Hipp

cli

$ pic foo.pic | groff -ms | ps2es | gs -dBATCH -sOutputFile ...
$ pic foo.pic | groff -ms > hello.ps
$ pic -p foo.pic > hello.ps
$ dpic -v foo.pic > foo.svg
  • -ms on groff will use defaults of .PS/.PE, will center drawing
-t LaTeX output

language

Eat:   ellipse "eat"
       arc ->
Work:  ellipse "work"
       move down from Eat.sw then right
Sleep: ellipse "sleep"
       arc cw -> from Work.s to Sleep.e
       arc cw -> rad 0 from Sleep.w to Eat.s
pic-life.svg
  • by default draws from left to right
    • changes when you put a direction (up/down/left/right)
    • from then on it becomes the new one
    • with the entrypoint of the new one attached to the exitpoint of the last
  • use {} to preserve/restore position and direction after the block is finished
  • optional ";" to end statements
  • use "#" to start comments
  • one line statements, can be separated into multiple lines with "\"
  • coordinates: x=rightward y=upward
  • first object put at 0,0
  • default unit is inches
    • use scale=2.54 to change it to centimeters
    • use scale=25.5 to change it to millimiters

blocks

  • use [] to defines a block, which can be later threated as a single object
    • defines a "bounding box" for its content
    • referenced as just "[]"
    • labels & variables are local to it
    • internal labels can be used
      • in "with" positioning outside
      • or directly "[].A"

roff commands

.PS [W] [H] start of pic, with optional width and height
.PS <file.pic  
.PE   end of pic
.ft [RBIP] switch font shape, P=previous
.ps , N, +N change font size, thickness, previous, new, or relative
.fam [TH] changes font family T=Times, H=Helvetica

labels

  • start with upper-case
  • a object can be labeled
    • refers the center of the object
  • a position can be labeled

    A: ( 0, sqrt(3/4) )
    
  • can be reset

    Box1: Box1 + 1,1
    

control flow

 if i == 0 then { }
 if i == 0 then { } else { }
for i=0 to 5 do { }
for i=0 to 5 by 0.1 do { }
for i=0 to 5 by *0.1 do { }

macros

  • non existing arguments are replaced by nulls strings
  • remove a definition with undef
  • arguments inside macro replaced with $1,$2,…
define treecolor % color "green" %
define smiley {
  r0 = $3
  r1 = 0.4*r0
  r2 = 0.04*r0
  ...
}
pi2 = 2*atan2( 0, -1 )
for x=0.1 to 1.3 by 0.08 do {
  smiley( 1.5*x*cos(x*pi2), 1.1*x*sin(x*pi2), 0.23*x )
}

commands

primitive objects - planar & linear

box 0.75 x 0.5  
circle 0.25 r  
ellipse 0.75 x 0.5  
oval   pikchr
diamond   pikchr
file   pikchr
cylinder   pikchr
dot   pikchr
line 1/2" a/t/b
arrow 1/2" a/t/b - synonym for "line ->"
spline    
arc 1/2"R 90° anti-clockwise
arc cw 1/2"R 90° clockwise
move 1/2" moves in current direction
"foo"   troff text

a/t/b = above top below, where the given strings will be put

attributes - cosmetic

above - for text, can stack
below - for text, can stack
[rl]just - for text, can stack
h[eigh]t 1  
wid[th] 1  
same - same dimensions as previous one
rad 1 box with rounded corners
dotted 0/1 for line/box
dashed 0/1 for line/box
<-> - double arrow for line/arc
-> - sinle arrow for line/arc
fill 1 gray intensity for box/circle/ellipse
color 1  
invis - invisible
shaded 1 DPIC, take a rgbstring()
outlined 1 DPIC, take a rgbstring()
thick[ness] 1 DPIC + GPIC
l[ine]thick 1 DPIC + GPIC
italic - pikchr
bold - pikchr
small - pikchr
big - pikchr

object dot(.) modifiers

.[x¦y]  
.[ns][we] objects corners / compass points
.wid[th]/.h[eigh]t  
.rad[ius]/.diameter  
.start/.center/.end for line,arrow,spline

a position can be

(X,Y) a coordinate
(POS1,POS2) sugar for (POS1.x,POS2.y)
OBJ + (X,Y) relative to another object
Here literal for the current position
[1st¦2nd] [last] ASHAPE  
ALABEL if object, it refers to its .center
f<p1,p2> interpolation by "f" between "p1" and "p2"
f [of the way] between p1 and p2 "

attributes - others

  • reset - reset all variables or given ones
  • sh {CMD} - runs arbitrary shell command, supports redirections
  • copy "file.txt" [thru MACRO] - includes pic file, ignores .PS/.PE lines
    • eg: a file with lines like "A: (0.2,0.5)"
    • thru MACRO makes it runs given macro with each line field as argument
  • copy "file.txt" thru { … }
    • you can give a literal macro
  • copy thru MACRO
    • runs it with all the following lines (me: a "here strings" of sorts)
  • up 0.1 right 0.2 == + 0.2,0.1
  • top/bottom/left/right - same as north/south/west/east
  • "\D'P 1 1 1 -1'" - drawing a filled (P) triangle with troff
  • LINEAR
    • [udlr] DIST [ [udlr] DIST ] [then…]
    • from POSITION [then…] to POSITION [chop [N] [chop N]]
      • "[then]" defines segments of a path
        • [udlr] DIST [ [udlr] DIST ] [then…]
      • chop - chops line by radius around object
  • PLANAR & LINEAR
    • [with .[ns][we]] at POSITION - define where to put the center of shape
    • move
      • NUMBER - inches in the current default direction
      • same - uses the same argument of last "move"
      • to POSITION
      • [udlr] DIST [ [udlr] DIST ] [then…]
        • then [udlr] N [ [udlr] N ] - define a path
    • by POSITION - attachment position UNDOCUMENTED

stdlib functions

sin(E) in radians cos(E) in radians
atan2(y,x) in radians sqrt(E) -
log(E) in base 10 exp(E) in base 10
max(E,E) - min(E,E) -
int(E) - sprintf(F,..) F=format
  • E=expr

default variables sizes

boxwid 0.75 boxht 0.5
linewid 0.75 lineht 0.5
circlerad 0.25 arcrad 0.25
ellipsewid 0.75 ellispseht 0.5
movewid 0.75 moveht 0.5
textwid 0 textht 0
arrowwid 0.05 arrowht 0.1
dashwid 0.05 arrowhead 2
maxpswid 11 maxpsht 8.5
fillval 0.3 scale 1
  • maxps*, for max picture dimensions
  • arrowhead, changes the head style
  • use fillval command, smaller values are darker
  • use reset command, to reset all variables values, or given ones

codebases

snippets

  • tree drawing macro

    define tree %
        line down 0.25i
        { line right 0.15i; move right 0.2i; "$1" ljust }
    %
    

tools

ps2eps   converts postscript to encapsulated postscript
eps[to]pdf   converts eps to pdf
pic2svg source  
org-mode source  

pic2graph

$ pic2graph < foo.me > foo.png
$ sed '1d,$d' foo.pic | pic2graph -background white -alpha remove -alpha off -border 10 -bordercolor white > foo.png
  • converts a PIC given in stdin program to PNG
  • must NOT have a .PS/.PE
  • flags are passed down to ImageMagick's convert
  • remove transparency by default

    -background white -alpha remove -alpha off
    
  • add additional border space

    -border 10 -bordercolor white
    
  • use the full page canvas

    -flatten
    

implementations

pikchr

dpic

pic-dpic.png
Figure 1: dpic output formats

articles

videos