[comp.lang.postscript] audio-tape-1.5.ps

jwz@lucid.com (Jamie Zawinski) (10/18/90)

Here is the most recent version of audio-tape.ps, the all-singing, all-dancing
PostScript program for generating audio cassette labels.  It's pretty easy
to use even if you're not that familiar with PostScript - just fill in the
blanks.  Extensively documented, too.

I am posting the whole thing, in its 58k glory, because the last time I
released a version of it, I first said "send mail if you want it," and the
seventy responses I got in the first day caused me to post it anyway.

Please let me know if you find any problems with it.  Enjoy...

		-- Jamie <jwz@lucid.com>

---------------------------- CUT HERE ----------------------------
%!PSAdobe-1
%%Creator: Jamie Zawinski <jwz@lucid.com>
%%Title: audio-tape.ps
%%CreationDate: 17-oct-90
%%
%%  PostScript code to generate audio-tape labels.  Version 1.5.
%%  Copyright (c) 1990 Jamie Zawinski (jwz@lucid.com or
%%  jwz@spice.cs.cmu.edu).
%%
%%  Permission granted for non-commercial use and distribution
%%  so long as this notice of copyright remains intact.
%%
%%EndComments

%%BeginDocumentation
%%
%% There are a few examples at the end of this file; print this for a
%% representative selection of what this code can do.  Search for the
%% string "example" to see how to do it.

%% =========================================================================
%%			       HOW TO USE THIS
%% =========================================================================
%%
%% To print a tape label, you construct a call to one of several PostScript
%% procedures defined in this file.  The calling syntax is fairly simple,
%% and you don't need to know PostScript to do it.  Just fill in the blanks.
%%
%% For a tape label with one album on each side, both albums by the same band,
%% do this:
%%
%%	 (Band Name) (Album 1 Name) (Album 1 Date)
%%		     (Album 2 Name) (Album 2 Date)
%%	  [ <...album 1 songs....> ] [ <...album 2 songs....> ]
%%	  two-albums
%%
%% For a tape label with one album on each side, both albums by different
%% bands, do this:
%%
%% 	 (Band 1 Name) (Album 1 Name) (Album 1 Date)
%%	    [ <...album 1 songs....> ]
%%	  (Band 2 Name) (Album 2 Name) (Album 2 Date)
%%	    [ <...album 2 songs....> ]
%%	  two-bands
%%
%% For a tape label with one double album consuming both sides, do this:
%%
%% 	 (Band Name) (Album Name) (Album Date)
%%	    [ <...songs, side 1....> ]
%%	    [ <...songs, side 2....> ]
%%	  double-album
%%
%% For a tape label with three or four albums/EPs by the same band, do this:
%%
%% 	 (Band Name) (Album 1.1 Name) (Album 1.2 Name) (Album 1.* Date)
%%		     (Album 2.1 Name) (Album 2.2 Name) (Album 2.* Date)
%%	    [ <...songs, side 1....> ]
%%	    [ <...songs, side 2....> ]
%%	  N-albums
%%
%% (Either of the strings (Album 1.2 Name) or (Album 1.2 Name) may be
%% an empty string; things will be positioned appropriately.)
%%
%% For a tape label with three or four albums/EPs by two different bands,
%% do this:
%%
%% 	 (Band 1 Name) (Album 1.1 Name) (Album 1.2 Name) (Album 1.* Date)
%%	    [ <...songs, side 1...> ]
%%	 (Band 2 Name) (Album 2.1 Name) (Album 2.2 Name) (Album 2.* Date)
%%	    [ <...songs, side 2...> ]
%%	  two-bands-N-albums
%%
%%
%% In the above examples, [ <songs> ] should really be of the form
%%
%%   [ (song 1) ... (song N) ]	    	that is, an array of strings; or it
%%					may also be of the form
%%
%%   [[ (song 1)  (song 1 time) ]   	that is, an array of arrays, where
%%    [ (song 2)  (song 2 time) ]	each sub-array holds exactly two
%%     ...				strings.  The first string is the name
%%    [ (song N)  (song N time) ]]	of a song, and the second string is
%%					the start-time, length, counter, or
%% whatever of the song.  The song name is printed flushleft, and the song
%% time is printed flushright.
%%
%% If an entry in the song array is of the form
%%    [ (song N)  (song N time) ...font... ]
%% where ...font... is one of /B, /I, /BI, or /Title.  This is explained a
%% little later.

%% =========================================================================
%%			      WHAT YOU WILL GET
%% =========================================================================
%%
%% The labels are printed two-per-page.  You do not need to insert "showpage"s
%% in this file; that happens automagically.
%%
%% The band-names and album-names are printed on the spine of the label.
%% For the one-band-on-both-sides cases, the band-name is printed tall enough
%% to fill the label.  For the two-band cases, the band names are printed one
%% atop the other.  Album names are scaled so that all album names fit on
%% one atop the other on the spine.
%%
%% In all cases (spine, song lists, etc) it is not possible for a string to
%% be "too long" - font-widths are scaled so that the strings fit in the
%% available space (taking into account adjascent strings of the same height;
%% strings stacked above/next to each other are scaled as a unit.  You'll
%% see what I mean.)
%%
%% Songs are printed in two columns on the back of the tape label, or on the
%% inside of the tape label (user-configurable).  The name of the album is
%% printed above the song lists.  When there are more than two albums on a
%% tape, the names of all three or four albums are printed on the spine, and
%% the names of albums 1.1 and 2.1 are printed above the song listings on
%% the inside.
%%
%% It is possible to specify the font of individual lines in the song listings
%% by placing a font-keyword in the third position of an element of the 
%% song-list array.  Valid face-specifiers are /B (bold), /I (italic), /BI
%% (bold italic), and /Title.  If the font is unspecified, /B, /I, or /BI,
%% then the font used for the song name is determined by one of the variables
%% /song-font, /song-font-bold, /song-font-italic, or /song-font-bold-italic.
%% The font will always be scaled to be /song-font-height points tall.
%%
%% If, however, the font is specified as /Title, then the font used will b
%% the value of /title-font, and it will be /title-font-height tall; it will
%% also be underlined.  The intent here is that specifying the font as /Title
%% makes an entry in the song listings look just like the album titles above
%% the listings.  That way, if you have more than one album on the same side
%% of a tape, you can display a title for both of them, which was not possible
%% in versions prior to 1.5.  (Extra hack: [(song) /Title] is considered to
%% be the same as [(song) () /Title], since the time is ignored for titles.)
%%
%% It is possible to include arbitrary graphics in place of the band-name
%% on the spine, to duplicate the way a band normally renders its name, or
%% whatever.  It is also (as of v1.4) possible to include an arbitrary
%% graphic on the inside flap, or printed (lightly) under the song listings.
%% See below.

