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

jwz@teak.berkeley.edu (Jamie Zawinski) (05/09/90)

Well, the response to this has been overwhelming...  After my post
yesterday morning, I've gotten thirty requests for it...  

So here it is.  Let me know what you think, and send me any improvements
you make, and any graphic band-names that you integrate into it.

---------------------------- audio-tape.ps ----------------------------
%!

%%%%  PostScript code to generate audio-tape labels.  Version 1.1.
%%%%
%%%%  Copyright (c) 1990 Jamie Zawinski (jwz@teak.berkeley.edu or
%%%%  jwz@spice.cs.cmu.edu).
%%%%
%%%%  Permission granted for non-commercial use and distribution
%%%%  so long as this notice of copyright remains intact. (fnord)

%% 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.
%%
%% Syntax:
%%
%% 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, [ <songs> ] is 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
%%    [ (song N)  (song N time) ]]	name 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.
%%
%% 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.  The name
%% of the album is printed above the song lists.  When there are more than
%% two albums on a tape, only the names of albums 1.1 and 2.1 are printed
%% on the inside, though all three or four appear on the spine.  This is 
%% sub-optimal.
%%
%% It is possible to include arbitrary graphics in place of the band-name
%% on the spine, to duplicate a band's preferred icon, or whatever.
%% Simply define a procedure for drawing the graphic, 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 here (whether I
%% like the band or not :-)).
%%
%% One problem I encountered with this code was that my co-worker's tapes
%% 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.
%%
%% The fonts of various things can also be easily tweaked.
%%
%% Questions?  Comments?  Suggestions?  Improvements?  Send them to me at the
%% above addresses.  "Please, no applause, just throw money."
%%
%% Enjoy...

/box {
  /h exch def /w exch def
  /y exch def /x exch def
  newpath
  x y moveto w 0 rlineto
  0 h neg rlineto w neg 0 rlineto
  closepath
} def

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

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

/max {
  /a exch def /b exch def
  a b gt { a } { b } ifelse
  } def

/max-stringwidth {
  /stringb exch def
  /stringa exch def
  stringa stringwidth pop
  stringb stringwidth pop
  max
  } def

%% Default font-names and sizes.  The sizes are stomped at runtime, but the
%% names are the responsibility of the user.
%%
/song-font /Helvetica def
/song-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


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


/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

/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
    0 0 w h box clip
    /x 0 def
    /x2 x w add 5 sub def
    /y song-font-height neg def
    songs { x y moveto
            dup
            0 get show
            x2 y moveto
            1 get rightshow
            /y y song-font-height sub 1 sub def
          } forall
  grestore
 } def


/print-songs {                 % write out both columns of the song listings
  /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
 } def


/set-songfont {	    % compute width of font for song listings.
  /font  song-font findfont song-font-height scalefont  def
  font setfont
  /maxw 0 def
  songs1 { /song exch def
           song 0 get  stringwidth pop
           song 1 get  stringwidth pop  add
	   maxw max
           /maxw exch def
         } forall
  songs2 { /song exch def
           song 0 get  stringwidth pop
           song 1 get  stringwidth pop  add
	   maxw max
           /maxw exch def
         } forall
  /w  inner-width 2 div 5 sub 15 sub def
  maxw w gt
   { font [ w maxw div 0 0 1 0 0 ] makefont setfont }
  if
  } def


/print-two-inner-album-titles {              % write the 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 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 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
 } def


/print-one-inner-album-title {              % write the album title centered above the song listings
  gsave
    /x 10 def
    /y  back-spine-height spine-height add
        margins 3 mul  add
        neg  def
    /w  inner-width 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 def
    maxw w gt
      { font [ w maxw div 0 0 1 0 0 ] makefont setfont }
    if

    gsave
      x y w inner-album-font-height 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
 } def


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


/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 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 box clip
    newpath
    x w 2 div add  y inner-album-font-height sub 2 add  moveto
    date1 centershow
  grestore
 } def


