Path: seismo!harvard!husc6!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: PostScript sticky label program Message-ID: <1799@panda.UUCP> Date: 5 May 86 14:06:26 GMT Sender: jpn@panda.UUCP Reply-To: liam@qmc-cs.UUCP (William Roberts) Organization: CS Dept, Queen Mary College, University of London, UK. Lines: 635 Keywords: postscript label Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 96 Submitted by: talcott!seismo!mcvax!cs.qmc.ac.uk!liam # This is a shar archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #--------cut--------cut--------cut--------cut--------cut-------- #! /bin/sh # shar: Shell Archiver # Run the following with /bin/sh to create: # README # background.test # sticky # sticky.1 # sticky.awk # sticky.ps # sticky.test # This archive created: Wed Apr 30 13:36:08 BST 1986 echo shar: extracting "README" '('1719 chars')' if test -f README then echo shar: will not overwrite existing file "README" else cat << \SHAR_EOF > README This directory contains software, example and manual page for a program which produces PostScript commands for printing address labels, conference badges etc. I believe that this system is a good example of how to write simple X-to-PostScript filters: essentially you do most of the programming in the PostScript prologue and do only minimal re-arrangement to input data. In many cases the re-arrangement is so easy that you only need an awk script and/or a few other Unix tools. The files are: sticky.1 - the manual page. This should be comprehensive enough for you to run the program. sticky.awk - An awk(1) script that translates the input data into the appropriate PostScript commands. sticky.ps - A PostScript prologue (set of sub-routines) which define all the routines used by the output from the awk script. sticky - A sh(1) script which outputs sticky.ps, then runs the sticky.awk on its arguments. sticky.test - A demonstration of the simple label features and the formatting capability. Type sticky stick.test and send the output to your PostScript printer. background.test - A demonstration of the labels-with-backgrounds advanced features of the program. Run as per the other .test file. REMARK: The sticky command is too complicated really: I shouldn't have added to "BACKGROUND" facility to this general-purpose system. Quick, distribute it before I get second thoughts.... William Roberts ARPA: liam@UK.AC.qmc.cs Queen Mary College UUCP: liam@qmc-cs.UUCP LONDON, UK SHAR_EOF if test 1719 -ne `wc -c < README` then echo shar: error transmitting "README" '('should be 1719 chars')' else echo README fi fi echo shar: extracting "background.test" '('217 chars')' if test -f background.test then echo shar: will not overwrite existing file "background.test" else cat << \SHAR_EOF > background.test FORMAT 2 HB 14 centre 14 H 14 centre 4 H 10 centre BACKGROUND logo (blank) SPEAKER Computer Turkeysetting Conference Anne Robbins Bernard Matthews William Roberts Frances Shipsey Angus Phillips Ann Nursey SHAR_EOF if test 217 -ne `wc -c < background.test` then echo shar: error transmitting "background.test" '('should be 217 chars')' else echo background.test fi fi echo shar: extracting "sticky" '('134 chars')' if test -f sticky then echo shar: will not overwrite existing file "sticky" else cat << \SHAR_EOF > sticky #! /bin/sh # LaserWriter version of the "sticky" labels program DIR=. AWK=sticky.awk PS=sticky.ps cat $DIR/$PS; awk -f $DIR/$AWK $* SHAR_EOF if test 134 -ne `wc -c < sticky` then echo shar: error transmitting "sticky" '('should be 134 chars')' else echo sticky fi fi echo shar: extracting "sticky.1" '('3621 chars')' if test -f sticky.1 then echo shar: will not overwrite existing file "sticky.1" else cat << \SHAR_EOF > sticky.1 .TH STICKY 1 "29 April 1982" .SH NAME sticky \- generate PostScript for address labels .SH SYNOPSIS .B sticky [ .B file .... ] .SH DESCRIPTION The .I file is converted into PostScript that will print it as address labels, suitable for use with sticky label stationery (hence the name!). Standard input will be used if .I file is ``-'' or no arguments are given. .PP Each label will have one address on it; each address is a sequence of non-blank lines from the file, terminated by a blank line or the end of the file. Lines consisting of just the .I troff(1) directive ``.nf'' are ignored. .PP If the first line of an address is the word ``FORMAT'', the address is used as a label format description. This description consists of a number of line formats which are used for the successive lines of each subsequent address. If an address has more lines than the current format description, the last line of the description is re-used for the extra lines (rather like the line formats in .IR tbl(1) ). Each line format has the following structure: .I .ce gap fontcode pointsize style .ft P .TP .I gap The gap to leave between the top of this line and the bottom of the previous line (or the top of the label) in points. 2 is a good number for this. .TP .I fontcode The .I troff(1) code for the font to use on this line (e.g. R, B, HO etc). .TP .I pointsize The pointsize of the text for this line. .TP .I style The layout style of the line; one of ``left'', ``right'' or ``centre''. The text will be aligned against the lefthand edge, the righthand edge or centred in the label respectively. .PP Addresses with a first line beginning with the word ``BACKGROUND'' are used to define a fixed part of the label. The rest of the first line is executed (as a PostScript procedure) whenever a subsequent label is printed. The rest of the address is taken to be fixed text and is printed as per the current format at the time the BACKGROUND command is issued. Subsequent changes to the format will not affect the background. An address line consisting of the just word ``(blank)'' results in a blank line in the PostScript version of the address, and is particularily useful when defining the background for labels. .SH EXAMPLES The default format is .in +0.5i .nf .ne 2 FORMAT 2 R 12 left. .in A pleasing effect with the first line in large italics, a gap before the second line and subsequent lines in smaller type is given by .in +0.5i .nf .ne 4 FORMAT 2 HO 14 left 4 H 12 left 2 H 12 left .fi .in Conference badges could be produced with .in +0.5i .nf .ne 4 FORMAT 20 HB 15 centre 8 HO 8 centre 2 HO 8 centre .fi .in To produce conference badges with some fixed text and a logo (the ``turkey'' from the PostScript CookBook, but you could define your own!), use .in +0.5i .nf .ne 4 FORMAT 2 HB 14 centre 14 H 14 centre 4 H 10 centre .ne 4 BACKGROUND logo (blank) SPEAKER Computer Turkey-Setting Conference Mr First Speaker Miss Second Speaker etc.... .fi .in .SH FILES .TP 2.5i /usr/local/lib/sticky/sticky.ps The PostScript prologue, including label size & layout on page. .TP /usr/local/lib/sticky/sticky.awk Awk(1) script for converting addresses to PostScript and handling the font name conversion. .SH "SEE ALSO" awk(1), troff(1), tbl(1). .SH "CUSTOMISING" The PostScript prologue can be modified to cope with specific types of label. New line formats can be added, as can additional procedures for use with the BACKGROUND facility. The safest way to do this is to copy and modify the existing routines. .SH "AUTHOR" .nf William Roberts Department of Computer Science Queen Mary College LONDON, UK .fi SHAR_EOF if test 3621 -ne `wc -c < sticky.1` then echo shar: error transmitting "sticky.1" '('should be 3621 chars')' else echo sticky.1 fi fi echo shar: extracting "sticky.awk" '('2185 chars')' if test -f sticky.awk then echo shar: will not overwrite existing file "sticky.awk" else cat << \SHAR_EOF > sticky.awk BEGIN { ADDRESS = "FALSE"; FORMAT="FALSE"; BACKGROUND="FALSE" FONTNAME["R"] = "/Times-Roman"; FONTNAME["I"] = "/Times-Italic"; FONTNAME["B"] = "/Times-Bold"; FONTNAME["BI"] = "/Times-BoldItalic"; FONTNAME["H"] = "/Helvetica"; FONTNAME["HO"] = "/Helvetica-Oblique"; FONTNAME["HB"] = "/Helvetica-Bold"; FONTNAME["HD"] = "/Helvetica-BoldOblique"; FONTNAME["C"] = "/Courier"; FONTNAME["CO"] = "/Courier-Oblique"; FONTNAME["CB"] = "/Courier-Bold"; FONTNAME["CD"] = "/Courier-BoldOblique"; } $1 == ".nf" \ { next } $1 == "FORMAT" && NF == 1 \ { FORMAT = "TRUE"; printf "[\n"; next } $1 == "BACKGROUND" \ { printf "/BackgroundProcs {"; for(i=2; i<=NF; i++) printf "%s ", $i; printf "} def\n[\n"; BACKGROUND = "TRUE"; next; } NF == 0 || ( NF == 1 && $1 == " ") \ { if (ADDRESS == "TRUE") printf "] def DoIt\n"; ADDRESS = "FALSE"; if (FORMAT == "TRUE") printf "] define_format\n\n"; FORMAT = "FALSE"; if (BACKGROUND == "TRUE") printf "] define_background\n\n"; BACKGROUND = "FALSE"; next; } # Format line is: pre-line_gap font pointsize line_style FORMAT == "TRUE" \ { FONT = FONTNAME[$2]; STYLE = $4; if ($4 == "center") STYLE = "centre"; printf "{ %d %s %d %s }\n", $1, FONT, $3, STYLE; next; } ADDRESS == "FALSE" && NF == 2 && $2 == "TIMES" \ { printf "/Repeat_count %d def\n", $1; printf "/Text [\n"; ADDRESS = "TRUE"; next; } ADDRESS == "FALSE" && BACKGROUND == "FALSE" \ { printf "/Text [\n"; ADDRESS = "TRUE"; } # all non-empty lines { if ($1 == "(blank)" && NF == 1 ) printf " ()\n"; else printf " (%s)\n", $0; } END { if (ADDRESS == "TRUE") printf "] def DoIt\n"; if (BACKGROUND == "TRUE" || FORMAT == "TRUE" ) printf "] pop\n"; printf "AllDone\n"; } SHAR_EOF if test 2185 -ne `wc -c < sticky.awk` then echo shar: error transmitting "sticky.awk" '('should be 2185 chars')' else echo sticky.awk fi fi echo shar: extracting "sticky.ps" '('3888 chars')' if test -f sticky.ps then echo shar: will not overwrite existing file "sticky.ps" else cat << \SHAR_EOF > sticky.ps %!PS-ADOBE-1.0 %%Pages: ? % Handle "sticky"-style labels /mm { 2.83465 mul} def % according to the CookBook /Label_Depth 37.3 mm def /Label_Width 104.5 mm def /Useable 0.8 def % useable depth,width /rows 7 def /cols 2 def /fine_tune {3 mm -12.5 mm translate} def % fine tune the positioning %%%%%%%%%%%%%%%%%%%%%%%%%% PostScript Routines %%%%%%%%%% fine_tune /Label { Label_Depth mul exch Label_Width mul exch } def /Label_Boundary { 1 0 Label rlineto 0 1 Label rlineto -1 0 Label rlineto 0 -1 Label rlineto } def /UnUseable 1 Useable sub 2 div def /labelrow 1 def /labelcol 1 def /DoIt % Argument: array of strings { Repeat_count { gsave labelcol 1 sub rows labelrow sub Label moveto currentpoint translate gsave Label_Boundary clippath % clip to label boundary UnUseable Useable UnUseable add Label moveto % Top Left of label gsave Background { BackgroundProcs BackDict begin PrintText end} if grestore PrintText grestore /labelcol labelcol 1 add def % increment column labelcol cols gt { /labelcol 1 def /labelrow labelrow 1 add def % increment row labelrow rows gt { showpage /labelrow 1 def % new page } if } if grestore } repeat /Repeat_count 1 def % reset multiplication count } def /AllDone { labelcol 1 eq labelrow 1 eq and not % not (row=1 & col=1) { showpage } if % print final page } def /define_format % arg: array of {line format} { /Format exch def /Format_max Format length 1 sub def } def %% Local format routines: centre, left, right %% /centre % args: string gap font ps { /ps exch def findfont ps scalefont setfont 0 exch neg rmoveto dup stringwidth pop Label_Width Useable mul exch sub 2 div ps neg gsave rmoveto show grestore 0 ps neg rmoveto % go down the vertical spacing amount } def /left % args: string gap font ps { /ps exch def findfont ps scalefont setfont 0 exch neg rmoveto 0 ps neg gsave rmoveto show grestore 0 ps neg rmoveto % go down the vertical spacing amount } def /right % args: string gap font ps { /ps exch def findfont ps scalefont setfont 0 exch neg rmoveto dup stringwidth pop Label_Width Useable mul exch sub ps neg gsave rmoveto show grestore 0 ps neg rmoveto % go down the vertical spacing amount } def %% Definitions for handling backgrounds %% /define_background % arg: array of {text} for current format { /Background true def % flag existence of background BackDict /Format Format put BackDict /Format_max Format_max put BackDict begin /Text exch def end } def %% BackgroundProc definitions %% %% logo is a silly example that prints the CookBook "turkey" in %% one corner of the label. /logo % Silly example of a BackgroundProc { gsave currentpoint translate 0 -20 translate 20 -20 scale {1 exch sub} settransfer 24 23 1 [24 0 0 23 0 -23] {<003B00 002700 002480 0E4940 114920 14B220 3CB650 75FE88 17FF8C 175F14 1C07E2 3803C4 703182 F8EDFC B2BBC2 BB6F84 31BFC2 18EA3C 0E3E00 07FC00 03F800 1E1800 1FF800>} image grestore } def /PrintText { gsave 0 1 Text length 1 sub %for i=0 to length(Text) -1 { dup Text exch get % extract the string exch dup Format_max gt % still within format? {pop Format_max} if % re-use last format line if necessary Format exch get exec % perform the format command } for grestore } def %% Default Label Format, Background & repetition count /Repeat_count 1 def [ { 2 /Times-Roman 12 left } ] define_format /Background false def % no background /BackDict 15 dict def % dictionary for the data SHAR_EOF if test 3888 -ne `wc -c < sticky.ps` then echo shar: error transmitting "sticky.ps" '('should be 3888 chars')' else echo sticky.ps fi fi echo shar: extracting "sticky.test" '('868 chars')' if test -f sticky.test then echo shar: will not overwrite existing file "sticky.test" else cat << \SHAR_EOF > sticky.test Mr David G Small High Level Hardware Ltd PO Box 170 Windmill Road Oxford OX3 7BN FORMAT 2 B 14 left 8 I 12 left 2 I 12 left Mr Paul Farmer Syntek Ltd Fanum House 48 Leicester Square London WC2H 7BY Mr F.J. Tucker Ernst & Whinney Beckett House 1 Lambeth Palace Road London EC1 FORMAT 2 HO 10 centre 6 HO 10 centre 2 HO 10 centre Mr F.J. Tucker Ernst & Whinney Beckett House 1 Lambeth Palace Road London EC1 FORMAT 4 CO 12 right Mr F.J. Tucker Ernst & Whinney Beckett House 1 Lambeth Palace Road London EC1 FORMAT 2 I 14 left 4 R 12 left 2 R 12 left Mr David G Small High Level Hardware Ltd PO Box 170 Windmill Road Oxford OX3 7BN Mr F.J. Tucker Ernst & Whinney Beckett House 1 Lambeth Palace Road London EC1 3 TIMES Sue White Research Co-ordinator Department of Computer Science & Statistics Queen Mary College Mile End Road LONDON E1 4NS SHAR_EOF if test 868 -ne `wc -c < sticky.test` then echo shar: error transmitting "sticky.test" '('should be 868 chars')' else echo sticky.test fi fi # End of shar archive exit 0