%% =========================================================================
%%			  HOW TO USE THIS UNDER UNIX
%% =========================================================================
%%
%% Of course, it's possible to just edit this file and print it each time you
%% want to print a label, but that kind of a pain.  And you don't want a copy
%% of this file sitting around for every tape label you print, it's too big.
%% Here's one way to easily do it.
%%
%%  -  Save a copy of this file in a file called "audio-tape-1.4.ps" in a safe
%%     place, so that if you screw up, you can do it again.
%%  -  Make a copy of this file called "audio-tape-prolog.ps" which consists
%%     of everything from the beginning of the file up to and including the
%%     line which says "%%EndProlog".  Delete everything between the lines 
%%     which say "%%BeginDocumentation" and "%%EndDocumentation" - those lines
%%     are the documentation you are reading now, and there's no sense in 
%%     sending N k of comments to the printer.
%%  -  Make a file called "audio-tape-trailer.ps" which consists of everything
%%     from the line which says "%%Trailer" to the end of the file (just a few
%%     lines).
%%  -  When you edit a new tape label, put it in its own file.  Include in this
%%     file only what the "How to Use This" section had you type in.
%%  -  To print a label or set of labels, do something like
%%     "cat audio-tape-prolog.ps my-label.ps audio-tape-trailer.ps | lpr"
%%     This will concatentate the PostScript code, the definitions of your
%%     labels, and the necessary trailer together, and hand that as input to
%%     "lpr" or whatever command you use for printing.
%%
%% I also have some Common Lisp code which maintains a database of tapes, and
%% can generate this PostScript code directly.  It uses a simple textual file
%% format for storing the song listings; if you want it, send me mail.  If you
%% use TI Explorer Lisp Machines, I have a totally whizzy menu-driven 
%% interface to editing, searching, and printing these labels. Again, just ask.

%% =========================================================================
%%			     SIMPLE CUSTOMIZATION
%% =========================================================================
%%
%% To change the fonts of various things, change the values of the variables
%% /song-font, /band-font, /album-font, /inner-album-font, or /date-font.
%% It is not possible to change the height or aspect ratio of the fonts, as
%% those are computed at runtime.
%%
%% If you prefer the labels to be printed in such a way that the song listings
%% will appear on the inside of the tape box instead of the outside, set the
%% variable /songs-go-inside to true.  It defaults to false.
%%
%% If you prefer the labels to be printed so that a band's graphic goes on the
%% inside of the tape box instead of the outside, set /icons-go-inside to
%% false.  It defaults to false.
%%
%% If you prefer to have the spine of the label wrong-side-up, set /flip-spine
%% to true.  It defaults to false.
%%
%% If /songs-go-inside and /icons-go-inside have the same value (both inside
%% or both outside) then the songs will be printed overlaying the icon.  The
%% icon will be printed at 25% intensity so that you can still read the songs
%% on top of dark areas.  This is customizable by changing the variable 
%% /icon-fade-factor.
%%
%% One problem I encountered with this code was that my co-worker's tapes all
%% looked just like mine...  I got around this by adding the parameter
%% /signature - set this to a string of your name or something, and it will
%% be printed on the back-spine of all of your labels.  It can be multiple
%% lines by specifying it as [ (line 1) (line 2) ... ] instead of as a string.
%% (Embedding newlines in a string will not do what you want.)

%% =========================================================================
%%			 SOPHISTICATED CUSTOMIZATION
%% =========================================================================
%%
%% Defining a new magic-name-printer is pretty simple.  Just define a
%% procedure for drawing the name, and index it in "magic-name-dict" under
%% the string which is the band's name.  There are some fairly sophisticated
%% examples of this in this file.  If you define any more, send them to me
%% and I'll include them in the next distribution (whether I like the band
%% or not :-)).
%%
%% Adding an icon-printer is similar - you use "magic-icon-dict" instead of
%% "magic-name-dict".  For magic-names, define the procedures to draw in
%% a device-scale (1 unit = 1 point) space with origin at the upper left.
%% For icons, define the procedure to be in a one-unit tall space - 1 unit
%% will correspond to the entire height of the flap on which the icon is
%% drawn.  For icons, the origin is at the XY center instead of the upper
%% left.  This is all kind of arbitrary, but it doesn't matter too much,
%% because the beauty of PostScript is that you can scale/translate within
%% your procedure to work in the space that is most convenient to you.
%%
%% When you add something to magic-name-dict or magic-icon-dict, be sure to
%% use "CIput" instead of "put" to insure case-insensitivity.
%%
%% When /songs-go-inside and /icons-go-inside have the same value, meaning 
%% that the songs will be printed overlaying the icon, we cause the icon to
%% be printed at quarter-intensity by changing the transfer function.  If
%% your icon is written in such a way that this is not desirable, it's
%% possible to defeat it within a given icon printer by doing something 
%% like "{} settransfer" within the scope of a "gsave".
%%
%% Note that magic-name and magic-icon printers are not used unless the label
%% being printed is a double album, or the albums on both sides are by the
%% same band.

%% =========================================================================
%%				   WISHLIST
%% =========================================================================
%% 
%%  o  A general font-change mechanism would be nice, for font changes in the
%%     signature as well as in the song listings.
%%
%%  o  Maybe there should be a way to print arbitrary text on the inside flap,
%%     aside from defining a magic-icon printer.
%%
%%  o  The magic-icon-printers should be used even if there are two different
%%     bands on one tape - print two of them side by side if necessary.
%%
%%  o  Maybe the magic-name printers should be invoked even if both sides of
%%     the tape are not by the same band.
%%
%%  o  The height of the song listing font should be autoscaled in the event
%%     that the user has more than twenty or so songs on one side of a tape.
%%
%%  o  When printing a song with the /Title flag, the title-fonts at the top
%%     of the listings should be scaled along with the inline font.  Also, the
%%     normal song listings should not be autoscaled along with the inline
%%     title as happens now.  The titles should be treated as a unit, and the
%%     songs as a unit, even though they may occupy the same region.

%% =========================================================================
%%	       WHAT THE CURRENTLY DEFINED MAGIC-NAME-PRINTERS DO
%% =========================================================================
%% 
%% o  Siouxsie and the Banshees is printed in an alternating sized, alternating
%%    cased font, with the "and" over the "the" like on many early albums.
%% o  Cabaret Voltaire is printed in a font that looks like the one on the
%%    cover of "Micro-Phonies."
%% o  New Order is printed with a black "New" overlapping a hollow "Order" as
%%    on "Low Life" etc.
%% o  OMD is printed on two lines, one font thicker than the other.  The OE is
%%    printed with an OE character.
%% o  Front 242 is printed similarly.
%% o  Love and Rockets has an icon - a heart on a rocket in a circle.
%% o  Bauhaus has an icon - the Beggars' Banquet "face-in-circle" logo.
%% o  Nitzer Ebb has three icons:
%%    o  If the album name is "That Total Age", the gear/star/hammer logo is
%%       printed.
%%    o  If the album name is "Belief", a low-resolution bitmap of the angry
%%       looking eye from the cover of that album is printed.  This is a fair
%%       example of how to incorperate such bitmaps, and it doesn't take up
%%       that much space, either.
%%    o  Otherwise, the star-over-gear icon from the Warsaw Ghetto EP is used.
%% o  Nine Inch Nails has an icon - "NIN" in a box with the first N backwards.
%%
%% Please send me more!

%% =========================================================================
%%				  CHANGELOG
%% =========================================================================
%% some time in 1988... created by Jamie Zawinski.
%% 30 may 90	Jamie Zawinski
%%	fixed a bug which made it impossible to have the band-name and
%%	album-name in different fonts for double-albums.
%% 27 jul 90	Jamie Zawinski
%%	fixed the above fix.
%% 28 jul 90    Jamie Zawinski
%%      Modified the magic-name printers to work around a bug in version 1.1
%%      of Adrian Aylward's Amiga postscript interpreter (post).  In that
%%      implementation, 'get' doesn't work on dictionaries whose keys are
%%      string instead of names; so I added some calls to 'cvn' before 
%%      storing into 'magic-name-dict'.
%%  6 aug 90    Jamie Zawinski
%%      Implemented magic-icons for arbitrary graphics on the back.
%%      Improved auto-scaling a great deal.
%%  9 aug 90	Jamie Zawinski
%%      Made songs able to be strings as well as [()()], and made the signature
%%      able to be multiple lines.  Made sig able to be in a different font
%%      than the song listings.  Made magic-name and magic-icon lookups happen
%%      case-insensitively.
%%  17 oct 90	Jamie Zawinski
%%      Made it possible to change the fonts of individual song listings, and
%%      have album-titles embedded in the middle of the song listings.  Fixed
%%      the auto-scaling of v1.5 to produce the exact same output as v1.4
%%      except where v1.5 does better.
%% =========================================================================

