PostScript

I’ve played with PostScript this week. PostScript is a page description language developed by Adobe in the 1970’s and 1980’s, and a precursor of PDF.

PostScript is a programming language. It’s stack-based, which means that the state of the program is represented in a single data structure, the stack. All the operations take their parameters from the top of the stack and put their return values back on top of it.

For example, to calculate 0.5 * ((7 * 6) + 42), you type this:

0.5 7 6 mul 42 add mul

Or, with comments:

0.5    % push 0.5 on stack
7      % push 7 on stack
6      % push 6 on stack
mul    % replace 7 and 6 with their product
42     % push 42 on stack
add    % replace 42 and 42 with ther sum
mul    % replace 0.5 and 42 with their product

Actually, I lied when I said that the whole state goes in the stack. In addition to stack, there is a data structure called dictionary that works like a hash table and becomes very handy to make programs more readable. You can put values into the dictionary with def command. You can later recall them with the name you gave them.

/the_answer_to_life_the_universe_and_everything 42 def
% Slash in the front of a token name means the
% token is not executed, but instead it's name is
% pushed on the stack. So, def takes two parameters
% a token name and a value and puts them on
% the dictionary as a (key, value) pair.

the_answer_to_life_the_universe_and_everything 5 mul
% 42*5 = 210

The real value of the dictionary is that you can define functions in it. You do this by specifying code blocks and putting them into the dictionary. Whenever a code block is recalled from the dictionary, it is immediately executed.

/square {
  dup mul
} def

the_answer_to_life_the_universe_and_everything square
% 42*42 = 1764

To actually print the results of these examples, you would use some of the many drawing commands of Postscript. E.g.

% Set the font to 20pt Courier.
/Courier findfont 20 scalefont setfont
% Set the starting location to near the upper left corner.
42 750 moveto

% Define a helper function.
/output_result {
  100 string % Create a placeholder string (length 100).
  cvs % Convert the operand on top of the stack to string.
  show % Output the string.
  (, ) show % Output a comma.
} def

0.5 7 6 mul 42 add mul
output_result

/the_answer_to_life_the_universe_and_everything 42 def
the_answer_to_life_the_universe_and_everything 5 mul
output_result

/square {
  dup mul
} def
the_answer_to_life_the_universe_and_everything square
output_result

This is a complete postscript program, so you can save it to a file with a .ps ending, open it with a postscript viewer, and see what it looks like.

A fun thing in PostScript is that almost anything besides whitespace can be a name. For example, you can give a definition to the asterisk:

/* {
  1 add
} def

0 * * * * * % five

Using this feature, I created a PostScript file that renders ASCII go boards. It turns this:

=========================================
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . + . . . . . + . . . . . + . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . + . . . . . + . . . . . + . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . x . . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
= . . . x . . . . . + . . . . . + . . . |
= . x x o . o . . o . . . . . . . . . . |
= . x o o . . . . . . . . . . . . . . . |
= . . . . . . . . . . . . . . . . . . . |
========================================+

into this:

postscript_go_grab2.gif

Here’s the code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s