Lab 4: pic and PostScript

Overview

Over the next two weeks, we will implement a program that translates between two programming languages, each designed to draw pictures:

  • The pic language is easy for people to read and write and lets us describe diagrams as a collection of shapes and arrows (think: flowcharts).

  • The PostScript (PS) language is primarily designed to be a portable way to describe documents that can be printed and displayed.

A translator (i.e., compiler) between these two languages gives us the best of both worlds: a programmer can write a high-level description of certain kinds of diagrams, them compile them into PostScript files, which can be displayed and printed on all kinds of devices.

Before we can write a compiler from pic to PS, we first must understand these languages. Thus, the purpose of this lab is to learn about pic and PS, by writing programs in each of these languages.

In the assignment, you will write an evaluator that takes as input an AST for pic and produces as output a PostScript file.

Materials

Use the assignment workflow and the link provided on Piazza to get access to this week’s files.

Do the lab on knuth

For this lab, you need to work on knuth. You can use VS Code with RemoteSSH, or ssh to knuth with the -Y flag (ssh -Y username@knuth.cs.hmc.edu) from a laptop with X-Windows installed.

Set up your environment to work with images

We will make use of a set of programs collectively known as ImageMagick. To do so, we need to set up a configuration file.

(Note: There is a small chance that you already have a configuration file. The commands below should not break anything with your existing configuration. But if you already have a file named ~/.config/ImageMagick/policy.xml, check with the course staff before running these commands.)

On knuth, run the following commands, which will allow you to convert from PostScript files to other files (such as images):

  mkdir -p ~/.config/ImageMagick
  cd ~/.config/ImageMagick
  touch policy.xml
  echo '<policy domain="coder" rights="read | write" pattern="PS" />' >> policy.xml
  cd -

Practice Writing pic Code (20 minutes)

The pic language is a simple language for drawing box and line diagrams. Let’s learn about pic and use it to create a few diagrams.

  1. Go through the short tutorial on pic.

  2. Edit the pic program in diagram.pic so that it will draw the exact diagram shown in Figure 1.

Reproduce this diagram with pic
Figure 1: Reproduce this diagram with `pic`.
  1. Run the following command to create a PostScript file:
      groff -p -T ps read-diagram > out.ps
    
  1. View the resulting picture. You have two options for viewing:
    1. If you have XWindows installed, you can view with the command
        gv out.ps
      

      Note: to see your output, you will probably need to change the default zoom level (5th button at the top) from 1.0000 to Fit to Window.

    2. If you are using VS Code, you can convert your PostScript file to an image by running the command
        convert out.ps -strip -opaque none out.png
      

      Now you can view the out.png in VS code.

  1. When you think your picture exactly matches Figure 1, you can test it by running the command
      /cs/cs131/bin/lab4-test out.ps
    

    You’ll get a message that tells you how closely your picture matches. If the match is not very close, the tester will generate a file out-diff.ps that visualizes the differences. Here is an example:

An almost-matching image
Figure 2: An example visualization of an image that almost matches. Everything matches except the last box, which only goes down, instead of down and to the left.

Practice Writing PostScript Code (25 minutes)

The PostScript language is a Turing-complete language for drawing text and graphics. A PostScript-enabled printer thus contains an embedded interpreter for the PostScript language. When you send it a .ps file, the printer interprets the file (i.e., runs the program that draws the page), and the result is made physical.

The file figure.ps is an extremely minimal PostScript file.

  1. Go through the short tutorial on postscript.

  2. Edit the PostScript program in figure.ps so that it draws a picture that includes a “person.” (Stick figures are totally acceptable.) You can debug your picture by viewing figure.ps with gv (if you are ssh-ing) or by converting figure.ps to an image (if you are using VS Code).

Practice with Coordinate Transformations (10 minutes)

One way to define a PostScript function is like so:

  /foo                   % pushes the symbolic name foo on the stack
  { 
  ...PostScript commands...
  }                      % pushes a sequence of commands on stack
  def                    % associate the name with the commands

Then, in your code, you can just say foo to execute that sequence of commands.

Turn your drawing of a person into a function. Call your function a few times interspersed, with uses of translate and/or rotate and/or scale, to get many “people” of different sizes, locations, and angles on one page. Once your masterpiece is finished, push your repo and commit on Gradescope.