%% Questions?  Comments?  Suggestions?  Improvements?  Send them to me,
%% jwz@lucid.com.  "Please, no applause, just throw money."
%%
%%EndDocumentation

/bdef { bind readonly def } bind readonly def

/box {
  4 2 roll
  newpath moveto
    exch dup 0 rlineto
    exch 0 exch neg rlineto
    neg 0 rlineto
  closepath
} bdef

/rightshow
 {dup stringwidth pop
  neg 0 rmoveto
  show } bdef

/centershow
 {dup stringwidth pop
  2 div neg 0 rmoveto
  show } bdef

/max {
  dup 3 -1 roll dup
  3 -1 roll gt
  { exch pop } { pop } ifelse
  } bdef

/max-stringwidth {
  stringwidth pop
  exch stringwidth pop
  max
  } bdef

%% Default font-names and sizes.  The widths (and sometimes heights) are 
%% stomped at runtime, but the names are the responsibility of the user.
%%
/song-font /Helvetica def
/song-font-bold /Helvetica-Bold def
/song-font-italic /Helvetica-Oblique def
/song-font-bold-italic /Helvetica-BoldOblique def
/song-time-font song-font-italic def
/song-font-height 8 def

/signature-font /Helvetica def
/signature-font-height 8 def

/band-font /Helvetica def
/band-font-height 13 def

/album-font /Helvetica def
/album-font-height 13 def

/inner-album-font /Helvetica-Bold def
/inner-album-font-height 13 def

/date-font /Helvetica-Bold def
/date-font-height 8 def

% if true, songs go inside the tape label, else outside.
/songs-go-inside false def

% if true, icons go inside the tape label, else outside.
/icons-go-inside false def

% If true, the spine will be printed with a nasty orientation.
/flip-spine false def

% if an icon and the song listings are being printed on the same flap, the
% icon will be faded by this amount (so that the songs will be readable).
%
/icon-fade-factor 0.20 def

/margins 4 def

/back-spine-height 40 def
/spine-height 32 def
/list-height 185 def
/total-height margins back-spine-height add
              margins spine-height add add
              margins list-height add  2 mul add
              margins add
            def

/inner-width 280 def
/total-width inner-width  margins dup add add  def

/extract-song-and-time-and-font {  % takes a song spec and leaves three things
                                   % on the stack - (song) (time) <font>.
  dup type /stringtype eq
  { () /R }
  { dup length
    dup 0 eq
    { pop pop () () /R }
    { dup 1 eq
      { 0 get () /R }
      { 2 eq
        { dup 0 get exch 1 get /R }
        { dup 0 get exch dup 1 get exch 2 get }
	ifelse
      } ifelse
    } ifelse
  } ifelse
  % if the time is /Title or /title, set the font to
  % be the same.
  exch dup dup
  /Title eq
  exch
  /title eq
  or
    { pop pop /Title dup } if
  exch
  decode-song-font-name
} bdef

/decode-song-font-name {   % takes a name, one of /R, /B, /I, /BI, or /Title
                           % and converts that to a font scaled appropriately.
                           % Leaves the font on the stack.
    
  song-font-height exch % put the height on the stack under the name.

  % convert the name to a font-name.
  dup /B eq
  { pop song-font-bold }
  { dup /I eq
    { pop song-font-italic }
    { dup /BI eq
      { pop song-font-bold-italic }
       { dup /Title eq
	 exch /title eq or
	 % if the code was /Title or /title, take the default height off the
	 % stack and put the title-font-height there instead.
	 { pop inner-album-font-height
	   inner-album-font }
	 { song-font }
	 ifelse
       } ifelse
    } ifelse
  } ifelse

  % set FH to the font height, leaving the font-name.
  exch /FH exch def
  % then find and scale the font, leaving it on the stack.
  findfont
  [ FH song-fonts-w-scale mul 0 0 FH 0 0 ] makefont
} bdef

/print-one-column {                    % write one column of the song listings
  /songs exch def
  /h exch def /w exch def
  /y exch def /x exch def
  gsave
    /w w 10 sub def
    /x x 5 add def
    /y  y inner-album-font-height sub  def
    x y translate
    -5 0 w h box clip newpath
    /x 0 def
    /x2 x w add 5 sub def
    /y song-font-height neg def

    songs { extract-song-and-time-and-font
	    setfont
	    dup /Title eq
	    { /y y inner-album-font-height song-font-height sub sub def
	      pop x 5 sub y moveto
              show
	      0 -2 rmoveto
	      x 5 sub y 2 sub lineto stroke   % underline it
	      /y y
	        inner-album-font-height song-font-height sub
	        2 sub sub def           % frob y.
	    }
	    { x2 y moveto
              rightshow
	      x y moveto
	      show }
	    ifelse
            /y y song-font-height sub 1 sub def
          } forall
  grestore
 } bdef


/print-songs {                 % write a column of the song listings; 0=left.
  /left exch def
  gsave
    /y  back-spine-height spine-height add
        margins 3 mul  add
        neg  def
    /w  inner-width 2 div def
    /h  list-height inner-album-font-height sub date-font-height sub
        margins 2 mul sub  def

    songs-go-inside { /y y list-height margins add sub def } if

    1 left eq
      { /x 10  def
        /songs songs1 def }
      { /x  w 10 add  def 
        /songs songs2 def }
    ifelse
    x y w h songs print-one-column
  grestore
 } bdef

/draw-icon {
  gsave
    total-width 2 div
    icons-go-inside
     { total-height list-height 2 div margins add sub neg }
     { total-height list-height 1.5 mul margins add sub neg }
    ifelse
    translate
    list-height dup scale

    icons-go-inside songs-go-inside and
    icons-go-inside not songs-go-inside not and or
      { { 1 exch sub icon-fade-factor mul 1 exch sub } settransfer
	  0 setgray } % ..to work around bug in GhostScript 2.0's settransfer.
    if
    magic-icon
  grestore
  } bdef

/set-songfont {	    % compute width-scale of fonts for song listings.
  /tfont song-time-font findfont song-font-height scalefont def
  /maxw 0 def
  /song-fonts-w-scale 1 def   % set to 1 for width computation.
  songs1 { extract-song-and-time-and-font
           setfont
           dup /Title eq
            { pop 0 }
            { stringwidth pop }
           ifelse
           exch stringwidth pop
           add
	   maxw max
           /maxw exch def
         } forall
  songs2 { extract-song-and-time-and-font
           setfont
           dup /Title eq
            { pop 0 }
            { stringwidth pop }
           ifelse
           exch stringwidth pop
           add
	   maxw max
           /maxw exch def
         } forall
  /w  inner-width 2 div 5 sub 15 sub def
  maxw w gt { /song-fonts-w-scale w maxw div def } if
  } bdef


