allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (10/29/89)
Posting-number: Volume 8, Issue 95 Submitted-by: jgreely@cis.ohio-state.edu (J Greely) Archive-name: up This package allows you to print conforming PS files n-up, with the scaling, rotation, and page positioning code kept in a readable configuration file. It includes a utility to create numbered test pages, as well as one that rearranges the pages in a PostScript file into signature order, for producing two-up, double-sided booklets. The scripts are written in Perl, and require that version 3.0 be available. If you don't have Perl, how-to instructions are provided for converting to another language. It is known to work on the output of enscript, pscat, psdit (all from the Adobe TranScript package), the Adobe documentation supplied with NeXT release 1.0, and absolutely *no* dvi-to-PS converter (dvips 4.2 seems the most promising, and I'm working on appropriate hacks). #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README HowTo Makefile up makeup parr up.rc up.1 makeup.1 # parr.1 uprc.5 # Wrapped by jgreely@cis.ohio-state.edu on Tue Oct 24 15:16:22 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(3286 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X Up, a PostScript print utility X hacked together with a two-by-four by J Greely X (jgreely@cis.ohio-state.edu) X X XThis package allows you to print conforming PS files n-up, with the Xscaling, rotation, and page positioning code kept in a readable Xconfiguration file. It has successfully been used on the output of Xptroff, enscript, psdit (all from Adobe's TranScript package), and the XAdobe documentation supplied with NeXT release 1.0, and should work on Xany file that obeys the rules the way I assume (note: it does not Xcurrently work with any known dvi-to-PS converter; I'm making some Xchanges to make it work with dvips 4.2 (available for anonymous ftp at Xlabrea.stanford.edu), but they're not done yet). The major feature is Xthe ability to create your own layouts, with arbitrary scaling, Xtranslations, and rotations. The output can be fed back through, for Xfurther reduction/destruction. X X Warning: if you don't have Larry Wall's Perl language installed, Xthis utility will be useless to you. It's not hard (ok, trivial) to Xconvert it to Nawk or C, and I'll probably get around to it soon, but Xfor now you need Perl (version 3.0). Debates on the merits of Perl as Xa programming language are discouraged by the author. If Perl is not Xlocated in /usr/bin, you'll need to change the first line of each Xexecutable. X X To use, unpack the shar file somewhere, edit the top of Makefile to Xindicate where things should go, and type "make install". It will Xinstall several symlinks to the script, as well as a general Xconfiguration file, which can be overridden by the user. X X Currently, it installs links to print 2, 4, 6, and 16 pages per Xsheet, and the supplied configuration file has sample layouts for Xdoing (among others) 8-up, 4-up in greeting-card positions, 10-up in a Xshrinking spiral, and more. 4up and 16up simply scale the page by .5 Xand .25, respectively (white lie; read my excuse in the config file). X2up and 6up are rotated, and the page positioning is given below: X X +-----+-----+ +---+---+---+ X | | | | 1 | 2 | 3 | X | 1 | 2 | +---+---+---+ X | | | | 4 | 5 | 6 | X +-----+-----+ +---+---+---+ X X X Note to NeXT users: both Preview and Yap can be used to preview Xoutput under release 1.0. Previous versions wouldn't work quite Xright. X X Note to people in general: after I finished writing this, someone Xtold me of at least one other n-up utility. The one I've seen works Xby what might be called elegant PostScript hacking, but I think mine Xsolves a different problem. X X Bugs, suggestions, offers of money and sacrifices, and anything Xinteresting done with this package will be cheerfully accepted. XDespite rumors to the contrary, I am *not* a black hole for e-mail. X X XAdditional utilities supplied: X Xparr - Page ARRanger. For arbitrary reordering of pages in a X conforming PS file. Switches are provided to automatically X do signature-order printing for two-up, left-to-right X layouts ("up -n pup"). Pages can be printed more than once X or not at all, and blank pages may be inserted anywhere. X Xmakeup - generates numbered test pages, for debugging new layouts X X-- XJ Greely (jgreely@cis.ohio-state.edu; osu-cis!jgreely), 89/10/23 END_OF_FILE if test 3286 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'HowTo' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'HowTo'\" else echo shar: Extracting \"'HowTo'\" \(5776 characters\) sed "s/^X//" >'HowTo' <<'END_OF_FILE' XQuick summary of what this package does, and how to duplicate its Xeffects if you don't like my code. X XA conforming PostScript file, for my purposes, is anything that meets Xall of the following requirements: X X1) first line must begin with the string '%!PS-Adobe'. X2) Each page must begin with a '%%Page:' line, and the graphics state X must be the default at that point (no translation, scaling, or X rotation of the coordinate space can carry over between pages). X The pages must be numbered starting at 1, which is a bit pedantic X of me. It's part of the spec, but it is by no means necessary for X the code to work. It's a one-line check, and I'm thinking of just X scrapping it. X3) There must be a '%%Trailer' line. X X XAs for what I *do* with all this, it's simple: X X1) When I see the '%!PS-Adobe' line, I insert the following lines X (ignoring the old '%!PS' line): X %!PS-Adobe-2.0 X %%Pages: (atend) X Page counts in the header are first-comes, first-served, so putting X mine at the very top will override anything that was in the X original file (and since the whole idea is to change the number of X pages, this is 'a good thing'). Since I do everything in one pass, X I have no idea how many pages there will be, so I defer it until X the end. X2) When I reach the end of the header comments (signified by the first X non-%% line or an explicit %%EndComments line), I insert the X user-defined prolog definitions into their own dictionary. To X simplify nesting, I use the current PID as part of the dictionary X name. I save the old value of showpage here, and redefine it to X print nothing. It looks like this (modulo interpretation of X variables marked by <>): X %%BeginProcSet: up_prolog 1 <pid> X /UpDict<pid> $plines 3 add dict def X UpDict<pid> begin X <user prolog> X /UpShowpage {showpage} bind def X /UpState {} def X end X /showpage {} def X %%EndProcSet: up_prolog 1 <pid> X3) For every '%%Page:' line, I first delete it, and then, if it is the X first page on a sheet, I save the current VM state, and insert the X user-specified scaling, rotation, and translation commands. It X looks like this (modulo the interpolation of the variables marked X by <>): X %%Page: ? <sheet number> X UpDict<pid> begin X save /UpState exch def X <even/odd> X <scale, translate, rotate> X <page positioning> X end X For pages that don't start a sheet, I just insert: X UpDict<pid> begin X <page positioning> X end X5) At the end of every sheet, I restore the VM state, and perform a X real showpage, like so: X UpDict<pid> begin UpState restore UpShowpage end X6) When I see the '%%Trailer' line, I replace it with: X UpDict<pid> begin UpState restore UpShowpage end X %%Trailer X You might suspect that this causes an error, or the printing of a X blank page, and if everything I said above were true, you'd be X right. The catch is that #5 is a lie. I detect the end of a sheet X by finding myself at the beginning of a new one, so the last sheet X never gets printed, unless it's done just before the trailer. X7) The last bit is simple. After the very last line of the input is X printed, the actual sheet count is added. This has to be this way, X since the *last* in a series of trailer comments is the one heeded. X It looks like this: X %%Pages: <sheet count> X X XIf this isn't entirely clear, here's a before/after. X X---------- XConforming PS file, which prints 4 numbered pages (output of "makeup 4"): X X%!PS-Adobe-1.0 X%%Creator: makeup X%%Title: Page Layout Test X%%CreationDate: Tue Oct 24 02:33:36 EDT 1989 X%%Pages: (atend) X%%DocumentFonts: Times-Roman X%%BoundingBox: 0 0 612 792 X%%EndComments X/inch {72 mul} def X/Nfont /Times-Roman findfont 5 inch scalefont def X/drawpage { X 2 setlinecap 3 setlinewidth 0 setgray X Nfont setfont X dup stringwidth X 11 inch exch sub 2 div X exch 8.5 inch exch sub 2 div X exch moveto show X 0.25 inch dup moveto X 8 inch 0 rlineto X 0 10.5 inch rlineto X -8 inch 0 rlineto X 0 -10.5 inch rlineto X closepath stroke X showpage X} def X%%EndProlog X%%Page: ? 1 X(1) drawpage X%%Page: ? 2 X(2) drawpage X%%Page: ? 3 X(3) drawpage X%%Page: ? 4 X(4) drawpage X%%Trailer X%%Pages: 4 X X---------- XPrevious file, filtered to print two pages per sheet ("up -n 2up"): X X%!PS-Adobe-2.0 X%%Pages: (atend) X%%Creator: makeup X%%Title: Page Layout Test X%%CreationDate: Tue Oct 24 02:33:36 EDT 1989 X%%Pages: (atend) X%%DocumentFonts: Times-Roman X%%BoundingBox: 0 0 612 792 X%%EndComments X%%BeginProcSet: up_prolog 1 7482 X/UpDict7482 23 3 add dict def XUpDict7482 begin X/inch {72 mul} def X/moveU {0 11 inch translate} def X/moveR {8.5 inch 0 translate} def X/moveD {0 -11 inch translate} def X/moveL {-8.5 inch 0 translate} def X/rotR {-90 rotate} def X/rotL {90 rotate} def X/doSpiral {moveU moveR rotR 0.67 dup scale} def X/moveHU { 0 5.5 inch translate} def X/doRevSpiral {moveHU rotL 0.67 dup scale} def X/UpShowpage {showpage} bind def X/UpState {} def Xend X/showpage {} def X%%EndProcSet: up_prolog 1 7482 X/inch {72 mul} def X/Nfont /Times-Roman findfont 5 inch scalefont def X/drawpage { X 2 setlinecap 3 setlinewidth 0 setgray X Nfont setfont X dup stringwidth X 11 inch exch sub 2 div X exch 8.5 inch exch sub 2 div X exch moveto show X 0.25 inch dup moveto X 8 inch 0 rlineto X 0 10.5 inch rlineto X -8 inch 0 rlineto X 0 -10.5 inch rlineto X closepath stroke X showpage X} def X%%EndProlog X%%Page: ? 1 XUpDict7482 begin Xsave /UpState exch def X7.75 inch 0 translate rotL 11 17 div dup scale Xend X(1) drawpage XUpDict7482 begin XmoveR Xend X(2) drawpage XUpDict7482 begin UpState restore UpShowpage end X%%Page: ? 2 XUpDict7482 begin Xsave /UpState exch def X7.75 inch 0 translate rotL 11 17 div dup scale Xend X(3) drawpage XUpDict7482 begin XmoveR Xend X(4) drawpage XUpDict7482 begin UpState restore UpShowpage end X%%Trailer X%%Pages: 2 X X-- XJ Greely (jgreely@cis.ohio-state.edu; osu-cis!jgreely) END_OF_FILE if test 5776 -ne `wc -c <'HowTo'`; then echo shar: \"'HowTo'\" unpacked with wrong size! fi # end of 'HowTo' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1059 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile to install 'up' X# XLIBDIR=/usr/local/lib XBINDIR=/usr/local/bin XMANDIR=/usr/man XSYMLINK=ln -s X XPROG=up XUTIL=makeup parr XLIB=up.rc XLINKS=2up 4up 6up 16up XMAN1=up.1 makeup.1 parr.1 XMAN5=uprc.5 X XFILES=README HowTo Makefile $(PROG) $(UTIL) $(LIB) $(MAN1) $(MAN5) X Xdefault: X @echo Edit Makefile, changing the values of LIBDIR, BINDIR, X @echo MANDIR, and SYMLINK, then type \"make install\" X Xinstall: $(PROG) $(UTIL) $(LIB) $(MAN1) $(MAN5) X cp $(PROG) $(UTIL) $(BINDIR) X cp $(LIB) $(LIBDIR) X for i in $(LINKS); do $(SYMLINK) $(BINDIR)/$(PROG) $(BINDIR)/$$i; done X @-mkdir $(MANDIR) X @-mkdir $(MANDIR)/man1 X @-mkdir $(MANDIR)/man5 X cp $(MAN1) $(MANDIR)/man1 X cp $(MAN5) $(MANDIR)/man5 X Xclean: X rm -f core up.shar* *~ X Xuninstall: X -for i in $(PROG) $(UTIL) $(LINKS); do rm $(BINDIR)/$$i; done X -rm $(LIBDIR)/$(LIB) X -for i in $(MAN1); do rm $(MANDIR)/man1/$$i; done X -for i in $(MAN5); do rm $(MANDIR)/man5/$$i; done X Xup.shar: $(FILES) X shar $(FILES) >up.shar X perl -i.old -pe 's/jgreely@[-.\w]+[-\w]/jgreely@cis.ohio-state.edu/g;'\ X up.shar X rm up.shar.old END_OF_FILE if test 1059 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'up' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'up'\" else echo shar: Extracting \"'up'\" \(4810 characters\) sed "s/^X//" >'up' <<'END_OF_FILE' X#!/usr/local/bin/perl X# up: X# PostScript n-up print utility. This script takes conforming PS X# files, and prints them n-up, where n is controlled by a symbolic X# name (taken from argv[0] or the command line), and the page X# positioning and scaling are looked up in a configuration file. X# X# usage: up [-n name] [-f config] [file ...] X# X# jgreely@cis.ohio-state.edu, 89/10/23 X# X X# set the name from $0 (argv[0]), after stripping a path X# X@foo = split(/\//,$0); X$name=pop(@foo); X X$HOME=$ENV{"HOME"}; X X# set a default prolog in case the config file doesn't have one X# make sure that plines is 2 larger than the number of definitions in X# the prolog (used to get dictionary size). X# X$plines=10; X$prolog = <<EOF; X/inch {72 mul} def X/moveU {0 11 inch translate} def X/moveR {8.5 inch 0 translate} def X/moveD {0 -11 inch translate} def X/moveL {-8.5 inch 0 translate} def X/rotR {-90 rotate} def X/rotL {90 rotate} def XEOF X X# search for a configuration file. The *last* one found is used X# X$config = "./up.rc"; X@search_path = ("/usr/lib/up.rc","/usr/local/lib/up.rc","$HOME/.uprc", X "./up.rc"); Xforeach $file (@search_path) { X $config = $file if (-f $file && -r $file); X} X X# check for options on command line. X# Xwhile ($_ = $ARGV[0],/^-/) { X shift; X last if /^-\-$/; X /^-[Ff]/ && ($config = shift,next); X /^-[Nn]/ && ($name = shift,next); X die "usage: up [-f config] [-n name] [file ...]\n"; X} X X# read relevant section of configuration file. For complete format X# description, see the provided up.rc file or uprc(5). X# Basically, read the config file until we find a line containing a X# name field equal to the current name. Once we do, read all name- X# value pairs up until a line containing just a '.', placing them all X# into an associative array. X# Xopen(config) || X die "can't find file '$config', stopped"; X$in_rec = 0; Xwhile(<config>) { X chop; X next if /^\s*#|^\s*$/; # skip comment and blank lines X if (/^prolog\s*=/) { X do read_prolog(); X next; X } X next unless ($in_rec || /$name/); X ($field,$value) = split(/\s*=\s*/); X if (($field eq "name") && ($value eq $name)) { X $in_rec++; X next; X } X last if /^\.$/; X $var{$field} = $value; X} Xclose(config); Xdie "no such record '$name' in file '$config', stopped" unless $in_rec; X$modulus = $var{"modulus"}; Xdie "invalid modulus == $modulus, stopped" unless $modulus; X X$_ = <>; Xif (/^%!PS-Adobe/) { X print <<EOF; X%!PS-Adobe-2.0 X%%Pages: (atend) XEOF X}else{ X die "Not conforming PostScript (no %!PS-Adobe), stopped"; X} X X# read comment section (up to first non-%% line, or %%EndComments) X# Xwhile (<>) { X if (!/^%%/) { X do print_prologue(); X print; X last; X } X if (/^%%EndComments/) { X print; X do print_prologue(); X last; X } X print; X} X Xwhile (<>) { X # X # to use slightly busted NeXT previewer X # X next if /^%%Pages:/; X if (/^%%Page:/) { X do enter_page(); X next; X } X if (/^%%Trailer/) { X do print_trailer(); X next; X } X print; X} X# print actual page count. This must be the last trailer comment X# printed. X# Xprint "%%Pages: $sheet\n"; Xexit(0); X X# the prolog consists of simple command definitions you want to make X# available to the configuration routines. None of them do anything X# complicated, but why make life more difficult for the user? X# Xsub print_prologue { X print <<EOF; X%%BeginProcSet: up_prolog 1 $$ X/UpDict$$ $plines 3 add dict def XUpDict$$ begin X$prolog X/UpShowpage {showpage} bind def X/UpState {} def Xend X/showpage {} def X%%EndProcSet: up_prolog 1 $$ XEOF X} X X# basically, at the beginning of a page, pull the number from the page X# header, take it modulo $modulus, and print things based on that # X# number. If it's 1, end the previous sheet (if there is one), X# increment the sheet number, and print a sheet header. For all X# pages, print the appropriate page motion command. X# Xsub enter_page { X $page++; X ($foo,$bar,$oldpage) = split; X die "Help! page number mismatch, stopped" if ($oldpage != $page); X $temp = $page % $modulus; X if ($temp == 1) { X if ($sheet++) { X print X "UpDict$$ begin UpState restore UpShowpage end\n"; X } X print <<EOF; X%%Page: ? $sheet XUpDict$$ begin Xsave /UpState exch def XEOF X print $sheet % 2 ? $var{'odd'} : $var{'even'},"\n"; X print $var{"scale"},"\n"; X }else{ X print "UpDict$$ begin\n"; X } X $temp = $modulus unless $temp; X print $var{$temp},"\n"; X print "end\n"; X} X X# print the trailer, which for us consists of a showpage (inserted X# before the trailer comment, to make it part of the last page). X# Xsub print_trailer { X print "UpDict$$ begin UpState restore UpShowpage end\n" if $page; X print "%%Trailer\n"; X} X X# read the prolog from the configuration file. All lines up to the X# the first one starting with '.' will be placed in $prolog X# Xsub read_prolog { X $prolog=''; X #plines=0; X while (<config>) { X last if /^\./; X $prolog .= $_; X $plines++; X } X chop($prolog); X $plines+=3; X} END_OF_FILE if test 4810 -ne `wc -c <'up'`; then echo shar: \"'up'\" unpacked with wrong size! fi chmod +x 'up' # end of 'up' fi if test -f 'makeup' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makeup'\" else echo shar: Extracting \"'makeup'\" \(1092 characters\) sed "s/^X//" >'makeup' <<'END_OF_FILE' X#!/usr/bin/perl X# test page printing for up. print arg pages, each with a box around X# the edges (.25 inches in), and the page number in large type. X# This is useful for debugging page layouts, as well as just wasting X# paper. X# X# usage: makeup count X# X# jgreely@cis.ohio-state.edu, 89/10/23 X# X$count = $ARGV[0]; Xdie "usage: makeup count\n" unless $count > 0; X X$date = `date`; Xchop($date); X Xprint <<EOF; X%!PS-Adobe-1.0 X%%Creator: makeup X%%Title: Page Layout Test X%%CreationDate: $date X%%Pages: (atend) X%%DocumentFonts: Times-Roman X%%BoundingBox: 0 0 612 792 X%%EndComments X/inch {72 mul} def X/Nfont /Times-Roman findfont 5 inch scalefont def X/drawpage { X 2 setlinecap 3 setlinewidth 0 setgray X Nfont setfont X dup stringwidth X 11 inch exch sub 2 div X exch 8.5 inch exch sub 2 div X exch moveto show X 0.25 inch dup moveto X 8 inch 0 rlineto X 0 10.5 inch rlineto X -8 inch 0 rlineto X 0 -10.5 inch rlineto X closepath stroke X showpage X} def X%%EndProlog XEOF X Xfor ($page=1;$page <= $count;$page++) { X print "%%Page: ? $page\n($page) drawpage\n"; X} X Xprint <<EOF; X%%Trailer X%%Pages: $count XEOF Xexit(0); END_OF_FILE if test 1092 -ne `wc -c <'makeup'`; then echo shar: \"'makeup'\" unpacked with wrong size! fi chmod +x 'makeup' # end of 'makeup' fi if test -f 'parr' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'parr'\" else echo shar: Extracting \"'parr'\" \(2661 characters\) sed "s/^X//" >'parr' <<'END_OF_FILE' X#!/usr/bin/perl X#parr: X# rearrange conforming PS code to print the pages in an arbitrary X# order. The -[sS] options (for signature order) assume two-up, left X# to right. The -o option takes a list of ranges, like this: X# 1-5 1-10,11-20 11-,1-10 X# usage: parr [-o list] [-s] [-S n] [file] X# X# jgreely@cis.ohio-state.edu, 89/10/23 X X$order=''; X$signFlag=''; X$signCount=0; X$DEBUG=0; X$rangePrint=0; X$TMPDIR='/tmp'; X Xwhile ($_ = $ARGV[0],/^-/) { X shift; X last if /^-\-$/; X /^-o/ && ($order = shift,next); X /^-S/ && ($signCount = shift,$signFlag++,next); X /^-s/ && ($signFlag++,next); X /^-d/ && ($DEBUG++,next); X /^-r/ && ($rangePrint++,next); X die "usage: parr [-d] [-r] [-o list] [-s] [-S n] [file]\n"; X} Xif ($signFlag && $order) { X die "parr: -s and -o cannot be used together\n"; X} X X$file = "$TMPDIR/p$$.header"; X@files = ($file); X$sheet=0; Xopen(file,">$file") || X die "$file: $!, stopped"; Xwhile (<>) { X # X # hack to use NeXT Preview: strip old '%%Pages:' lines X # X next if /^%%Pages:/; X if (/^%%Page:/) { X close(file); X $sheet++; X $file = "$TMPDIR/p$$.$sheet"; X push(@files,$file); X open(file,">$file") || X die "$file: $!, stopped"; X } X if (/^%%Trailer/) { X close(file); X $file = "$TMPDIR/p$$.trailer"; X push(@files,$file); X open(file,">$file") || X die "$file: $!, stopped"; X } X print file $_; X} Xclose(file); X X@order = (); Xif ($order) { X foreach $range (split(/,/,$order)) { X ($start,$sep,$end) = split(/(-)/,$range); X $start = 1 unless $start; X $end = $sheet unless $end; X if ($sep) { X push(@order,$start..$end); X }else{ X push(@order,$start); X } X } X}elsif ($signFlag) { X if (! $signCount) { X $signCount = $sheet; X $signCount += (4 - $sheet % 4) if ($sheet % 4); X }else{ X $signCount *=4; X } X for($base=0;$base<$sheet;$base+=$signCount) { X @tmp = ($signCount/2+$base); X push(@tmp,$tmp[0]+1,$tmp[0]+2,$tmp[0]-1); X while ($tmp[3] > $base) { X push(@order,@tmp); X @tmp = ($tmp[0]-2,$tmp[1]+2,$tmp[2]+2,$tmp[3]-2); X } X } X}else{ X @order = (1..$sheet); X} X X@tmp=@order; X@order=(); Xforeach $page (@tmp) { X push(@order,$page > $sheet ? "B" : $page); X} X Xif ($rangePrint) { X print join(',',@order),"\n"; X unlink @files unless $DEBUG; X exit(0); X} X Xopen(file,"$TMPDIR/p$$.header"); X$_ = <file>; Xprint $_,"%%Pages: (atend)\n"; Xprint while <file>; Xclose(file); X Xforeach $page (@order) { X $count++; X print "%%Page: ? $count\n%%OldPage: $page\n"; X if ($page eq "B") { X print "showpage\n"; X }else{ X open(file,"$TMPDIR/p$$.$page"); X while (<file>) { X print unless /^%%Page:/; X } X close(file); X } X} Xopen(file,"$TMPDIR/p$$.trailer"); Xprint while <file>; Xclose(file); Xprint "%%Pages: $count\n"; X Xunlink @files unless $DEBUG; Xexit(0); END_OF_FILE if test 2661 -ne `wc -c <'parr'`; then echo shar: \"'parr'\" unpacked with wrong size! fi chmod +x 'parr' # end of 'parr' fi if test -f 'up.rc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'up.rc'\" else echo shar: Extracting \"'up.rc'\" \(3086 characters\) sed "s/^X//" >'up.rc' <<'END_OF_FILE' X# jgreely@cis.ohio-state.edu, 89/10/23 X# X X# this is the normal prolog, and defines everything used below X# Xprolog= X/inch {72 mul} def X/moveU {0 11 inch translate} def X/moveR {8.5 inch 0 translate} def X/moveD {0 -11 inch translate} def X/moveL {-8.5 inch 0 translate} def X/rotR {-90 rotate} def X/rotL {90 rotate} def X/doSpiral {moveU moveR rotR 0.67 dup scale} def X/moveHU { 0 5.5 inch translate} def X/doRevSpiral {moveHU rotL 0.67 dup scale} def X. X X# up is a synonym for twoup, since my code doesn't work correctly for X# the case n==1. Until I robustify it, this will stay. X# Xname=up Xmodulus=2 Xscale=7.75 inch 0 translate rotL 11 17 div dup scale X1= X2=moveR X. X Xname=2up Xmodulus=2 Xscale=7.75 inch 0 translate rotL 11 17 div dup scale X1= X2=moveR X. X X# two-up with even pages rotated, for double-siding X# Xname=pup Xmodulus=2 Xeven=moveU moveR rotR rotR Xodd= Xscale=7.75 inch 0 translate rotL 11 17 div dup scale X1= X2=moveR X. X X# note that 4up is scaled a bit smaller than you might think. If I X# just scaled by .5, I'd lose my top and bottom edges (printer X# limitations) X# Xname=4up Xmodulus=4 Xscale=0.2125 inch 0.275 inch translate 0.475 dup scale X1=moveU X2=moveR X3=moveL moveD X4=moveR X. X X# this does a greeting-card format, designed to be folded into X# fourths. If you're not sure how it's supposed to look, run: X# makeup 4 | up -n card | lpr X# Xname=card Xmodulus=4 Xscale=0.2125 inch 0.275 inch translate 0.475 dup scale X1=moveU moveU moveR rotR rotR X2=moveU moveU moveR rotR rotR X3=moveR X4=moveU moveU moveR rotR rotR X. X X# this is about the limit for a 300 dpi device, unless it's reasonably X# new and you have good eyes. I like it at 400 dpi. X# Xname=6up Xmodulus=6 Xscale=0.25 inch 0.75 inch translate rotL 4 11 div dup scale X1=moveD X2=moveR X3=moveR X4=moveD moveL moveL X5=moveR X6=moveR X. X X# this is a bit too far for casual reading. It's entering magnifying X# glass territory, which is bad, unless you need to carry lots of RFCs X# around. X# Xname=8up Xmodulus=8 Xscale=0.7 inch 0 translate rotL 11 34 div dup scale X1=moveD X2=moveR X3=moveR X4=moveR X5=moveD moveL moveL moveL X6=moveR X7=moveR X8=moveR X. X X# Steve Romig's contribution to evil PostScript hacking. To see what X# it does, run: X# makeup 10 | up -n spiral | lpr X# Xname=spiral Xmodulus=10 Xscale=7.75 inch 0 translate rotL 11 17 div dup scale X1= X2=doSpiral X3=doSpiral X4=doSpiral X5=doSpiral X6=doSpiral X7=doSpiral X8=doSpiral X9=doSpiral X10=doSpiral X. X X# More from Steve, this time in the other direction X# Xname=revspiral Xmodulus=10 Xscale=7.75 inch 0 translate rotL 11 17 div dup scale X1=moveR X2=doRevSpiral X3=doRevSpiral X4=doRevSpiral X5=doRevSpiral X6=doRevSpiral X7=doRevSpiral X8=doRevSpiral X9=doRevSpiral X10=doRevSpiral X. X X# this is not legible on anything under 400 dpi, and even then you'll X# probably want a magnifying glass. You *can* read it with the naked X# eye, but not for long. X# Xname=16up Xmodulus=16 Xscale=0.25 0.25 scale X1=moveU moveU moveU X2=moveR X3=moveR X4=moveR X5=moveD moveL moveL moveL X6=moveR X7=moveR X8=moveR X9=moveD moveL moveL moveL X10=moveR X11=moveR X12=moveR X13=moveD moveL moveL moveL X14=moveR X15=moveR X16=moveR X. END_OF_FILE if test 3086 -ne `wc -c <'up.rc'`; then echo shar: \"'up.rc'\" unpacked with wrong size! fi # end of 'up.rc' fi if test -f 'up.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'up.1'\" else echo shar: Extracting \"'up.1'\" \(2731 characters\) sed "s/^X//" >'up.1' <<'END_OF_FILE' X.TH UP 1 "23 October 1989" X.SH NAME Xup \- convert conforming PostScript files to print n-up X.br Xmakeup \- create numbered test pages for up X.SH SYNOPSIS X.B up X[ X.B \-f Xconfig_file ] [ X.B \-n Xname ] [ file ... ] X.PP X.B makeup Xcount X.SH DESCRIPTION X.I Up Xreads a conforming PostScript file, and performs translation, Xrotation, and scaling operations to print several pages on one sheet Xof paper. It uses a human-readable configuration file to determine Xhow to arrange pages, and selects named layouts based on the name the Xprogram was called by (see also the X.I \-f Xoption). The output is also conforming, which means that it can be Xfed back through for further reduction. X.PP XThe configuration file is slightly magical, but easy to use for simple Xlayouts. Quite complicated effects are possible by embedding Xarbitrary PostScript commands. See X.IR spiral , Xin the supplied configuration file. The format is completely Xdescribed in uprc(5). X.PP X.I Makeup Xis a simple utility that generates X.I count Xpages of conforming PostScript to stdout, with each page containing a X10.5x8 inch box, and a large page number. Its main excuse for Xexistence is debugging new layouts, although the enterprising could Xset up calendar formats. X.SH OPTIONS X.TP X.B \-f X.I config_file XUse an alternate configuration file. Normally, it uses the last of Xthe following that is found: /usr/local/lib/up.rc, ~/.uprc ./up.rc. X.TP X.B \-n X.I name XExplicitly specify what page layout to use, no matter what name the Xprogram was called by. This is handy for testing new layouts, and Xconfigurations that you haven't created links for yet. X.SH FILES X.PD 0 X.TP 25 X.B /usr/local/lib/up.rc Xglobal configuration X.TP X.B ~/.uprc Xuser's personal configuration X.TP X.B ./up.rc Xcurrent directory's configuration X.br X.ne 5 X.PD X.SH "SEE ALSO" XPostScript Language Reference Manual, perl(1), ptroff(1), enscript(1), Xpsdvi(1), dvips(1), uprc(5) X.SH AUTHOR XJ Greely (jgreely@cis.ohio-state.edu), Ohio State University, Department Xof Computer and Information Science, etc. Laws warranted where voided Xby Prohibition. X.SH STATUS XHighly experimental, and dangerous in the wrong hands. Not to be used Xwhile under the influence of whimsy. X.SH BUGS XDoesn't seem to work with psdvi output, although dvips (3.4) works. X.PP XThe configuration file parsing is less than robust. X.PP XSome would say that the use of X.I Perl Xis a bug. X.PP XThe way I test for conformance with Adobe's document structuring Xconventions is iffy. I don't apologize for it, but I don't like it, Xeither. Eventually, I'll break down and do proper checking, probably Xwhen I convert it all to C. X.PP X.IR Makeup 's Xpage numbering doesn't fit within the margins after page 999. I have Xno intention of fixing this. END_OF_FILE if test 2731 -ne `wc -c <'up.1'`; then echo shar: \"'up.1'\" unpacked with wrong size! fi # end of 'up.1' fi if test -f 'makeup.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makeup.1'\" else echo shar: Extracting \"'makeup.1'\" \(14 characters\) sed "s/^X//" >'makeup.1' <<'END_OF_FILE' X.so man1/up.1 END_OF_FILE if test 14 -ne `wc -c <'makeup.1'`; then echo shar: \"'makeup.1'\" unpacked with wrong size! fi # end of 'makeup.1' fi if test -f 'parr.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'parr.1'\" else echo shar: Extracting \"'parr.1'\" \(1245 characters\) sed "s/^X//" >'parr.1' <<'END_OF_FILE' X.TH PARR 1 "23 October 1989" X.SH NAME Xparr \- rearrange pages in a PostScript file, for signatures X.SH SYNOPSIS X.B parr X[ X.B \-r X] [ X.B \-s X] [ X.B \-S X.I sheets X] [ X.B \-o X.I pagelist X] [file] X.SH DESCRIPTION X.I Parr Xreads a conforming PostScript file, and rearranges the pages in Xinteresting ways, of which the primary one is signature order (for Xdouble-sided, two-up printing). Pages can be printed more than once Xor not at all, and blank pages may be inserted anywhere. X.SH OPTIONS X.TP X.B \-r XJust print the page order to stdout. X.TP X.B \-s XPrint in signature order. Default is to make one large signature, Xunless the X.B \-S Xoption is used. The output is meant to be passed through "up -n pup". X.TP X.B \-S X.I sheets XImplies the X.B \-s Xflag. Used to indicate how many sheets should be in each signature. XNote that this is the number of X.I double-sided Xsheets. X.TP X.B \-o X.I pagelist XArbitrary order. Pages are specified as a comma-separated list of Xpage ranges, like this: 21-,11-19,20,-10. A 'B' may be used to Xindicate the printing of a blank page. X.SH "SEE ALSO" XPostScript Language Reference Manual, up(1) X.SH AUTHOR XJ Greely (jgreely@cis.ohio-state.edu), Ohio State University, Department Xof Computer and Information Science, etc. END_OF_FILE if test 1245 -ne `wc -c <'parr.1'`; then echo shar: \"'parr.1'\" unpacked with wrong size! fi # end of 'parr.1' fi if test -f 'uprc.5' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uprc.5'\" else echo shar: Extracting \"'uprc.5'\" \(2484 characters\) sed "s/^X//" >'uprc.5' <<'END_OF_FILE' X.TH UPRC 5 "24 August 1989" X.SH NAME Xuprc \- layout configuration file for "up" X.SH DESCRIPTION XThe X.I uprc Xfile contains all of the information necessary to describe a page Xlayout for the X.I up Xutility. The format is simple, but capable of some impressively Xtwisted output. A sample configuration is given below, followed by a Xcomplete explanation. Records in a file begin with a line containing Xeither "name=something" or "prolog=", and end with a line containing Xjust a period. X.IP X prolog= X /inch {72 mul} def X /moveU {0 11 inch translate} def X /moveR {8.5 inch 0 translate} def X /moveD {0 -11 inch translate} def X /moveL {-8.5 inch 0 translate} def X /rotR {-90 rotate} def X /rotL {90 rotate} def X . X X name=4up X modulus=4 X scale=0.2125 inch 0.275 inch translate 0.475 dup scale X 1=moveU X 2=moveR X 3=moveL moveD X 4=moveR X . X.PP XThe X.I prolog Xrecord contains an arbitrary number of lines of PostScript code to be Xplaced right before the "%%EndProlog" comment in the header. These Xcommands must not effect the graphics state, and should only be used Xto define functions for use at page breaks. The default header (shown Xabove) defines functions to move the page origin (in terms of pages), Xand rotate the co-ordinate space 90 degrees left and right. More than Xone header can be present in a file; the X.I last Xone found before the desired layout record will be used. X.PP XLayout records contain five types of fields. X.IR name , X.IR modulus , X.IR even/odd , X.IR <number> , Xand X.IR scale . XThe X.I name Xfield may contain any number of alphanumeric characters, and Xis what determines the logical record name. The X.I modulus Xfield must contain a decimal number indicating the number of pages to Xbe placed on a sheet. There should be fields numbered from 1 through X.IR modulus , Xcontaining the PostScript commands to move the origin to the correct Xplace for that page (relative to the location of the previously Xprinted page). The X.I scale Xfield contains PostScript commands that set up the scaling at the Xbeginning of each sheet. Despite the name, rotations and translations Xalso belong here. The X.I even/odd Xfields are used to make even and odd sheets print differently. XThey're not often useful, but they're handy for preparing double-sided Xoutput. X.PP XBlank lines and lines beginning with a "#" character are ignored. X.SH FILES X/usr/local/lib/up.rc, ~/.uprc, ./up.rc X.SH "SEE ALSO" Xup(1), PostScript Language Reference Manual X.SH AUTHOR XJ Greely (jgreely@cis.ohio-state.edu) END_OF_FILE if test 2484 -ne `wc -c <'uprc.5'`; then echo shar: \"'uprc.5'\" unpacked with wrong size! fi # end of 'uprc.5' fi echo shar: End of shell archive. exit 0