home *** CD-ROM | disk | FTP | other *** search
- From: les@chinet.chi.il.us (Leslie Mikesell)
- Newsgroups: comp.lang.perl,alt.sources
- Subject: nametag.pl
- Message-ID: <1990Dec04.185336.4946@chinet.chi.il.us>
- Date: 4 Dec 90 18:53:36 GMT
-
-
- I haven't been able to find a generic mail-merge routine that forces
- the merged text to fit into certain spaces, so I wrote this...
-
- This program generates postscript code for nametags with the text
- centered and scaled to fit into the appropriate spots (for our
- nametag stock). I normally run it as part of a spooler printer
- interface program, but it can be run as a stand-alone operation.
-
- Bugs:
- It should probably read a parameter file to get the positioning info,
- but with an interpreted language it is just as easy to edit the
- script - at least for the person who wrote it.
- The whole operation could doubtlessly be done in postscript
- by someone with a stack-oriented brain. In retrospect it was a bad
- idea to try to hit a pre-printed bar exactly (although the color
- does give a nice effect). I've had to adjust the $YSLIDE variable
- as much as 12 points to compensate for different printers.
- ---
- Les Mikesell
- les@chinet.chi.il.us or les@fb.com
-
- # ---- cut here --------
- # nametag.pl
- # Perl program to generate postscript program....
- # execute with:
- # perl nametag.pl file...
- # or pass the input on stdin - output is to stdout
- # This is set up for pre-printed nametag stock 2 across, 3 down
- # with a logo at the top and a red bar near the bottom on each,
- # but it should work to change the constants for other layouts.
- #
- # print nametags from files in format:
- # line1|line2|line3|line4|line5
- # ... (each line contains the data for one nametag, up to 5 lines
- # using "|" as the delimiter for lines on the tag)
- #
- # if line2 is empty, line3 moves up
- # line4 prints in 14 pt italic just above red bar
- # line5 lands on red bar (red bar refers to a position near the bottom)
- #
- # blank lines are ignored
- # a form-feed in the file ejects the current page (for easier
- # grouping for distribution)
- # otherwise pages are filled (6/page) until the end of file is reached
- #
- # Procedure tline:
- # Fonts are selected by first attempting ch1 (choice 1 below) in its
- # specified size. If it is too wide, an attempt is made using ch2.
- # If it still doesn't fit, ch2 is rescaled to make it fit.
- # Iline does the same with fonts ch3 and ch4 for italics.
- # starting point size is imbedded in the perl code:
- # 24pt for lines 1,2,3, 14 pt for line 4, 20 pt for line 5
- #
-
- # ---- positioning info -----
- # column layout
- $COLS=2 ;
- $ROWS=3 ;
- # -- these numbers are postscript units --
- # -- adjust this number for vertical allignment --
- $YSLIDE= 1; # may need to tweak for printer
-
- # -- starting points --
- $X1=25; # indent to 1st printing posn
- $Y1=687 + $YSLIDE ; # top line vertical posn
- $Y4=601 + $YSLIDE ; # above red bar
- $Y5=572 + $YSLIDE ; # red bar
- $DX=286; # add for 2nd col
- $DY=264; # sub for 2nd, 3rd rows
- $LINE=30; # sub for 2nd,3rd lines
- $WIDTH = $DX -10; # max space to fill
- # ----
- # This is the postscript header with some definitions
- # -- ch1 def sets first font choice, ch2 is used if 1st attempt is too wide
- # -- likewise ch3 & ch4 for italics
- $HD='%!
- % 1st, 2nd tries for tline
- /ch1 { /Helvetica-Bold findfont exch scalefont setfont} def
- /ch2 { /Helvetica-Narrow-Bold findfont exch scalefont setfont} def
- % 1st, 2nd tries for iline
- /ch3 { /Helvetica-BoldOblique findfont exch scalefont setfont} def
- /ch4 { /Helvetica-BoldOblique findfont exch scalefont setfont} def
- % x y width string max-pts
- % pick a font that lets string fit in width (ch1, ch2 pair)
- % center within the space
- /tline
- {
- /pts exch def
- /str exch def
- /wd exch def
- /y1 exch def
- /x1 exch def
- % try 1st choice
- pts ch1
- str stringwidth pop wd gt {
- % did not fit - try 2nd choice font
- pts ch2
- /sw str stringwidth pop def
- sw wd gt {
- % still did not fit - rescale
- currentfont wd sw div scalefont setfont
- }if
- }if
- % center within space and print
- wd str stringwidth pop sub 2 div x1 add y1 moveto str show
- }def
-
- % x y width string max-pts
- % same w/italic font (ch3, ch4 choices)
- % center within the space
- /iline
- {
- /pts exch def
- /str exch def
- /wd exch def
- /y1 exch def
- /x1 exch def
- % try 1st choice
- pts ch3
- str stringwidth pop wd gt {
- % did not fit - try 2nd choice font
- pts ch4
- /sw str stringwidth pop def
- sw wd gt {
- % still did not fit - rescale
- currentfont wd sw div scalefont setfont
- }if
- }if
- % center within space and print
- wd str stringwidth pop sub 2 div x1 add y1 moveto str show
- }def
-
- ';
-
- $CCOL=-1;
- $CROW=0;
-
- printf "%s",$HD; #postscript program
- $NEWPAGE=1;
- $NPAGE=0;
- while (<>) { # read input line
- if (/\f/) { # go to different page
- $NEWPAGE = 1;
- s/\f//; # likely not to be a newline after formfeed
- }
- s/\r//; # ignore carriage returns
- chop; # remove linefeed
- if (/^ *$/) { next;} # skip blank lines
- # "(" in text must be "\(" in postscript output
- s/\\/\\\\/g; # I hate it when this happens...
- s/\(/\\(/g;
- s/\)/\\)/g;
- #
- # print $CCOL; #..for debugging only
- # print "\n";
- # print $CROW;
- # print "\n";
- if ($NEWPAGE > 0) { # starting a page
- $CCOL = $COLS -1;
- $CROW = $ROWS -1;
- }
- if (++$CCOL == $COLS) {
- $CCOL = 0;
- if (++$CROW == $ROWS) {
- $CROW = 0;
- if ($NPAGE++ > 0 ) {
- printf "%s\n","showpage"; # eject previous page
- }
- printf "%% page %d\n",$NPAGE; # sometimes handy to know
- $NEWPAGE = 0;
- }
- }
- # calc x y coordinates for this one
- $LX = $X1 + $CCOL * $DX;
- $LY1 = $Y1 - $CROW * $DY;
- $LY2 = $LY1 - $LINE;
- $LY3 = $LY2 - $LINE;
- $LY4 = $Y4 - $CROW * $DY;
- $LY5 = $Y5 - $CROW * $DY;
- # break item into lines
- @LINE=split(/\|/);
- if ($LINE[1] eq "" ) {
- $LY3 = $LY2; # close up if line 2 is blank
- }
- # print the non-blank lines - the number is the initial point size
- # tline uses helvetica, iline is italic
- if ($LINE[0] ne "" ) {
- printf "%d %d %d (%s) 24 tline \n",$LX,$LY1,$WIDTH,$LINE[0] ;
- }
- if ($LINE[1] ne "" ) {
- printf "%d %d %d (%s) 24 tline \n",$LX,$LY2,$WIDTH,$LINE[1] ;
- }
- if ($LINE[2] ne "" ) {
- printf "%d %d %d (%s) 24 tline \n",$LX,$LY3,$WIDTH,$LINE[2] ;
- }
- if ($LINE[3] ne "" ) {
- printf "%d %d %d (%s) 14 iline \n",$LX,$LY4,$WIDTH,$LINE[3] ;
- }
- if ($LINE[4] ne "" ) {
- printf "%d %d %d (%s) 20 tline \n",$LX,$LY5,$WIDTH,$LINE[4] ;
- }
- }
-
- printf "%s\n%% end of page %d\n","showpage",$NPAGE;
- # you may or may not need a control-D here, depending on whether
- # or not something else handles postscript EOF
- # uncomment the next line if you need it
- # print "\004";
-