/print-two-inner-album-titles {   % write album titles above the song listings
  gsave
    /x 10 def
    /y  back-spine-height spine-height add
        margins 3 mul  add
        neg  def
    /w  inner-width 2 div 10 sub def
    /x2 w 20 add def

    songs-go-inside { /y y list-height margins add sub def } if

    /font  inner-album-font findfont inner-album-font-height scalefont  def
    font setfont
    /maxw albumname1 albumname2 max-stringwidth def

    maxw w gt
      { font [ w maxw div 0 0 1 0 0 ] makefont setfont }
    if

    gsave
      x y w inner-album-font-height 1.5 add box clip newpath
      x  y inner-album-font-height sub 2 add  moveto
      albumname1 show
      0 -2 rmoveto
      x  y inner-album-font-height sub  lineto stroke        % underline it.
    grestore
    gsave
      x2 y w inner-album-font-height 1.5 add box clip newpath
      x2 y inner-album-font-height sub 2 add  moveto
      albumname2 show
      0 -2 rmoveto
      x  y inner-album-font-height sub  lineto stroke        % underline it.
    grestore
  grestore
 } bdef


/print-one-inner-album-title {  % write album title centered above songs.
  gsave
    /x 10 def
    /y  back-spine-height spine-height add
        margins 3 mul  add
        neg  def
    /w  inner-width x sub def

    songs-go-inside { /y y list-height margins add sub def } if

    /font inner-album-font findfont inner-album-font-height scalefont def
    font setfont
    /maxw albumname1 stringwidth pop def

    maxw w gt
      { font [ w maxw div 0 0 1 0 0 ] makefont setfont }
    if

    gsave
      x y w inner-album-font-height 1.5 add box clip newpath
      x w 2 div add  y inner-album-font-height sub 2 add  moveto
      albumname1 centershow
      newpath 
      x  y inner-album-font-height sub  moveto
      w 10 sub 0 rlineto stroke
    grestore
  grestore
 } bdef


/print-inner-album-titles {
  double-album-p
  { print-one-inner-album-title }
  { print-two-inner-album-titles }
  ifelse
} bdef


/print-one-date {       % write a date centered below the song listings
  gsave
    /x 10 def
    /y  back-spine-height spine-height add
        list-height  add
        margins 2 mul  add
        inner-album-font-height sub
        neg  def
    /w  inner-width x sub def

    songs-go-inside { /y y list-height margins add sub def } if

    date-font findfont date-font-height scalefont setfont
    x y w inner-album-font-height 1.5 add box clip newpath
    x w 2 div add  y inner-album-font-height sub 2 add  moveto
    date1 centershow
  grestore
 } bdef


/print-two-dates {              % write the dates below the song listings
  gsave
    /x 25 def
    /y  back-spine-height spine-height add
        list-height add
        margins 2 mul  add
        inner-album-font-height sub
        neg  def
    /w  inner-width 2 div def
    /x2 w 25 add def

    songs-go-inside { /y y list-height margins add sub def } if

    date-font findfont date-font-height scalefont setfont
    gsave
      x y w inner-album-font-height box clip newpath
      x  y inner-album-font-height sub 2 add  moveto
      date1 show
    grestore
    gsave
      x2 y w inner-album-font-height box clip newpath
      x2  y inner-album-font-height sub 2 add  moveto
      date2 show
    grestore
  grestore
 } bdef

/print-dates {
  double-album-p
  { print-one-date }
  { print-two-dates }
  ifelse
} bdef


/compute-spine-font-xscale {
  % compute horizontal size of largest band name string...
  magic-name-p
   { magic-name-width }
   { band-font findfont band-font-height scalefont setfont
     bandname1 bandname2 max-stringwidth }
  ifelse
  % compute horizontal size of largest album name string...
  album-font findfont album-font-height scalefont setfont
  albumname1 albumname2 max-stringwidth
  albumname3 albumname4 max-stringwidth max
  add	     		  % add them and divide inner-width by them to get
  spine-height mul	  % the ratio to scale the fonts by.  If this is
  inner-width		  % less than 1, don't do any scaling.
  10 sub     % subtract 10 from inner-width to account for the 5 point margin
             % between the text and the right and left edges.
  % if the two fonts are the same height, insert an additional 10 point gap.
  band-font-height album-font-height eq { 10 sub } if
  
  exch div
  dup 1 ge { pop 1 } if
} bdef


/box-name-printers-p false def   % For debugging.  You don't want this.


/draw-spine {                       % draw the spine of the tape (upside-down)
  gsave
    margins  margins margins add  back-spine-height add neg  translate

    flip-spine not { 180 rotate inner-width neg spine-height translate } if
    
    0 0  inner-width  spine-height  box stroke     % the box around the spine
    0 0  inner-width  spine-height  box clip newpath
    margins spine-height neg translate
    /xscale compute-spine-font-xscale def
    gsave
      0 0 moveto
      spine-height xscale mul spine-height scale
      magic-name-p
      { box-name-printers-p  % debugging magic-name-printer sizing.
	{ 0 setgray 0 0 magic-name-width -1 box fill
	  { 1 exch sub } settransfer 0.01 setlinewidth 0 setgray
	  0 1 9 { 0 moveto 0 1 rlineto stroke } for }
	if
	0 0.2222 translate
	0.9 0.9 scale
	magic-name }
      { band-font findfont band-font-height scalefont setfont
	0 1 band-font-height sub moveto
	bandname1 show
	0 1 band-font-height dup add sub moveto
	bandname2 show
      }
      ifelse
    grestore
    inner-width margins sub margins sub 0 translate
    gsave
      spine-height xscale mul spine-height scale
      /afh album-font-height def
      album-font findfont afh scalefont setfont
      1 afh sub
      dup 0 exch moveto
      albumname1 () eq not {                  albumname1 rightshow afh sub }if
      albumname2 () eq not {dup 0 exch moveto albumname2 rightshow afh sub }if
      albumname3 () eq not {dup 0 exch moveto albumname3 rightshow afh sub }if
      albumname4 () eq not {dup 0 exch moveto albumname4 rightshow }if
      pop
    grestore
  grestore
} bdef

/coerce-to-array-of-strings {  % if given a string, puts it in an array.
  dup
  type /stringtype eq
  { 1 array astore }
  if
  } bdef


/draw-back-spine {                 % draw the short flap on the back.
  /x margins def
  /y margins neg def
  /w inner-width def
  /h back-spine-height def
  gsave
  x y w h box stroke
    x y w h box clip newpath
    x w add  y h add neg  translate
    180 rotate
    signature-font findfont signature-font-height scalefont setfont
    /s signature coerce-to-array-of-strings def
    /sx margins def
    /sy h margins 3 mul sub neg
        s length 1 sub signature-font-height mul add
       def
    s { sx sy moveto
	show
	/sy sy signature-font-height sub def
      } forall
  grestore
 } bdef


/reset {		% resets all the tape-specific parameters.
  /bandname1 () def
  /bandname2 () def
  /albumname1 () def
  /albumname2 () def
  /albumname3 () def
  /albumname4 () def
  /date1 () def
  /date2 () def
  /magic-name-p false def
  /magic-icon-p false def
  /double-album-p false def
  } bdef

reset	    		% do it now to give them their initial values.
/signature () def	% probably redefined later.