/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
 } def

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


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

    180 rotate
    inner-width neg  spine-height  translate
    
    0 0  inner-width  spine-height  box stroke     % the box around the spine
    0 0  inner-width  spine-height  box clip

    () bandname1 eq () bandname2 eq and		   % If both albumnames are empty strings, then /allowable-width is *2.
      { /allowable-width inner-width 12 sub def }
      { /allowable-width inner-width 2 div 12 sub def }
    ifelse

    /long-name-hack-p false def

    magic-name-p
      { 2  spine-height 2 sub neg  spine-height  magic }
      { /font band-font findfont band-font-height scalefont def
        font setfont
 
	/maxw bandname1 bandname2 max-stringwidth def
        album-font-height band-font-height eq		% if both fonts are the same height
        { /maxw	maxw					% then maxw is sum of width of largest two strings, and
              albumname1 albumname2 max-stringwidth	% allowable-width is doubled.
              albumname3 albumname4 max-stringwidth
             max add 20 add def
	  /allowable-width inner-width 12 sub def
	  /long-name-hack-p true def
	}
        if

        maxw allowable-width  gt
         { font [  allowable-width maxw div  0 0 1 0 0 ] makefont setfont }
        if
 
        5 band-font-height neg moveto
        bandname1 show
        5 band-font-height neg dup add  moveto
        bandname2 show
       }
    ifelse
 
    long-name-hack-p not
    { /font album-font findfont album-font-height scalefont def
      font setfont
      /maxw
        albumname1 albumname2 max-stringwidth
        albumname3 albumname4 max-stringwidth
        max def
      maxw allowable-width gt { font [  allowable-width maxw div  0 0 1 0 0 ] makefont setfont } if
    } if

    /albx inner-width 5 sub def
    /alby album-font-height neg def
    albumname1 () eq not
     { albx alby moveto  albumname1 rightshow
       /alby alby album-font-height sub def }
    if
    albumname3 () eq not
     { albx alby moveto  albumname3 rightshow
       /alby alby album-font-height sub def }
    if
    albumname2 () eq not
     { albx alby moveto  albumname2 rightshow
       /alby alby album-font-height sub def }
    if
    albumname4 () eq not
     { albx alby moveto  albumname4 rightshow
       /alby alby album-font-height sub def }
    if
  grestore
} def


/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
    x w add  y h add neg  translate
    180 rotate
    song-font findfont song-font-height scalefont setfont
    margins  h margins 3 mul sub neg  moveto
    signature show
  grestore
 } def


/reset {		% resets all the strings to be empty.
  /signature () def
  /bandname1 () def
  /bandname2 () def
  /albumname1 () def
  /albumname2 () def
  /albumname3 () def
  /albumname4 () def
  /date1 () def
  /date2 () def
  /magic-name-p false def
  /double-album-p false def
  } def

reset	% do it now to give them their initial values.

/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.

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

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


% A dictionary for storing magic band-name-rendering functions.
%
/magic-name-dict 200 dict def

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


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


/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
} def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		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 20 def
  /album-font-height 13 def
  check-magic
  dump-internal
} def


/two-bands {			% arguments:  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 13 def
  /album-font-height 13 def
  /magic-name-p false def
  dump-internal
} def


/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 20 def
  /album-font-height 20 def
  /double-album-p true def
  check-magic
  dump-internal
} def


/N-albums {			% arguments:  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 20 def

  () albumname3 eq () albumname4 eq and
  { /album-font-height 13 def }
  { () albumname3 eq () albumname4 eq or
    { /album-font-height 10 def }
    { /album-font-height 7 def }
    ifelse }
  ifelse

  check-magic
  dump-internal
} def


/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 13 def

  () albumname3 eq () albumname4 eq and
  { /album-font-height 13 def }
  { () albumname3 eq () albumname4 eq or
    { /album-font-height 10 def }
    { /album-font-height 7 def }
    ifelse }
  ifelse
  /magic-name-p false def
  dump-internal
} def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		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".
%%%
magic-name-dict (Front 242)
	{
	  /sc exch def
	  /y exch def
	  /x exch def
	  gsave
	    x y translate
	    sc sc 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
	}
put

%%% Draw "Orchestral Manoeuveres in the Dark" on two lines; use the
%%% "oe" character.
%%%
magic-name-dict (Orchestral Manoeuveres in the Dark)
	{
	  /sc exch def
	  /y exch def
	  /x exch def
	  gsave
	    x y translate
	    sc 0.7 mul sc 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
	}
put


%%% Draw "OMD" in the same way as "Orchestral Manoeuveres in the Dark".
%%%
magic-name-dict (OMD)
  magic-name-dict (Orchestral Manoeuveres in the Dark) get
put


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

magic-name-dict (New Order)
	{
	  /sc exch def
	  /y exch def
	  /x exch def
	  gsave
	    x y translate
	    sc sc scale
	    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
	}
put


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

magic-name-dict (Siouxsie and the Banshees)
	{
	  /sc exch def
	  /y exch def
	  /x exch def
	  gsave
	    x y translate
	    sc sc scale
	    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
	    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
	}
put

%%% 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.
%%%

magic-name-dict (Cabaret Voltaire)
	{
	  /sc exch def /y exch def /x exch def
	  gsave
	    x y translate
	    /sc sc 0.5 mul def
	    sc sc 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
	}
put

%% 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 } def

/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 } def

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

/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 } def

/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 } def

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

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

/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 } def

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

/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 } def

/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 } def

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

/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 } def



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%    		Begin Example-Land.			%%%%%%%%
%%%%%%%								%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%% Set this string to what you want printed on the back flap.
%%
/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 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)	()]
 [() ()]
 [(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.



%%%%%  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