| 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 |
- 1984 (in unix v8), 1988 (released)
- a troff preprocessor, it passes most of its input untouched
- a procedural programming language
- "intended for the comfort of non-programmers"
- inspired by ideal, PICTURE, v(iewgraph), grap
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
- 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.54to change it to centimeters - use
scale=25.5to change it to millimiters
- use
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 |
roff escape
| \D'P 1 1 1 -1' | drawing a filled (P) triangle with troff |
| \fR, \f1 | roman font (default) |
| \fI, \f2 | italic font |
| \fB, \f3 | bold font |
| \fP | revert prev style |
| \h | horizontal motion |
| \v | vertical motion |
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 | |
| -> | single 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() |
| [xy]slanted | 1 | GPIC |
| 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]/.diam[eter] | |
| .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 |
| [up¦down] N | OBJ + (0,±N) |
| [right¦left] N | OBJ + (±N,0) |
| 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)
- top/bottom/left/right - alias for north/south/west/east
- 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
- "[then]" defines segments of a path
- 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 positionUNDOCUMENTED
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
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
- https://pikchr.org/home/doc/trunk/doc/differences.md
- modern pic's replacement
- drops support for loops
- drops support for conditionals
- emacs org mode for pikchr https://github.com/kljohann/pikchr-mode
dpic