/draw-tape-label {     % draw one.  Assumes all variables have been filled in.
		       % Takes X and Y on the stack.
  /y exch def
  /x exch def
  gsave
    90 rotate
    x y translate

    0 0 total-width total-height box stroke

    margins total-height neg
            list-height 2 mul add
            margins 2 mul add
    inner-width list-height box stroke    % draw a box around the back.
    magic-icon-p { draw-icon } if

    margins total-height neg
            list-height add
            margins add
    inner-width list-height box stroke    % draw a box around the listings.

    draw-back-spine
    print-inner-album-titles
    draw-spine
    set-songfont
     0 print-songs
     1 print-songs
    print-dates
    0 0 total-width total-height box      % draw the outermost box.
  grestore
  reset
 } bdef


%%% Case-insensitive dictionary lookup.  Yowza.

/nsdc-buf 255 string def
/nstring-downcase { % target-string source-string
    	 	    % convert a string to lowercase; copies source-string
		    % into target-string, doing the conversion.  The two 
		    % strings may be the same, and the source-string may
    		    % be a 'name'.
  dup type /nametype eq { nsdc-buf cvs } if
  0 exch
  { dup dup 65 ge
    exch 90 le and
     { 32 add } if
    exch dup
    4 1 roll exch
    2 index 5 1 roll
    put 1 add
  } forall
  pop
} bdef

/CIget { % like get, but uses a lowercase version of the string.
    dup length string exch nstring-downcase get
} bdef

/CIput { % like put, but uses a lowercase version of the string.
    exch dup length string exch nstring-downcase exch put
} bdef

/CIknown { % like known, but uses a lowercase version of the string.
    dup length string exch nstring-downcase known
} bdef


% Dictionaries for storing magic band-name-and-icon-rendering functions.
%
/magic-name-dict 200 dict def
/magic-icon-dict 200 dict def

% Invoke the magic band-name-rendering function for the current band.
%
/magic-icon { magic-icon-dict bandname1 CIget exec } def
/magic-name { magic-name-dict bandname1 CIget 0 get exec } def

/magic-name-width { magic-name-dict bandname1 CIget 1 get } def


% Decide whether this band has a magic rendering function.
%
/check-magic {
  /magic-name-p magic-name-dict bandname1 CIknown def
  /magic-icon-p magic-icon-dict bandname1 CIknown def
} bdef


% Define a new magic-name printer.
/define-magic-name-printer {   % arguments: bandname procedure width
   2 array astore
   magic-name-dict  % stack: band [proc w] dict
   3 1 roll         % stack: dict band [proc w]
   CIput
} bdef


/tick false def		% Currently on the left side of page or right.
			% Controls showpages and positioning.

/dump-internal {	% toss one puppy out.
  tick { 360 } { 50 } ifelse -100 draw-tape-label
  tick { showpage } if
  /tick tick not def
  reset
} bdef

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		The user-level functions.		%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


/two-albums {	% arguments:  bandname album1 date1 album2 date2 songs1 songs2
  /songs2 exch def
  /songs1 exch def
  /date2 exch def
  /albumname2 exch def
  /date1 exch def
  /albumname1 exch def
  /bandname1 exch def
  /band-font-height  0.6 def
  /album-font-height 0.4 def
  check-magic
  dump-internal
} bdef


/two-bands { %args: bandname1 album1 date1 songs1 bandname2 album2 date2 songs2
  /songs2 exch def
  /date2 exch def
  /albumname2 exch def
  /bandname2 exch def
  /songs1 exch def
  /date1 exch def
  /albumname1 exch def
  /bandname1 exch def
  /band-font-height  0.4 def
  /album-font-height 0.4 def
  /magic-name-p false def
  /magic-icon-p false def
  dump-internal
} bdef


/double-album {	% arguments:  bandname album date songs1 songs2
  /songs2 exch def
  /songs1 exch def
  /date1 exch def
  /albumname1 exch def
  /bandname1 exch def
  /band-font-height  0.6 def
  /album-font-height 0.6 def
  /double-album-p true def
  check-magic
  dump-internal
} bdef


/N-albums { %args:  bandname album1.1 album1.2 date1 album2.1 album2.2 date2 songs1 songs2
  /songs2 exch def
  /songs1 exch def
  /date2 exch def
  /albumname4 exch def
  /albumname2 exch def
  /date1 exch def
  /albumname3 exch def
  /albumname1 exch def
  /bandname1 exch def

  /band-font-height 0.6 def
  () albumname3 eq () albumname4 eq and
  { /album-font-height 0.4 def }
  { () albumname3 eq () albumname4 eq or
    { /album-font-height 0.3125 def }
    { /album-font-height 0.21875 def }
    ifelse }
  ifelse

  check-magic
  dump-internal
} bdef


/two-bands-N-albums { % arguments:  band1 album1.1 album1.2 date1 songs1 band2 album2.1 album2.2 date2 songs2
  /songs2 exch def
  /date2 exch def
  /albumname4 exch def
  /albumname2 exch def
  /bandname2 exch def
  /songs1 exch def
  /date1 exch def
  /albumname3 exch def
  /albumname1 exch def
  /bandname1 exch def

  /band-font-height 0.4 def

  () albumname3 eq () albumname4 eq and
  { /album-font-height 0.4 def }
  { () albumname3 eq () albumname4 eq or
    { /album-font-height 0.3125 def }
    { /album-font-height 0.21875 def }
    ifelse }
  ifelse
  /magic-name-p false def
  /magic-icon-p false def
  dump-internal
} bdef

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		The Magic-Name Printers.		%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    These routines will be automatically invoked to	%%%%%%%%
%%%%%%%    draw certain band-names, so that you can have	%%%%%%%%
%%%%%%%    really hi-tech tape-labels.  Add more!		%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%% Draw "Front 242" as a long, thin "front" over a long, tall "242".
%%%
(Front 242)
  {
    gsave
      0 -0.1 translate
      0.95 1 scale
      /Helvetica-Bold findfont [ 1.35 0 0 0.4 0 0 ] makefont  setfont
      0 0.58 moveto
      (FRONT) show
      /Helvetica-Bold findfont [ 2.85 0 0 0.7 0 0 ] makefont  setfont
      0 0 moveto (242) show
    grestore
  } bind
  4
define-magic-name-printer

%%% Draw "Orchestral Manoeuveres in the Dark" on two lines; use the
%%% "oe" character.
%%%
(Orchestral Manoeuveres in the Dark)
  {
    gsave
      0 -0.1 translate
      0.7 1 scale
      /Helvetica-Bold findfont [0.45 0 0 0.65 0 0] makefont setfont
      0.1 0.35 moveto
      (ORCHESTRAL MAN\352UVRES) show
      /Helvetica findfont [1 0 0 0.3 0 0] makefont setfont
      0.1 0.05 moveto
      (IN THE DARK) show
    grestore
  } bind
  4.2
define-magic-name-printer


%%% Draw "OMD" in the same way as "Orchestral Manoeuveres in the Dark".
%%%
magic-name-dict (OMD) cvn
  magic-name-dict (Orchestral Manoeuveres in the Dark) cvn CIget
CIput


%%% Draw "New Order" as a dark "New" over an outlined "Order", staggered.
%%%

(New Order)
  {
    gsave
      0 -0.1 translate
      0.02 setlinewidth
      1.5 setmiterlimit
      /Helvetica-Bold findfont setfont
      0 0.1 moveto
      (Order) true charpath stroke
      1.57 0.1 moveto
      (new) show
    grestore
  } bind
  3.2
define-magic-name-printer


%%% Draw "Siouxsie and the Banshees" with varying-height letters,
%%% like on the early albums.
%%%

