riem@ztivax.UUCP (Raimund Riem) (03/08/90)
Sometimes ago I asked for help on printing two or four pages on one sheet of paper. Now I will summarized the repies to all interested people. Someone know about a solution for the Macintosh? Thanks for all replies. From rei Wed Feb 21 13:28:37 1990 From: rei (Dr Manfred Reitenspiess) Date: Wed, 21 Feb 90 13:28:36 -0100 Message-Id: <9002211228.AA19196@ztivax.uucp> Received: by ztivax.uucp; Wed, 21 Feb 90 13:28:36 -0100 To: riem Subject: re psnews: two pages on one Status: RO the standard ensrcript package on the VAX does exactly that: enscript -2rk -p<outfile> <infile> However, I have another question: when printing the thereby generated postscript file on an Apple laserwriter, the top of the page is moving too far down. This results in a missing first column of first of each two printed pages. If you find something more convenient than enscript or if you find a solution to my problem, please send mail to rei@ztivax -------------------------------------------------------------------- Manfred Reitenspiess ZFE IS SOF42, Siemens AG, Otto-Hahn-Ring 6, 8000 Muenchen 83 Tel.: 089-636-42393 Mail: rei@ztivax -------------------------------------------------------------------- ENSCRIPT(1) UNIX Programmer's Manual ENSCRIPT(1) NAME enscript - convert text files to POSTSCRIPT format for printing SYNOPSIS enscript [ -12BGghKklmoqRr ] [ -L_l_i_n_e_s ] [ -f_f_o_n_t ] [ -F_h_f_o_n_t ] [ -b_h_e_a_d_e_r ] [ -p_o_u_t ] [ _s_p_o_o_l_o_p_t_s ] [ _f_i_l_e_s ] DESCRIPTION _e_n_s_c_r_i_p_t reads in plain text files, converts them to POSTSCRIPT format, and spools them for printing on a POSTSCRIPT printer. Fonts, headings, limited formatting options and spooling options may be specified. For example: enscript -Paleph boring.txt prints a copy of the file called boring.txt on the printer called "aleph". enscript -2r boring.c prints a two-up landscape listing of the file called boring.c on the default printer (see below). Font specifications have two parts: A font name as known to POSTSCRIPT (e.g., Times-Roman, Times-BoldItalic Helvetica, Courier), and a point size (1 point=1/72 inch - 8 point is a good small font). So Courier-Bold8 is 8 point Courier Bold, Helvetica12 is 12 point Helvetica. The environment variable ENSCRIPT may be used to specify defaults. The value of ENSCRIPT is parsed as a string of arguments _b_e_f_o_r_e the arguments that appear on the command line. For example "ENSCRIPT='-fTimes-Roman8'" sets your default body font to 8 point Times Roman. The possible options are: -2 set in two columns. -1 set in one column (the default). -r rotate the output 90 degrees (landscape mode). This is good for output that requires a wide page or for pro- gram listings when used in conjunction with -2. "enscript -2r files" is a nice way to get program list- ings. -R don't rotate, also known as portrait mode (the default). -G print in gaudy mode: causes page headings, dates, page numbers to be printed in a flashy style, at some slight 12 Nov 1985 Image Network Development System-4.2 BSD 1 ENSCRIPT(1) UNIX Programmer's Manual ENSCRIPT(1) performance expense. -l simulate a line printer: make pages 66 lines long and omit headers. -B omit page headings. -b_h_e_a_d_e_r sets the string to be used for page headings to _h_e_a_d_e_r. The default header is constructed from the file name, its last modification date, and a page number. -L_l_i_n_e_s set the maximum number of lines to output on a page. _E_n_s_c_r_i_p_t usually computes how many to put on a page based on point size, and may put fewer per page than requested by _l_i_n_e_s. -f_f_o_n_t sets the font to be used for the body of each page. Defaults to Courier10, unless two column rotated mode is used, in which case it defaults to Courier7. -F_h_f_o_n_t sets the font to be used for page headings. Defaults to Courier-Bold10. -p_o_u_t causes the POSTSCRIPT file to be written to the named file rather than being spooled for printing. As a spe- cial case, -p - will send the POSTSCRIPT to the stan- dard output. -g causes the fact that a file is garbage to be ignored. Normally, any file with more than a small number of non-printing characters is suspected of being garbage, and not printed - this option means "print it anyway." -o If _e_n_s_c_r_i_p_t cannot find characters in a font, the miss- ing characters are listed. -q causes _e_n_s_c_r_i_p_t to be quiet about what it is doing. _E_n_s_c_r_i_p_t won't report about pages, destination, omitted characters, etc. Fatal errors are still reported to the standard error output. -k enables page prefeed (if the printer supports it). This allows simple documents (e.g., program listings in one font) to print somewhat faster by keeping the printer running between pages. 12 Nov 1985 Image Network Development System-4.2 BSD 2 ENSCRIPT(1) UNIX Programmer's Manual ENSCRIPT(1) -K disable page prefeed (the default). -h suppress printing of job burst page. In 4.2bsd systems, the following spooler options are also recognized: -P_p_r_i_n_t_e_r causes the output to be sent to the named printer. -#_n causes _n copies of the output to be produced. The default is one. -m causes the printer daemon to send mail upon job comple- tion. -J_n_a_m_e sets the job name for use on the burst page. Other- wise, the name of the first input file will be used. -C_c_l_a_s_s set the job classification for use on the burst page. In System V, the following spooler options are also recog- nized: -t_t_i_t_l_e sets job title for use on the burst page. -d_d_e_s_t causes the output to be sent to the named printer or printer class. -n_n causes _n copies of the output to be produced. The default is one. -w or -m causes the printer daemon to write or send mail upon job completion. ENVIRONMENT ENSCRIPT string of options to be used by _e_n_s_c_r_i_p_t. PSLIBDIR path name of a directory to use instead of /usr/local/lib/ps for enscript prologue and font metric files. PSTEMPDIR path name of temporary directory to use instead of 12 Nov 1985 Image Network Development System-4.2 BSD 3 ENSCRIPT(1) UNIX Programmer's Manual ENSCRIPT(1) XPSTEMDIRX of spooled temporary files. PRINTER (4.2bsd) the name of a printer (as in the -P option) for _l_p_r to use. If no -P option is specified, _l_p_r will use this printer. If neither -P nor PRINTER is set, _e_n_s_c_r_i_p_t will spool to a printer named ``PostScript''. LPDEST (System V) the name of a printer (as in the -d option) for _l_p to use. If no -d option is specified, _l_p will use this printer. If neither -d nor LPDEST is set, _e_n_s_c_r_i_p_t will spool to a printer class named ``PostScript''. FILES /usr/local/lib/ps/*.afm font metrics files. /usr/local/lib/ps/enscript.pro prologue for enscript files. lpr(1 bsd), lp(1 V) Printer spooler SEE ALSO pr(1), ps630(1), getopt(3). 4.2bsd: lpr(1), lpq(1), lprm(1). System V: lp(1), cancel(1), lpstat(1). DIAGNOSTICS Should be self explanatory. AUTHOR Adobe Systems Incorporated Gaudy mode by Guy Riddle of AT&T Bell Laboratories FEATURES Options and the ENSCRIPT environment string are parsed in _g_e_t_o_p_t(3) fashion. BUGS Long lines are truncated. Line truncation may be off by a little bit as printer margins vary. There should be a "wrap" option and multiple (truncated or wrapped) columns. _E_n_s_c_r_i_p_t generates temporary files which are spooled for printing. The temporary file names are used by the spooling software (e.g., _l_p_q), rather than the symbolic job name passed to _l_p_r. There are too many options. 12 Nov 1985 Image Network Development System-4.2 BSD 4 ENSCRIPT(1) UNIX Programmer's Manual ENSCRIPT(1) NOTES POSTSCRIPT is a trademark of Adobe Systems Incorporated. Times and Helvetica are registered trademarks of Allied Cor- poration. 12 Nov 1985 Image Network Development System-4.2 BSD 5 From leoh%hardy%relay.EU.net@unido Fri Feb 23 16:57:49 1990 Date: Fri, 23 Feb 90 08:56:57 EST From: leoh%hardy@uunet.UU.NET (Leo Hinds) To: riem@ztivax Subject: Re: Printing two pages on one sheet Newsgroups: comp.sys.mac,comp.lang.postscript In-Reply-To: <904@ztivax.UUCP> Organization: Harris Computer Systems, Fort Lauderdale, FL There is a program that was posted to the net a while back (not sure of exact date), that would do 2/4/8/16/n up ... without much effort. I have a copy of the shar file (~30k in size) ... let me know if you want it. -- leoh@hdw.csd.harris.com H H i d sssss L eeeee oooo H H nnnn ddddd ss L eee o o HHHHHH i n n d d ss LLLLLL eeeee oooo H H i n n ddddd sssss From jw%owf%ethz%chx400%cernvax@unido Fri Feb 23 17:48:00 1990 Date: Fri, 23 Feb 90 09:58:10 +0100 From: jw%owf%chx400@cernvax Message-Id: <9002230858.AA00653@thor.owf.uucp> To: riem@ztivax Subject: Re: Printing two pages on one sheet Newsgroups: comp.sys.mac,comp.lang.postscript In-Reply-To: <904@ztivax.UUCP> Organization: OWF AG Zurich, Switzerland Status: RO Providing, your postscript file is a *conforming* postscript file the program below will generate exactly what you want Juerg Wanner (jw@owf.uucp) OWF AG Asylstr. 125 CH-8032 Zuerich ----- snip snip snip ------ /* a5.c * * mutilates a conforming postscript file for 2 pages per A4 * */ #include <stdio.h> #define BUFSIZ 1024 static char buf[BUFSIZ]; main(argc, argv) int argc; char **argv; { int page = 0, trail = 0; register int cnt, c; register char *bp; while ((c = getchar()) != EOF) { bp = buf; *bp = '\0'; if (c != '%') { copyline(buf, c); } else { cnt = BUFSIZ - 1; do { if (c == EOF) { *bp = '\0'; } else *bp++ = c; } while ((c = getchar()) != '\n' && --cnt > 0); *bp = 0; if ((c == EOF) && (bp == buf)) break; else if (strncmp(buf,"%%Page:",7) == 0) { if (++page & 1) { printf("%%%%Page: %d %d\n", (page+1) >> 1, (page+1) >> 1); while (c != '\n' && c != EOF) c = getchar(); } } else if (strncmp(buf,"%%EndComments",13) == 0) { copyline(buf, c); printf("/$first$ true def\n"); printf("/$a4height$ 297 25.4 div 72 mul def\n"); printf("/$a4width$ 210 25.4 div 72 mul def\n"); printf("/$xlate$ {\n"); printf(" 90 rotate\n"); printf(" -72 25.4 div $a4width$ neg translate\n"); printf(" 210 297 div dup scale\n"); printf("} bind def\n"); printf("/$oshow$ {\n"); /* uncomment this if you want a 'gutter' line printf(" 1 setlinewidth\n"); printf(" 0 0 moveto 0 $a4height$ lineto stroke\n"); */ printf(" showpage\n"); printf(" /$first$ true store\n"); printf(" $xlate$\n"); printf("} bind def\n"); printf("/showpage {\n"); printf(" /$first$ load {\n"); printf("\t$a4width$ 0 translate\n"); printf("\t/$first$ false store\n"); printf("\t} {\n"); printf("\t$oshow$\n"); printf(" } ifelse\n"); printf("} bind def\n"); printf("$xlate$\n"); } else if (strncmp(buf,"%%Trailer",9) == 0) { if (page++ & 1) printf("\n$oshow$\n\n"); copyline(buf, c); trail++; } else if (strncmp(buf, "%%Pages:", 8) == 0) { if (!trail) printf("%%%%Pages: (atend)\n"); } else copyline(buf, c); } } printf("%%%%Pages: %d\n", page>>1); exit(0); } copyline(buf, c) char *buf; register char c; { printf("%s", buf); while (c != '\n' && c != EOF) { putchar(c); c = getchar(); } putchar('\n'); } From d85-kai%nada.kth.se@unido Fri Feb 23 21:11:24 1990 Date: Fri, 23 Feb 90 20:46:23 +0100 From: d85-kai@nada.kth.se (Kai-Mikael J{{-Aro) Message-Id: <9002231946.AAdraken14558@nada.kth.se> To: riem@ztivax Subject: Re: Printing two pages on one sheet Newsgroups: comp.sys.mac,comp.lang.postscript In-Reply-To: <904@ztivax.UUCP> Organization: Royal Institute of Technology, Stockholm, Sweden Mark Hahn has written a program, mpage, that does exactly this. Would you like me to send you a copy? -- Kai-Mikael J{{-Aro d85-kai@nada.kth.se "NO DISASSEMBLE!" - No. 5 From d85-kai%nada.kth.se@unido Fri Mar 2 17:04:43 1990 Date: Fri, 2 Mar 90 15:10:59 +0100 From: d85-kai%nada.kth.se@unido (Kai-Mikael J{{-Aro) Message-Id: <9003021410.AAdraken28094@nada.kth.se> To: riem@ztivax Subject: Printing two pages usw. Since I wrote to you another program, multi.ps which does something similar, popped up. I do not know if you have received a copy of this, so I will send you two letters, one containing mpage and one containing multi, both as shar archives. Kai-Mikael J{{-Aro d85-kai@nada.kth.se "NO DISASSEMBLE!" - No. 5 // Sorry, program still not received From rob%siesoft.co.uk%siesoft@sinix Wed Mar 7 12:40:12 1990 Subject: PostScript filter Status: RO I am currently working on the SINIX spooler project for Siemens at SDG in England. Here is a filter which we have used for producing twin-column landscape output. Hope this helps - there is a bug somewhere which causes an error after the document is printed. I haven't looked at this problem yet - you'll only see it if you have a PostScript error handler downloaded in any case. I don't seem to have a working shar available, so have appended the two sources! compile a2ps.c with cc -o a2ps -DUNIX. header.ps should go in /usr/local/lib We have some other filters if you are interested. Rob Henley. 8-< LONG TEXT FOLLOWS! ----------- a2ps.c ---------- /************************************************************************/ /* */ /* Description: Ascii to PostScript printer program. */ /* File: imag:/users/local/a2ps/a2ps.c */ /* Created: Mon Nov 28 15:22:15 1988 by miguel@imag (Miguel Santana) */ /* Version: 2.0 */ /* */ /* Edit history: */ /* 1) Derived of shell program written by evan@csli (Evan Kirshenbaum). */ /* Written in C for improve speed execution and portability. Many */ /* improvements have been added. */ /* */ /* /************************************************************************/ /* * Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr * * Permission is granted to copy and distribute this file in modified * or unmodified form, for noncommercial use, provided (a) this copyright * notice is preserved, (b) no attempt is made to restrict redistribution * of this file, and (c) this file is not distributed as part of any * collection whose redistribution is restricted by a compilation copyright. */ #include <stdio.h> #ifdef ANSIC #include <time.h> #else #ifdef UNIX #include <sys/time.h> #else #ifdef SYSV #include <sys/types.h> #include <sys/timeb.h> #include <time.h> #else error ! #endif #endif #endif #ifndef HEADER_PS #define HEADER_PS "/usr/local/lib/header.ps" #endif #ifndef LINESPERPAGE #define LINESPERPAGE 66 #endif #ifndef COLUMNSPERLINE #define COLUMNSPERLINE 86 #endif #define FALSE 0 #define TRUE 1 int fold_line(); void print_file(); char cut_line(); int column = 0; /* Column number (in current line) */ int line = 0; /* Line number (in current page) */ int line_number = 0; /* Source line number */ int first_page; /* First page for a file */ int nonprinting_chars, chars; /* Number of nonprinting and total chars */ int prefix_width; /* Width in characters for line prefix */ int numbering = TRUE; /* Line numbering option */ int folding = TRUE; /* Line folding option */ int restart = TRUE; /* Restart page number at each file option */ int only_printable = FALSE; /* Replace non printable char by space option */ int interpret = TRUE; /* Interpret TAB, FF and BS chars option */ int print_binaries = FALSE; /* Force printing for binary files */ char * pname; main(argc, argv) int argc; char ** argv; { int narg; char * arg; pname = argv[0]; /* Option processing */ arg = argv[narg = 1]; while (narg < argc && arg[0] == '-') { switch (arg[1]) { case 'b': if (arg[2] != NULL) goto usage; print_binaries = TRUE; break; case 'f': if (arg[2] != NULL) goto usage; folding = TRUE; break; case 'i': if (arg[2] != NULL) goto usage; interpret = TRUE; break; case 'n': if (arg[2] == NULL) { numbering = TRUE; break; } if (arg[3] != NULL) goto usage; switch (arg[2]) { case 'b': print_binaries = FALSE; break; case 'f': folding = FALSE; break; case 'i': interpret = FALSE; break; case 'n': numbering = FALSE; break; case 'r': restart = FALSE; break; case 'v': only_printable = TRUE; break; default: goto usage; } break; case 'r': if (arg[2] != NULL) goto usage; restart = TRUE; break; case 'v': if (arg[2] != NULL) goto usage; only_printable = FALSE; break; default: usage: fprintf(stderr, "%s: usage: a2ps [-n{bfinrv}] [-b] [-f] [-i] [-n] [-r] [-v] [f1 f2 ... fn]\n", pname); exit(1); } arg = argv[++narg]; } /* * the next test was >=, but a2ps didn't work as a filter with * no parameters. */ if (narg > argc) goto usage; /* Header printing (postcript prolog) */ print_header(); /* Print files designated or standard input */ prefix_width = numbering ? 6 : 1; if (narg >= argc) print_file("stdin"); else { while (narg < argc) { if (freopen(arg, "r", stdin) == NULL) { fprintf(stderr, "%s: Error opening %s\n", pname, arg); printf("cleanup\n"); exit(1); } print_file(arg); arg = argv[++narg]; } } printf("cleanup\n"); printf("\014end\n%% \n%% End Of Job\n%% \n\004"); /* SA 23.2.89 */ } void print_file(name) char *name; { register int c; int start_line, continue_exit; int char_width; /* * Printing binary files is not very useful. We stop printing * if we detect one of these files. Our heuristic to detect them: * if 50% characters of first page are non-printing characters, * the file is a binary file. * Option -b force binary files impression. */ first_page = TRUE; nonprinting_chars = chars = 0; /* * Preprocessing (before printing): * - TABs expansion (see interpret option) * - FF and BS interpretation * - replace non printable characters by a space or a char sequence * like: * ^X for ascii codes < 0x20 (X = [@, A, B, ...]) * ^? for del char * M-c for ascii codes > 0x3f * - prefix parents and backslash ['(', ')', '\'] by backslash * (escape character in postcript) */ column = 0; line = line_number = 0; start_line = TRUE; printf("(%s) newfile\n", name); if (restart) printf("/sheet 1 def\n"); printf("startpage\n"); c = getchar(); while (c != EOF) { /* Form feed */ if (c == '\f' && interpret) { if (!start_line) printf(") s\n"); start_line = TRUE; printf("endpage startpage\n"); if (first_page && is_binaryfile(name)) return; line = 0; if ((c = getchar()) == EOF) break; } /* Start a new line? */ if (start_line) { if (numbering) printf("(%-5d ", ++line_number); else printf("( "); start_line = FALSE; } /* Interpret each character */ switch (c) { case '\b': if (!interpret) goto print; if (column > 0) column--; putchar(c); break; case '\n': column = 0; start_line = TRUE; printf(") s\n"); if (++line >= LINESPERPAGE) { printf("endpage startpage\n"); if (first_page && is_binaryfile(name)) return; line = 0; } break; case '\t': if (interpret) { continue_exit = FALSE; do { if (++column + prefix_width > COLUMNSPERLINE) if (folding) { if (fold_line(name) == FALSE) return; } else { c = cut_line(); continue_exit = TRUE; break; } putchar(' '); } while (column & 0x7); if (continue_exit) continue; break; } default: print: if (only_printable) char_width = 1; else { char_width = c > 0177 ? 2 : 0; char_width += c < ' ' || c == 0177 ? 2 : 1; } if (prefix_width + (column += char_width) > COLUMNSPERLINE) if (folding) { if (fold_line(name) == FALSE) return; } else { c = cut_line(); continue; } if (c == '(' || c == ')' || c == '\\') putchar('\\'); if (c >= ' ' && c < 0177) putchar(c); else { nonprinting_chars++; if (only_printable) putchar(' '); else { if (c > 0177) { printf("M-"); c &= 0177; } if (c < ' ') printf("^%c", c+'@'); else if (c == 0177) printf("^?"); else putchar(c); } } chars++; break; } c = getchar(); } if (!start_line) printf(") s\n"); printf("endpage\n"); } int fold_line(name) char *name; { column = 0; printf(") s\n"); if (++line >= LINESPERPAGE) { printf("endpage startpage\n"); if (first_page && is_binaryfile(name)) return FALSE; line = 0; } if (numbering) printf("( "); else printf("( "); return TRUE; } char cut_line() { char c; while ((c = getchar()) != EOF && c != '\n' && c != '\f'); return c; } is_binaryfile(name) char *name; { first_page = FALSE; if (!print_binaries && (nonprinting_chars*100 / chars) >= 75) { fprintf(stderr, "%s: %s is a binary file: printing aborted\n", pname, name); return TRUE; } return FALSE; } print_header() { register int c; FILE *f; char *string; #ifdef ANSIC time_t date; #else #ifdef UNIX struct timeval date; struct tm *p; #else #ifdef SYSV struct timeb date; #endif #endif #endif if ((f = fopen(HEADER_PS, "r")) == NULL) { fprintf(stderr, "%s: Postscript header missing (%s)\n", pname, HEADER_PS); exit(1); } /* Header file printing */ while ((c = getc(f)) != EOF) putchar(c); /* Retrieve date and hour */ #ifdef ANSIC if (time(&date) == -1) { fprintf(stderr, "Error calculing time\n"); exit(1); } string = ctime(&date); /* and print them */ printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11); #else #ifdef UNIX (void) gettimeofday(&date, (struct timezone *)0); p = localtime(&date.tv_sec); string = asctime(p); /* and print them */ printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11); #else #ifdef SYSV (void)ftime(&date); string = ctime(&date.time); printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11); #endif #endif #endif /* Go on */ printf("startdoc\n"); } 8-< --- header.ps %! PostScript Source Code % % File: imag:/users/local/a2ps/header.ps % Created: Tue Nov 29 12:14:02 1988 by miguel@imag (Miguel Santana) % Version: 2.0 % Description: PostScript prolog for a2ps ascii to PostScript program. % % Edit History: % - Original version by evan@csli (Evan Kirshenbaum). % - Modified by miguel@imag to: % 1) Correct an overflow bug when printing page number 10 (operator % cvs). % 2) Define two other variables (sheetwidth, sheetheight) describing % the physical page (actually A4 format). % 3) Minor changes (reorganization, comments, etc). % % Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr % % Permission is granted to copy and distribute this file in modified % or unmodified form, for noncommercial use, provided (a) this copyright % notice is preserved, (b) no attempt is made to restrict redistribution % of this file, and (c) this file is not distributed as part of any % collection whose redistribution is restricted by a compilation copyright. % % General macros. /xdef {exch def} bind def /inch {72 mul} bind def /getfont {exch findfont exch scalefont} bind def % Dimensions of a physical page. /sheetwidth 11.7 inch def /sheetheight 8.25 inch def % Character size for differents fonts. /filenamefontsize 12 def /datefontsize filenamefontsize 2 sub def /headerfontsize filenamefontsize 4 add def /bodyfontsize 6.8 def % Font assignment to differents kinds of "objects" /filenamefont /Helvetica-Bold filenamefontsize getfont def /datefont /Helvetica datefontsize getfont def /bodyfont /Courier bodyfontsize getfont def % Logical page attributs (a half of a real page or sheet). /linesperpage 66 def /sidemargin 4 def /topmargin 4 def /pagewidth bodyfont setfont (0) stringwidth pop 86 mul sidemargin dup add add def /pageheight bodyfontsize linesperpage mul topmargin dup add add headerfontsize add def % Upper corner for a logical page. Coordinate x is not the same for left % and right pages: upperx is an array of two elements, indexed by sheetside. /uppery sheetheight pageheight add 2 div def /upperx [ sheetwidth pagewidth 2 mul sub 3 div % upperx for left page dup 2 mul pagewidth add % upperx for right page ] def % String used to make easy printing numbers /pnum 12 string def /empty 12 string def % Function startdoc: initializes printer and global variables. /startdoc { sheetheight 0 inch translate % new origin for the coordinate system 90 rotate % landscape format /sheetside 0 def % sheet side that contains current page /sheet 1 def % sheet number } bind def % Function newfile: init file name and reset page number for each new file. /newfile { /filename xdef /pagenum 1 def cleanup } bind def % Function cleanup: terminates printing, flushing last page if necessary. /cleanup { sheetside 1 eq { /sheetside 0 def sheetnumber /sheet sheet 1 add def copypage erasepage } if } bind def % % Function startpage: prints page header and page border and initializes % printing of the file lines. /startpage { printheader printborder upperx sheetside get sidemargin add uppery topmargin sub bodyfontsize sub headerfontsize sub moveto bodyfont setfont } bind def % Function printheader: prints page header. /printheader { upperx sheetside get uppery headerfontsize sub 1 add moveto datefont setfont gsave sidemargin 2 rmoveto date show % date/hour grestore gsave pagenum pnum cvs pagewidth sidemargin sub pnum stringwidth pop sub (Page ) stringwidth pop sub 3 rmoveto (Page ) show pnum show % page number grestore empty pnum copy gsave filenamefont setfont pagewidth filename stringwidth pop sub 2 div 2 rmoveto filename show % file name grestore } bind def % Function printborder: prints border page. /printborder { upperx sheetside get uppery moveto gsave % print the four sides pagewidth 0 rlineto % of the square 0 pageheight neg rlineto pagewidth neg 0 rlineto closepath stroke grestore 0 headerfontsize neg rmoveto pagewidth 0 rlineto stroke } bind def % % Function endpage: adds a sheet number to the page (footnote) and prints % the formatted page (physical impression). Activated at the end of each % source page (linesperpage reached or FF character). /endpage { sheetside 1 eq { /sheetside 0 def sheetnumber copypage erasepage /sheet sheet 1 add def } { /sheetside 1 def } ifelse /pagenum pagenum 1 add def } bind def % Function sheetnumber: prints the sheet number. /sheetnumber { sheetwidth upperx 0 get sub sidemargin add sheetheight uppery sub headerfontsize sub moveto datefont setfont sheet pnum cvs show empty pnum copy } bind def % Function s: print a source line /s { gsave show grestore 0 bodyfontsize neg rmoveto } bind def