ASCII to PostScript Converter

This PostScript program is prepended to an ASCII text file. When the concatenation is sent to a PostScript printer, the ASCII file is printed using a reasonable set of assumptions.

How it works

Consider the innermost loop:
{ %loop BS
   (\b) search exch
   show
   not { exit } if
   pop currentpoint exch colwid sub exch moveto
} loop %BS
The top of the stack is a string of characters to be interpreted. The search primitive searches for the first backspace (\b) in the string. First assume a backspace is found.

The search pushes the string after the backspace, the backspace, the string before the backspace, and true. The exch swaps the true and the string before the backspace. The show prints the string before the backspace. The not changes the true to false and the exit is not done. Then the current point is moved left by colwid and the loop repeats. This happens until no more backspaces are left.

When there are no backspaces found, search pushes the string itself and false. The exch swaps the false and the string and the show prints the string. The not changes the false to true and the exit is done.

Now, each embedding layer of this program follows the same schema but does a different step in the processing. Consider the next loop out:

{ %loop TAB
  (\t) search exch
  { %loop BS
*** just exactly the code described in the previous paragraph, above ***
   } loop %BS
   not { exit } if
   pop currentpoint exch 36 sub colwid div .49 add cvi
   8 add dup 8 mod sub colwid mul 36 add exch moveto
} loop %TAB
Similarly, this code finds the first tab in the string, prints the data up to the tab (processing backspaces as needed), then if a tab was found moves the current point right to the next multiple of colwid columns.

The next loop out processes carriage returns, which cause the current point to return to the beginning of the line without any vertical advancement. For LaserWriters connected over a serial link this may be a problem, as both CR and LF get converted to NewLine in the input processing. This is not a problem on EtherNet or AppleTalk printers. It may be necessary to remove this loop and condition the next outside loop (which processes Line Feeds) on Carriage Return instead.

The LF loop moves the point to the left margin, advances by 11 points, and may cause a new page. The FF loop causes a new page.

The outermost loop reads entire 256-character blocks from the input stream and calls the FF loop on them. This code is all inlined, and at the end is bound and executed.

The code itself

===== Cut Here =====
%!-Adobe-1.0
%%Title: asciiprint.ps
%%Creator: Ben Cranston 
%%CreationDate: Thu Feb 8 1990
%%Pages 0

/Courier findfont 10 scalefont setfont
/colwid (m) stringwidth pop def
36 756 moveto
256 string
{ %exec
   { %loop over file
      dup currentfile exch readstring exch
      { %loop FF
         (\f) search exch
         { %loop LF
            (\n) search exch
            { %loop CR
               (\r) search exch
               { %loop TAB
                  (\t) search exch
                  { %loop BS
                     (\b) search exch
                     show
                     not { exit } if
                     pop currentpoint exch colwid sub exch moveto
                  } loop %BS
                  not { exit } if
                  pop currentpoint exch 36 sub colwid div .49 add cvi
                  8 add dup 8 mod sub colwid mul 36 add exch moveto
               } loop %TAB
               not { exit } if
               pop 36 currentpoint exch pop moveto
            } loop %CR
            not { exit } if
            pop 36 currentpoint exch pop
            11 sub dup 25 le { %if
               pop showpage 756
            } if
            moveto
         } loop %LF
         not { exit } if
         pop showpage 36 756 moveto
      } loop %FF
      not { exit } if
   } loop %over file
   pop showpage
} bind exec

The tab code has been changed to make it more readable and modifiable.
The two 8s are the tab stops, you should be able to change them to any
other number.  The only other change is the indentation at three should
be a tad more readable than the old indentation at two.

Back to ZBEN's home page.