(Siouxsie and the Banshees)
  {
    gsave
      0 -0.1 translate
      0.7 0.4 scale
      0.1 0.25 translate
      /big-font   /Helvetica findfont [ 0.5 0 0 2.2 0 0 ] makefont  def
      /med-font   /Helvetica findfont [ 0.5 0 0 1.1 0 0 ] makefont  def
      /small-font /Helvetica findfont [ 0.5 0 0 1.5 0 0 ] makefont  def
      0 -0.1 5.9 -1.8 box clip newpath
      0 0 moveto
      big-font setfont (SI) show
      0 0.8 rmoveto
      small-font setfont (o) show
      0 -0.8 rmoveto
      big-font setfont (UXSIE) show
      med-font setfont
      currentpoint /y exch def /x exch def
      .07 0.85 rmoveto
      (and) show x y moveto (THE) show
      big-font setfont (BANSHE) show
      0 0.8 rmoveto
      small-font setfont (e) show
      0 -0.8 rmoveto
      big-font setfont (S) show
    grestore
  } bind
  4
define-magic-name-printer


%%% Draw "Cabaret Voltaire" in their font.  I should probably have
%%% implemented this as a font, instead of as a set of procedures,
%%% but life's too short.
%%%

(Cabaret Voltaire)
  {
    gsave
      0 -0.1 translate
      0.5 0.5 scale
      1.8 setmiterlimit 0.1 setlinewidth
      0.2 0.3 moveto cabaret-c 0.5 0 rmoveto cabaret-a
      0.7 0 rmoveto cabaret-b  0.6 0 rmoveto cabaret-a
      0.7 0 rmoveto cabaret-R  0.6 0 rmoveto cabaret-e
      0.4 0 rmoveto cabaret-T  1.0 0 rmoveto cabaret-v
      0.6 0 rmoveto cabaret-o  0.7 0 rmoveto cabaret-L
      0.6 0 rmoveto cabaret-t  0.4 0 rmoveto cabaret-A
      0.45 0 rmoveto cabaret-I 0.45 0 rmoveto cabaret-r
      0.5 0 rmoveto cabaret-e
    grestore
  } bind
  4.1
define-magic-name-printer

%% Internal procedures to the "Cabaret Voltaire" printer.
%%
/cabaret-c { gsave currentpoint translate newpath 0.5 0.25 moveto 0.25 0 lineto
  0 0.5 lineto 0.25 1 lineto 0.5 0.75 lineto stroke grestore } bdef

/cabaret-a { gsave currentpoint translate newpath 0.25 0.75 moveto 0.5 1 lineto
   0.5 0 lineto 0 0.5 lineto 0.5 0.5 lineto stroke grestore } bdef

/cabaret-b { gsave currentpoint translate newpath 0 1 moveto 0 0 lineto 
  0.5 0.5 lineto 0 0.5 lineto stroke grestore } bdef

/cabaret-R { gsave currentpoint translate newpath 0 0 moveto 0 1 lineto 0.5 0.5
  lineto 0 0.5 lineto 0.25 0.5 moveto 0.5 0 lineto stroke grestore } bdef

/cabaret-e { gsave currentpoint translate newpath 0.375 0.25 moveto 
  0.25 0 lineto 0 0.5 lineto 0.25 1 lineto 0.5 0.5 lineto 0 0.5 lineto stroke
  grestore } bdef

/cabaret-T { gsave currentpoint translate newpath 0 1 moveto 0.5 1 lineto 
  0.25 1 moveto 0.25 0 lineto stroke grestore } bdef

/cabaret-v { gsave currentpoint translate newpath
  0 1 moveto 0.25 0 lineto 0.5 1 lineto stroke grestore } bdef

/cabaret-o { gsave currentpoint translate newpath 0.25 1 moveto 0.5 0.5 lineto
  0.25 0 lineto 0 0.5 lineto closepath stroke grestore } bdef

/cabaret-L { gsave currentpoint translate newpath 0 1 moveto
    0 0.10 lineto 0.5 0.10 lineto stroke grestore } bdef

/cabaret-t { gsave currentpoint translate newpath 0 1 moveto
  0 0 lineto 0.275 0.25 lineto stroke 0 0.75 moveto 0.25 0.75 lineto stroke
  grestore } bdef

/cabaret-A { gsave currentpoint translate newpath 0 0 moveto 0.25 1 lineto
  0.5 0 lineto stroke 0.125 0.5 moveto 0.375 0.5 lineto stroke grestore } bdef

/cabaret-I { gsave currentpoint translate newpath 0.25 0 moveto 0.25 1 lineto
  stroke grestore } bdef

/cabaret-r { gsave currentpoint translate newpath 0 0 moveto 0 1 lineto stroke
  0 0.75 moveto 0.25 1 lineto 0.5 0.75 lineto stroke grestore } bdef


(Nine Inch Nails)
  { gsave
      0 0 moveto
      /Helvetica findfont [ 1 0 0 1 0 0] makefont
      /Helvetica findfont [-1 0 0 1 0 0] makefont
      dup setfont
      gsave
        90 rotate 0.3 -0.2 translate 0.7 0.7 scale NiNbox
      grestore
      /nw (n)stringwidth pop neg def
      0.6 0 moveto
      nw 0 rmoveto (n)show
      nw 0 rmoveto exch dup setfont (i)show
      nw 0 rmoveto exch dup setfont (n)show
      nw 0 rmoveto exch dup setfont (e i)show
      nw 0 rmoveto exch dup setfont (n)show
      nw 0 rmoveto exch dup setfont (ch )show
      nw 0 rmoveto exch dup setfont (n)show
      nw 0 rmoveto exch dup setfont (ails)show
      pop pop
    grestore } bind
  6.3
define-magic-name-printer



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		The Magic-Icon Printers.		%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    These routines will be automatically invoked to	%%%%%%%%
%%%%%%%    draw icons for tapes of certain band, again for	%%%%%%%%
%%%%%%%    added whizziness.  Add more!		 		%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

magic-icon-dict (Love and Rockets) cvn { L&R } CIput

/L&R {    % Love and Rockets logo.
  gsave
   0.005 setlinewidth
   gsave
     newpath 0.5 0 moveto 0 0 0.5 0 360 arc clip newpath
     -0.5 -0.5 1 -1 box fill
     1 setgray
     -0.1875 -0.5 0.375 -1 box fill
   grestore
   newpath 0.5 0 moveto 0 0 0.5 0 360 arc stroke
   L&R-rocket
   L&R-heart
  grestore
  } bdef

/L&R-rocket {
  -0.0625 0.3125 0.125 0.625 box fill   % shaft
  -0.0625 0.3125 moveto 0.125 0 rlineto % head
   0 0.5 lineto closepath fill
  -0.0625 -0.2 moveto -0.03 -0.03 rlineto % lfin
   0 -0.25 rlineto 0 -0.3125 lineto fill
   0.0625 -0.2 moveto 0.03 -0.03 rlineto  % rfin
   0 -0.25 rlineto 0 -0.3125 lineto fill
  } bdef

/L&R-heart-path {
  newpath
  0 0.125 moveto
  -0.0625 0.125 0.0625 0 180 arc
  0 -0.125 lineto
  0.125 0.125 lineto
   0.0625 0.125 0.0625 0 180 arc
  closepath
  } bdef

/L&R-heart {
  0.5 setgray L&R-heart-path fill
  0 setgray L&R-heart-path stroke
  } bdef


magic-icon-dict (Bauhaus) cvn { BEGA } CIput

