nametag.pl

Leslie Mikesell les at chinet.chi.il.us
Wed Dec 5 05:53:36 AEST 1990


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 at chinet.chi.il.us   or  les at 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";



More information about the Alt.sources mailing list