/BEGA {  % Beggars Banquet logo.
  gsave
   0.005 setlinewidth
   newpath 0.5 0 moveto 0 0 0.5 0 360 arc stroke
   newpath 0.5 0 moveto 0 0 0.5 0 360 arc clip newpath
   0     0.3333 moveto 0.25 0 rlineto 0 -0.25 rlineto stroke  % eye
   0.083 0.3333 0.1666 0.1666 box fill
   0.3125 0.5 0.02 0.5 box fill                         % nose v
   0.2125 0 moveto 0.3125 0 lineto stroke               % nose h
   0.2725 0 0.04 0.3 box fill                           % mouth v
   0.2125 -0.125 0.1 0.03 box fill                      % mouth h
   0.125 -0.3 0.155 0.25 box fill                       % chin v
   0.0625 -0.3 moveto 0.28 -0.3 lineto stroke           % chin h
  grestore
  } bdef

magic-icon-dict (Nitzer Ebb) cvn { NE-dispatch } CIput

/NE-dispatch {  % draw one of three nitzer ebb logos, depending on albumname.
  albumname1 (That Total Age) eq
  { NE3 }
  { albumname1 (Belief) eq
    { NE-belief }
    { NE-star-and-gear }
    ifelse
  }
  ifelse
} bdef

/NE3 {  % Nitzer Ebb "That Total Age" logo.
  gsave
    -0.175 0.5 0.35 1 box fill
    0.5 setgray
    /s 0.3 def
    gsave 0 -0.3333 translate s s scale
     NE-hammer grestore
    gsave s s scale
     starpath fill grestore
    gsave 0 0.3333 translate s s scale
     NE-gear grestore
  grestore
  } bdef

/NE-gear {
  gsave
    0.1 setlinewidth
    0 0 0.375 0 360 arc stroke
    0 1 8
     { -0.075 0.5 0.15 0.1 box fill
       45 rotate
     } for
  grestore
  } bdef

/NE-hammer {
  gsave
    0.05 0 translate
    45 rotate
    -0.1 0.4 0.2 0.85 box fill
    -0.3 0.4 0.45 0.2 box fill
     0.15 0.4 moveto
     0.35 0.2 lineto
     0.15 0.2 lineto
     closepath fill
  grestore
  } bdef

/starpath {
  newpath 0 0.5 moveto
  0 1 4 { 144 rotate 0 0.5 lineto } for
  closepath
  } bdef


/NE-star-and-gear {  % Nitzer Ebb "Warsaw Ghetto" logo.
  gsave
   0.8 0.8 scale
   NE-split-gear
  grestore
  NE-split-star
  } bdef

/NE-split-star {
  gsave
    0.02 setlinewidth
    0 setgray starpath stroke
    starpath clip newpath
    0 setgray 0 0.5 0.5 1 box fill
    1 setgray -0.5 0.5 0.5 1 box fill
  grestore
  } bdef

/NE-gear-path {
    0 0.5 moveto
    0 1 11
      { -0.075 0.5 lineto
        -0.075 0.45 lineto
        30 rotate
         0.075 0.45 lineto % ## make this a curveto!!
         0.075 0.45 lineto
         0.075 0.5 lineto
      } for
    closepath
  } bdef


/NE-split-gear {
  gsave
    % I tried doing this with eopath, but it doesn't work in Amiga Post 1.1.
    0.005 setlinewidth
    0 setgray
    NE-gear-path stroke
    NE-gear-path clip newpath
    -0.5 0.5 0.5 1 box fill
    1 setgray 0.4 0 moveto 0 0 0.4 0 360 arc fill
    0 setgray 0.4 0 moveto 0 0 0.4 0 360 arc stroke
  grestore
  } bdef

%% What follows is a bitmap of the "grainy eye" image from "Belief".
%% Digitized on an Amiga, converted to PS with Jef Poskanzer's PBM toolkit.
%% I would have stored the bitmap run-length encoded, but that would have
%% taken some work, as the only rle-decoders I have expect to draw the image
%% as they decode, and not store it away for future use as we do here.
%%
/NE-belief {
  gsave
  0.8 0.8 scale
  -0.5 -0.5 translate
  82 71 1
  [ 82 0 0 -71 0 71 ]
  %% 28 lines of bitmap data... pinhead representation (tm).
  {<000000000000000000003f000000000000000000003f000000000000000000003f00000000
   0000000000003f000000000000000000003f03ffffffffffeffff0003f03ffffffdf3fffffb
   0003f03fffff800002ff661003f03ffffe00000060ffb003f03ffff8000000001fc003f007f
   fc00000000067c003f007fe000000000001d803f001f00000000000008203f0000000000000
   00006003f000000000000000004003f0000000000001e0000003f0000000000003f8000003f
   0000000000007d0000003f000000000000390000003f000000000000000000003f000000000
   000000000003f000000000000000000003f000000000000000000003f000000002000000000
   003f0000000ff000000000003f0000001fe006000000003f0000003f8046000000003f02000
   07fc1c6000000003f0200007fb780000000403f0300007fc70800000f803f0300003ff03040
   0008883f030001ffffff800018003f0380004ffffe0001f8003f03800007fffc0003fc003f0
   380001780000053f4003f03800001c8000197f7003f03800001f80001fffe003f03800046c0
   0037ffbf003f03800007f801ffffff803f0380000ffffffffff0003f03800003fffffffffe0
   03f03800002fffffffffe003f03c00000fffffffff8003f03c00000fffffffff8003f03c000
   01fffffffff0003f03c000007ffffffff0003f03c000001ffffffff0003f03c000007ffffff
   fe0003f03c00000ffffffffe0003f03e000007fffffffe0003f03e000003fffffff40003f03
   e000001fffffff80003f03e000001ffffffd80003f03f0000003fffffe00003f03f0000001f
   ffffc00003f03f0000001fffffc00003f03f0000000fffffc00003f03f00000017ffff80000
   3f03f0000001fffffc00003f03f0000000fffff800003f03e0000000fffff800003f03e0000
   0003ffff000003f03e000000017fff000003f0300000000179fe000003f02000000001f0ae0
   00003f000000000001000000003f0000000000007f0000003f000000000000000000003f000
   000000000000000003f000000000000000000003f000000000000000000003f000000000000
   000000000000000000000000000000000000000000000000000000000000000000000000000
   000000000000000000000000000000000000000000000000000000000000000000000000000
   000000000000000000000000000000000000000000000000000000000000000000000000000
   000000000000000000000000000000000000000000000000000000000000000000000000000
   000000000000000000000000000000000000000000000000000000000000000000000000000
   000000000000000000000000000000000000000000000000000000000000000000000000000
   000000000000000000000000>}
  image
  grestore
  } bdef

magic-icon-dict (Nine Inch Nails) cvn { NiN } CIput

/NiNbox {
   gsave
    0.7 0.7 scale
    /Helvetica-Bold findfont [ 1 0 0 1 0 0] makefont
    /Helvetica-Bold findfont [-1 0 0 1 0 0] makefont
    dup setfont
    (NIN)stringwidth pop 2 div -0.3 translate
    0 0 moveto
    /Nw (N)stringwidth pop neg def
    Nw 0 rmoveto (N)show Nw 0 rmoveto
    exch dup setfont (IN)show exch
    0.1 setlinewidth
    -0.1 -0.15 Nw (IN)stringwidth pop add 0.2 add -1.05 box stroke
    pop pop
    grestore
} bdef


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%EndProlog


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		Begin Example-Land.			%%%%%%%%
%%%%%%%		Modify what lies after this point.		%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%% Set this string to what you want printed on the back flap, or an array
%% of strings (one string per line).
%%
/signature (From the Jamie Zawinski Collection of Fine Tapes) def

/band-font /Helvetica def		% The font for band-names.
/album-font /Helvetica def		% The font for album-names.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  An example of the normal case: two albums by one band,	%%%%%%%%
%%%%%%  with one album on each side of the tape.		%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

(Gang of 4)		(Entertainment)		(1979)
			(Solid Gold)		(1981)

[(Ether)
 (Natural's not in it)
 (Not Great Men)
 (Damaged Goods)
 (Return the Gift)
 (Guns before Butter)
 ()
 (I Found that Essence Rare)
 (Glass)
 (Contract)
 (At Home He's a Tourist)
 (5:45)
 (Anthrax)
 ()
 (To Hell With Poverty)
 (Capital it Fails Us Now)
 ]
[(Paralysed)
 (What we All Want)
 (Why Theory)
 (If I could keep it for myself)
 (Outside the trains don't run on time)
 ()
 (Cheeseburger)
 (The Republic)
 (In the Ditch)
 (A Hole in the Wallet)
 (He'd send in the Army)
 ]
two-albums


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  An example of a double album, which consumes both sides	%%%%%%%%
%%%%%%  of the tape.  Also an example of the automatic "magic	%%%%%%%%
%%%%%%  printer" feature, since the band name is known.		%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

(Front 242)		(Backcatalogue)		(1982-1985)

[[(U-Men (LP mix))		(3:12)]
 [(Geography II)		(1:08)]
 [(Kampfbereit)			(3:18)]
 [(Operating Tracks)		(3:48)]
 [(Geography I)			(2:16)]
 [(Take One)			(4:45)]
 [(Controversy Between)		(4:54)]
 [(Sample D)			(3:15)]
 ]
[[(Nomenklatura I)		(4:24)]
 [(Nomenklatura II)		(2:10)]
 [(Lovely Day)			(5:26)]
 [(Special Forces)		(5:30)]
 [(Commando Remix)		(9:03)]
 [(No Shuffle (single mix))	(3:45)]
 [(Don't Crash)			(4:51)]
 [(Funkahdafi)			(3:15)]
 [(Take One (live))		(5:00)]
 ]
double-album


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  An example of a double album, which consumes both sides	%%%%%%%%
%%%%%%  of the tape.  The band name and album name are printed  %%%%%%%%
%%%%%%  in different fonts.                                     %%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

album-font band-font		    % push the current values on the stack.
/band-font /Courier-Bold def	    % redefine the album and band fonts.
/album-font /Times-Italic def

(bauhaus)   	    	(1979-1983) ()
[(Kick in the Eye)
 (Hollow Hills)
 (In Fear of Fear)
 (Ziggy Stardust)
 (Silent Hedges)
 (Crack the Whip)
 (Third Uncle)
 (Spirit)
 (All We Ever Wanted was Everything)
 (She's in Parties)
 (Sanity Assassin)
 (untitled)
 ]
[(Double Dare)
 (In the Flat Field)
 (Dark Entries)
 (Stigmata Martyr)
 (Bela Lugosi's Dead)
 (Telegram Sam)
 (St. Vitus Dance)
 (Spy in the Cab)
 (Terror Couple Kills Colonel)
 (The Passion of Lovers)
 (Mask)
 ]
double-album	      	    	    	% print the album...

/band-font exch def			% restore the fonts to the values that
/album-font exch def			% we pushed on the stack a while ago.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  An example of three albums by one band that happen to	%%%%%%%%
%%%%%%  fit on one tape - one album on the front and two on	%%%%%%%%
%%%%%%  the back.						%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

(Shriekback)
  (Jamscience)	()					(1984)
  (Tench)	(Knowledge, Power, Truth and Sex)	(1982, 1984)

[(Under the Lights)
 (Building Up a New Home)
 (Hand on my Heart)
 (International)
 (Putting on the Pressure)
 (Party Line)
 (My Careful Hands)
 (Midnight Maps)
 ()
 (Working on the Ground)
 (Lined Up (instrumental))
 (Hapax Legomena)
 ]
[(Sexthinkone)
 (A Kind of Fascination)
 (All the Greek Boys)
 (Moth Loop)
 (Here Comes my Hand: Clap)
 ()
 [(Knowledge, Power, Truth and Sex) /Title]
 (Mercy Dash)
 (Achtung)
 (Hubris)
 (Suck)
 (Nerve)
 (Mistah Linn He Dead)
 ]

N-albums

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  An example of two albums, each by different bands, with	%%%%%%%%
%%%%%%  one album on each side of the tape.			%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

(Revolting Cocks)	(Big Sexy Land)		(1986)

[[(38)					  (4:10)]
 [(We Shall Cleanse the World)		  (5:34)]
 [(Attack Ships on Fire)		  (4:55)]
 [(Big Sexy Land)			  (3:57)]
 [(Union Carbide (West Virginia version)) (3:20)]
 [(TV Mind)				  (5:39)]
 [(No Devotion)				      ()]
 [(Union Carbide (Bhopal version)) 	  (3:39)]
 [(You Often Forget (Malignant)) 	  (8:28)]
 ]

(Sisters of Mercy)	(Floodland)		(1988)

[[(Dominion/Mother Russia)		  (7:01)]
 [(Flood I)				  (6:22)]
 [(Lucretia My Reflection)		  (4:57)]
 [(1959)				  (4:09)]
 [(This Corrosion)	       		 (10:55)]
 [(Flood II)				  (6:47)]
 [(Driven Like the Snow)		  (6:27)]
 [(Neverland (a Fragment))		  (2:46)]
 ]
two-bands

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  An example of several EPs and singles by one band on	%%%%%%%%
%%%%%%  both sides of a tape.  Also, the band-name is printed	%%%%%%%%
%%%%%%  in a different font for this one.			%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

band-font			% push band-font on the stack..
/band-font /Times-Roman def	% change it...

(THE ART OF NOISE)
	(Who's Afraid of the Art of Noise?)	(Beatbox. Paranoimia.)  ()
	(The Art of Noise have Closed Up.)	(Legs. Peter Gunn.)	()

[[(A Time for Fear (Who's Afraid?))	(1984)]
 [(Beatbox (Diversion One))		()]
 [(Snapshot)				()]
 [(Close to the Edit)			()]
 [(Who's Afraid (of the Art of Noise?))	()]
 [(Momento)				()]
 [(How to Kill)				()]
 [(Realization)				()]
 [()					()]
 [(Beatbox (Battle))			(1983)]
 [(The Army Now)			()]
 [(Donna)				()]
 [(Bright Noise)			()]
 [(Moments in Love)			()]
 [()					()]
 [(Legs)				(1985)]
 ]
[[(Closely Closely (Enough's Enough!))	(1984)]
 [(Close Up (Hop))			()]
 [(A Time to Hear (Who's Listening?))	()]
 [()					()]
 [(Hoops and Mallets)			(1985)]
 [(Legs (Inside Legmix))		()]
 [()					()]
 [(Paranoimia (Headroom Mix))		(1986)]
 [(Why Me?)				()]
 [(A Nation Rejects)			()]
 [()					()]
 [(Peter Gunn Theme)			(1986)]
 [(Something Always Happens)		()]
 [()					()]
 [(Beatbox (Battle))			(1983)]
 ]
N-albums			% print the label...

/band-font exch def		% set band font back to what it was before.


%%Trailer
%%  This form should always be here at the end, to make sure that the
%%  final page is dumped even if there are an odd number of labels
%%  being printed.
%%
tick { showpage } if