Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!allbery From: mark@pyrdc.UUCP (Mark Hahn) Newsgroups: comp.sources.misc Subject: v09i089: Mpage (2 of 2): Reduce and Print Text or Postscript Keywords: postscript, mpage, reduce Message-ID: <74698@uunet.UU.NET> Date: 27 Dec 89 00:19:48 GMT Sender: allbery@uunet.UU.NET Organization: Pyramid Technology, Government Systems Lines: 1156 Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Posting-number: Volume 9, Issue 89 Submitted-by: mark@pyrdc.UUCP (Mark Hahn) Archive-name: mpage/part02 . . . . . . . . . . . The Obligitory Dotted Line . . . . . . . . . . . . #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of archive 2 (of 2)." # Contents: Makefile.mpage TODO mp_args.c mp_main.c mp_page.c # mp_sample.c mpage.1 # Wrapped by mark@pyrdc on Tue Dec 26 16:29:23 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile.mpage' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile.mpage'\" else echo shar: Extracting \"'Makefile.mpage'\" \(1172 characters\) sed "s/^X//" >'Makefile.mpage' <<'END_OF_FILE' X# X# $Header: Makefile,v 1.3 89/05/25 09:06:55 mark Exp $ X# XHEAD = mp_head.h XSRCS = mp_main.c mp_glob.c mp_text.c mp_post.c mp_file.c mp_page.c mp_args.c XMOBJ = mp_main.o mp_glob.o mp_text.o mp_post.o mp_file.o mp_page.o mp_args.o XSMPL = mp_sample.c mp_page.c mp_glob.c mp_args.c XSOBJ = mp_sample.o mp_page.o mp_glob.o mp_args.o X X X#CFLAGS = -gx -DDEBUG XCFLAGS = -gx X X.SUFFIXES: .c,v X Xdefault: mpage msample Makefile.mpage X @echo Done! X Xmpage: $(MOBJ) X $(CC) $(CFLAGS) -o mpage $(MOBJ) X Xmsample: $(SOBJ) X $(CC) $(CFLAGS) -o msample $(SOBJ) X XMakefile.mpage: Makefile X Xclean: X rm -rf $(MOBJ) mpage mpage.ps X Xmp_main.o: $(HEAD) mp_main.c X $(CC) -c $(CFLAGS) mp_main.c X Xmp_glob.o: $(HEAD) mp_glob.c X $(CC) -c $(CFLAGS) mp_glob.c X Xmp_text.o: $(HEAD) mp_text.c X $(CC) -c $(CFLAGS) mp_text.c X Xmp_post.o: $(HEAD) mp_post.c X $(CC) -c $(CFLAGS) mp_post.c X Xmp_file.o: $(HEAD) mp_file.c X $(CC) -c $(CFLAGS) mp_file.c X Xmp_page.o: $(HEAD) mp_page.c X $(CC) -c $(CFLAGS) mp_page.c X Xmp_args.o: $(HEAD) mp_args.c X $(CC) -c $(CFLAGS) mp_args.c X Xmp_sample.o: $(HEAD) X $(CC) -c $(CFLAGS) $*.c X Xmpage.ps: mpage.1 X psroff -t -man mpage.1 > mpage.ps X X X# add your proper install stuff Xinstall: END_OF_FILE echo shar: NEWLINE appended to \"'Makefile.mpage'\" if test 1173 -ne `wc -c <'Makefile.mpage'`; then echo shar: \"'Makefile.mpage'\" unpacked with wrong size! fi # end of 'Makefile.mpage' fi if test -f 'TODO' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'TODO'\" else echo shar: Extracting \"'TODO'\" \(1684 characters\) sed "s/^X//" >'TODO' <<'END_OF_FILE' XCurrent Wish List: X X X- Should print a help string when invoked as "mpage". However, like Xcat(1), I chose to default to processing standard input when no files Xare specified. I will change this so that the file "-" refers to Xstandard input and hence you will have to type something like: X ls -Rl | mpage -8 - XMore thought is required here. (you comments solicited) X X X- Add support for handeling ATT style spoolers. Or any type spooler. XShouldn't be that difficult. X X X- Support for reducing mpage output. I.E. if I do: X mpage -8P file.txt | mpage -8 XI should get 64-up output. Problems are that the PostScript code Xproduced is not "recursive". The end-of-page macro in particular Xsuffers under re-definition, you get blank pages. Another problems is Xresolution of the printer. See the next Wish item. X X X- Better handeling of PostScript input. The current stuff works, but Xit is not general enough. I am currently learning more here, thanks Xto the "Green Book" and will work on a cleaner parser for Version 3. X(Oh-my-goodness, a pre-announcement ;-) X XPerhaps I should convert the whole PostScript processing routing to be Xa "Finite Automata". Each line will represent a "token" parsed by its Xcomment, output will be based upon transitions from state to state. XThe automata should allow states and transitions to be added dynamicly Xso that we can adapt to differening structure conventions, and Xdiffering PostScript code generators (psdit, dvi2ps, etc ...) X X X- Fix A4 paper handeling. X X X- Add better timing information, possible adding command line Xarguments to control the amount of timing information added to the Xfile. (Eyuk, more arguments:-( X X X- Lots more, I'm sure. END_OF_FILE echo shar: NEWLINE appended to \"'TODO'\" if test 1685 -ne `wc -c <'TODO'`; then echo shar: \"'TODO'\" unpacked with wrong size! fi # end of 'TODO' fi if test -f 'mp_args.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mp_args.c'\" else echo shar: Extracting \"'mp_args.c'\" \(5080 characters\) sed "s/^X//" >'mp_args.c' <<'END_OF_FILE' X# include X# include X X# ifndef lint Xstatic char *rcs_id = X "@(#) $Header: mp_args.c,v 2.6 89/05/25 15:43:07 mark Exp $"; X# endif X X# include "mp_head.h" X X/* X * mpage: a program to reduce pages of print so that several pages X * of output appear on one printed page. X * X * Written by: X * ...!uunet!\ Mark Hahn, Sr Systems Engineer X * >pyrdc!mark Pyramid Technology Corporation X * ...!pyramid!/ Vienna, Va (703)848-2050 X * X * X * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia X * X * Permission is granted to anyone to make or distribute verbatim X * copies of this document as received, in any medium, provided X * that this copyright notice notice is preserved, and that the X * distributor grants the recipient permission for further X * redistribution as permitted by this notice. X * X */ X X/* $Log: mp_args.c,v $ X * Revision 2.6 89/05/25 15:43:07 mark X * added the -b options as a converse to the -o option. X * X * Revision 2.5 89/05/25 10:42:39 mark X * changes to print a page count on stderr after the print job is queued. X * X * Revision 2.4 89/05/25 08:57:47 mark X * rearranged the rcs header keywords for better readability. X * X * Revision 2.3 89/05/22 14:41:03 mark X * Fixed the type-o in the rcs identification string X * X * Revision 2.2 89/05/22 14:38:06 mark X * Added rcs identification usable with the "what" program X * X * Revision 2.1 89/05/22 14:31:29 mark X * New Major Revision X * X * Revision 1.1 89/05/22 14:25:29 mark X * Initial revision X * */ X Xdo_args(argc, argv, envflag) X int argc; X char **argv; X int envflag; X{ X char *optstr; X int consumed; X int currarg; X int opterrors; X X opterrors = 0; X for (currarg = 1; currarg < argc; currarg++) { X if (*argv[currarg] != '-') { X if (envflag) { X opterrors++; X } X break; X } X optstr = argv[currarg]; X consumed = 0; X while (*++optstr && ! consumed) { X switch (*optstr) { X default: X fprintf(stderr,"%s: unknown option -%c\n", X MPAGE, *optstr); X opterrors++; X break; X case '1': X sheetindex = 0; X break; X case '2': X sheetindex = 1; X break; X case '4': X sheetindex = 2; X break; X case '8': X sheetindex = 3; X break; X case 'A': /* A4 sized, european paper */ X opt_a4 = 1; X set_page(); X break; X case 'a': /* across */ X sheetorder = LEFTRIGHT; X break; X case 'h': X ++optstr; X opt_doheader = 1; X (void)strcpy(opt_header, optstr); X consumed = 1; X break; X case 'L': X ++optstr; X opt_lines = atoi(optstr); X consumed = 1; X break; X case 'l': /* landscape */ X sheetaspect = LANDSCAPE; X break; X case 'n': /* normal */ X sheetaspect = NORMAL; X break; X case 'o': /* print outlines */ X opt_outline = 1; X break; X case 'b': /* don't print outlines */ X opt_outline = 0; X break; X case 'P': /* Printer */ X ++optstr; X (void) strcpy(printer, optstr); X consumed = 1; X break; X case 'p': /* pr */ X opt_pr++; X break; X case 's': /* silent (don't print page count) */ X opt_verbose = 0; X break; X case 'u': /* updown */ X sheetorder = UPDOWN; X break; X case 'v': /* verbose (print page count) */ X opt_verbose = 1; X break; X case 'W': X ++optstr; X opt_width = atoi(optstr); X consumed = 1; X break; X } X } X } X if (opterrors) { X return -1; X } X return currarg; X} X Xdo_env() X{ X int argc; X char **argv, **slice(); X char copy[LINESIZE]; X char *env, *getenv(); X X env = getenv("PRINTER"); X if (env) { X strcpy(printer, env); X } X X env = getenv("MPAGE"); X if (env) { X strcpy(copy, env); X argv = slice(copy, &argc); X if (do_args(argc, argv, 1) < 0) { X fprintf(stderr, "%s: error in envronment \"%s\"\n", X MPAGE, env); X return 0; X } X } X return 1; X} X Xchar *slc_argv[20]; X Xchar **slice(string, cntp) X char *string; X int *cntp; X{ X int count; X X /* X * mimic the shell for conformity X */ X slc_argv[0] = MPAGE; X count = 1; X /* X * while there are still characters to be processed X */ X while (*string) { X /* X * skip any leading or leftover white space X */ X while (*string == ' ') { X string++; X } X /* X * make sure we had more than just white space before X * we believe we actually have an argument X */ X if (*string) { X /* X * point the next slot in argv to this string X */ X slc_argv[count] = string; X count += 1; X /* X * and go looking for the end of this string X * which is delienated by a space or NULL X */ X while (*string && *string != ' ') { X string++; X } X /* X * if this not the end of the string, then convert X * the space into a NULL and move forward one byte. X * if this is the end of the string, we already have X * a suitable NULL byte for the string and it also X * drops us out of all the loops X */ X if (*string) { X *string = 0; X string++; X } X } X } X /* X * return the count via the integer pointer we were given X * and put a null pointer into the argv array for conformity X */ X slc_argv[count] = 0; X *cntp = count; X return slc_argv; X} END_OF_FILE echo shar: NEWLINE appended to \"'mp_args.c'\" if test 5081 -ne `wc -c <'mp_args.c'`; then echo shar: \"'mp_args.c'\" unpacked with wrong size! fi # end of 'mp_args.c' fi if test -f 'mp_main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mp_main.c'\" else echo shar: Extracting \"'mp_main.c'\" \(4943 characters\) sed "s/^X//" >'mp_main.c' <<'END_OF_FILE' X# include X# include X X# ifndef lint Xstatic char *rcs_id = X "@(#) $Header: mp_main.c,v 2.5 89/05/25 10:42:35 mark Exp $"; X# endif X X# include "mp_head.h" X X/* X * mpage: a program to reduce pages of print so that several pages X * of output appear on one printed page. X * X * Written by: X * ...!uunet!\ Mark Hahn, Sr Systems Engineer X * >pyrdc!mark Pyramid Technology Corporation X * ...!pyramid!/ Vienna, Va (703)848-2050 X * X * X * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia X * X * Permission is granted to anyone to make or distribute verbatim X * copies of this document as received, in any medium, provided X * that this copyright notice notice is preserved, and that the X * distributor grants the recipient permission for further X * redistribution as permitted by this notice. X * X */ X X/* $Log: mp_main.c,v $ X * Revision 2.5 89/05/25 10:42:35 mark X * changes to print a page count on stderr after the print job is queued. X * X * Revision 2.4 89/05/25 08:58:25 mark X * rearranged the rcs header keywords for better readability. X * X * Revision 2.3 89/05/22 14:40:28 mark X * Fixed the type-o in the rcs identification string X * X * Revision 2.2 89/05/22 14:37:30 mark X * Added rcs identification usable with the "what" program X * X * Revision 2.1 89/05/22 14:31:15 mark X * New Major Revision X * X * Revision 1.1 89/05/22 14:19:56 mark X * Initial revision X * */ X Xmain(argc,argv) X int argc; X char **argv; X{ X FILE *outfd; X int currarg; X struct sheet *thelist; X struct sheet *thesheet; X X /* X * examine the environment for PRINTER and MPAGE environment variables X */ X if (do_env() == 0) { X fprintf(stderr, usage, MPAGE); X exit(1); X } X X currarg = do_args(argc, argv, 0); X if (currarg < 0) { X fprintf(stderr, usage, MPAGE); X exit(1); X } X X /* X * if a printer was specified then create a lpr command using X * the specified printer, else output goes to standard out X */ X if (*printer) { X (void)sprintf(outcommand, "ucb /usr/ucb/lpr -P%s", printer); X if ((outfd = popen(outcommand, "w")) == NULL) { X fprintf(stderr, "%s: cannot create pipe for '%s'\n", X outcommand); X perror(MPAGE); X } X } else { X outfd = stdout; X } X X /* X * pick the array of sheet lists based upon the specified option X */ X if (sheetorder == UPDOWN) { X sheetlist = up_down; X } else { X sheetlist = left_right; X } X X /* X * from the array of sheet lists pick the proper sheet list for X * the given sheetaspect, then select the proper sheet format X * for the given number of redueced pages per output page X */ X thelist = sheetlist[sheetaspect]; X thesheet = &(thelist[sheetindex]); X X /* X * if either lines or columns were specified as options, over X * the default sheets idea of the number of line or cloumns X * per reduced page X */ X if (opt_lines > 0) { X thesheet->sh_plength = opt_lines; X } X if (opt_width > 0) { X thesheet->sh_cwidth = opt_width; X } X X /* X * if there are arguments left over after processing options, then X * these are names of files to process, else process the standard X * input X */ X if (currarg < argc) { X ps_title(argv[currarg], outfd); X for ( ;currarg < argc; currarg++) { X do_file(argv[currarg], thesheet, outfd); X } X } else { X ps_title("", outfd); X do_stdin(thesheet, outfd); X } X /* X * having processed all input, print out a PS trailer X * (timeing stuff stolen from old adobe troff stuff) X */ X fprintf(outfd, "%%%%Trailer\n"); X fprintf(outfd, "statusdict begin jobname print flush"); X fprintf(outfd, " (: Job finished:\\n) print\n"); X fprintf(outfd, "(\\tmpage time (s) = ) print flush usertime "); X fprintf(outfd, "mp_stm sub 1000 div ==\n(\\tmpage pages = ) print "); X fprintf(outfd, "flush pagecount mp_pgc sub ==\nend flush\n"); X fprintf(outfd, "%%%%Pages: %d\n", ps_pagenum); X if (opt_verbose) { X fprintf(stderr, "[%s: %d pages, ", MPAGE, ps_pagenum); X if (*printer == 0) { X fprintf(stderr, "on ]\n"); X } else { X fprintf(stderr, "printer %s]\n", printer); X } X } X /* X * proper clean up to make sure the pipe is flushed X */ X if (*printer) { X (void)pclose(outfd); X } X return 0; X} X X/* X * ps_title prints a post script header suitable for PS processors X */ Xps_title(name, outfd) X char *name; X FILE *outfd; X{ X time_t curr_time; X char *time_str; X X fprintf(outfd, "%%!PS-Adobe-1.0\n"); X fprintf(outfd, "%%%%DocumentFonts: Courier\n"); X fprintf(outfd, "%%%%Title: %s (mpage)\n", name, MPAGE); X fprintf(outfd, "%%%%Creator: %s\n", MPAGE); X (void)time(&curr_time); X time_str = ctime(&curr_time); X fprintf(outfd, "%%%%CreationDate: %s",time_str); X fprintf(outfd, "%%%%Pages: (atend)\n"); X fprintf(outfd, "%%%%BoundingBox: 20 20 596 776\n"); X fprintf(outfd, "%%%%EndComments\n\n"); X fprintf(outfd, "/mp_stm usertime def\n"); X fprintf(outfd, "/mp_pgc statusdict begin pagecount end def\n"); X fprintf(outfd, "statusdict begin /jobname (%s) def end\n", name); X} END_OF_FILE echo shar: NEWLINE appended to \"'mp_main.c'\" if test 4944 -ne `wc -c <'mp_main.c'`; then echo shar: \"'mp_main.c'\" unpacked with wrong size! fi # end of 'mp_main.c' fi if test -f 'mp_page.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mp_page.c'\" else echo shar: Extracting \"'mp_page.c'\" \(5452 characters\) sed "s/^X//" >'mp_page.c' <<'END_OF_FILE' X# include X# include X X# ifndef lint Xstatic char *rcs_id = X "@(#) $Header: mp_page.c,v 2.4 89/05/25 08:58:28 mark Exp $"; X# endif X X# include "mp_head.h" X X/* X * mpage: a program to reduce pages of print so that several pages X * of output appear on one printed page. X * X * Written by: X * ...!uunet!\ Mark Hahn, Sr Systems Engineer X * >pyrdc!mark Pyramid Technology Corporation X * ...!pyramid!/ Vienna, Va (703)848-2050 X * X * X * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia X * X * Permission is granted to anyone to make or distribute verbatim X * copies of this document as received, in any medium, provided X * that this copyright notice notice is preserved, and that the X * distributor grants the recipient permission for further X * redistribution as permitted by this notice. X * X */ X X/* $Log: mp_page.c,v $ X * Revision 2.4 89/05/25 08:58:28 mark X * rearranged the rcs header keywords for better readability. X * X * Revision 2.3 89/05/22 14:41:01 mark X * Fixed the type-o in the rcs identification string X * X * Revision 2.2 89/05/22 14:38:04 mark X * Added rcs identification usable with the "what" program X * X * Revision 2.1 89/05/22 14:31:27 mark X * New Major Revision X * X * Revision 1.1 89/05/22 14:25:52 mark X * Initial revision X * */ X Xset_page() X{ X if (opt_a4) { X ps_width = 596; X ps_height = 842; X } else { X ps_width = 612; X ps_height = 792; X } X} X Xxbase1() X{ X Debug(DB_POINTS, "%%xbase1: %d\n", pg_sheetmargin + pg_pagemargin); X return pg_sheetmargin + pg_pagemargin; X} X Xxbase2() X{ X Debug(DB_POINTS, "%%xbase2: %d\n", (ps_width / 2) + pg_pagemargin); X return (ps_width / 2) + pg_pagemargin; X} X Xybase1() X{ X Debug(DB_POINTS, "%%ybase1: %d\n", pg_sheetmargin + pg_pagemargin); X return pg_sheetmargin + pg_pagemargin; X} X Xybase2() X{ X Debug(DB_POINTS, "%%ybase2: %d\n", X (((ps_height / 2) - pg_sheetmargin) / 2) X + pg_sheetmargin + pg_pagemargin); X return (((ps_height / 2) - pg_sheetmargin) / 2) X + pg_sheetmargin + pg_pagemargin; X} X Xybase3() X{ X Debug(DB_POINTS, "%%ybase3: %d\n", (ps_height / 2) + pg_pagemargin); X return (ps_height / 2) + pg_pagemargin; X} X Xybase4() X{ X Debug(DB_POINTS, "%%ybase4: %d\n", X (((ps_height / 2) - pg_sheetmargin) / 2) X + (ps_height / 2) + pg_pagemargin); X return (((ps_height / 2) - pg_sheetmargin) / 2) X + (ps_height / 2) + pg_pagemargin; X} X Xytop1() X{ X Debug(DB_POINTS, "%%ytop1: %d\n", ybase1() + yht4()); X return ybase1() + yht4(); X} X Xytop2() X{ X Debug(DB_POINTS, "%%ytop2: %d\n", ybase2() + yht4()); X return ybase2() + yht4(); X} X Xytop3() X{ X Debug(DB_POINTS, "%%ytop3: %d\n", ybase3() + yht4()); X return ybase3() + yht4(); X} X Xytop4() X{ X Debug(DB_POINTS, "%%ytop4: %d\n", ybase4() + yht4()); X return ybase4() + yht4(); X} X Xxwid1() X{ X Debug(DB_POINTS, "%%xwid1: %d\n", X ps_width - ((2 * pg_sheetmargin) + (2 * pg_pagemargin))); X return ps_width - ((2 * pg_sheetmargin) + (2 * pg_pagemargin)); X} X Xxwid2() X{ X Debug(DB_POINTS, "%%xwid2: %d\n", X (ps_width / 2) - (pg_sheetmargin + (2 * pg_pagemargin))); X return (ps_width / 2) - (pg_sheetmargin + (2 * pg_pagemargin)); X} X Xyht1() X{ X Debug(DB_POINTS, "%%yht1: %d\n", X ps_height - ((2 * pg_sheetmargin) + (2 * pg_pagemargin))); X return ps_height - ((2 * pg_sheetmargin) + (2 * pg_pagemargin)); X} X Xyht2() X{ X Debug(DB_POINTS, "%%yht2: %d\n", X (ps_height / 2) - (pg_sheetmargin + (2 * pg_pagemargin))); X return (ps_height / 2) - (pg_sheetmargin + (2 * pg_pagemargin)); X} X Xyht4() X{ X Debug(DB_POINTS, "%%yht4: %d\n", X (((ps_height / 2) - pg_sheetmargin) / 2) - (2 * pg_pagemargin)); X return (((ps_height / 2) - pg_sheetmargin) / 2) - (2 * pg_pagemargin); X} X Xoutline_1(outfd) X FILE *outfd; X{ X /* one page outline */ X fprintf(outfd, "0 setlinewidth\n"); X fprintf(outfd, "%3d %3d moveto\n", pg_sheetmargin, pg_sheetmargin); X fprintf(outfd, "%3d %3d lineto\n", pg_sheetmargin, X ps_height - pg_sheetmargin); X fprintf(outfd, "%3d %3d lineto\n", ps_width - pg_sheetmargin, X ps_height - pg_sheetmargin); X fprintf(outfd, "%3d %3d lineto\n", ps_width - pg_sheetmargin, X pg_sheetmargin); X fprintf(outfd, "closepath stroke\n"); X} X Xoutline_2(outfd) X FILE *outfd; X{ X /* two page outline */ X outline_1(outfd); X fprintf(outfd, "%3d %3d moveto\n", pg_sheetmargin, ps_height / 2); X fprintf(outfd, "%3d %3d lineto\n", ps_width - pg_sheetmargin, X ps_height / 2); X fprintf(outfd, "stroke\n"); X} X Xoutline_4(outfd) X FILE *outfd; X{ X /* four page outline */ X outline_2(outfd); X fprintf(outfd, "%3d %3d moveto\n", ps_width / 2 , pg_sheetmargin); X fprintf(outfd, "%3d %3d lineto\n", ps_width / 2 , X ps_height - pg_sheetmargin); X fprintf(outfd, "stroke\n"); X} X Xoutline_8(outfd) X FILE *outfd; X{ X /* eight page outline */ X outline_4(outfd); X fprintf(outfd, "%3d %3d moveto\n", pg_sheetmargin, X ((ps_height / 2) - pg_sheetmargin) / 2 + pg_sheetmargin); X fprintf(outfd, "%3d %3d lineto\n", ps_width - pg_sheetmargin, X ((ps_height / 2) - pg_sheetmargin) / 2 + pg_sheetmargin); X fprintf(outfd, "stroke\n"); X fprintf(outfd, "%3d %3d moveto\n", pg_sheetmargin, X ((ps_height / 2) - pg_sheetmargin) / 2 + (ps_height / 2)); X fprintf(outfd, "%3d %3d lineto\n", ps_width - pg_sheetmargin, X ((ps_height / 2) - pg_sheetmargin) / 2 + (ps_height / 2)); X fprintf(outfd, "stroke\n"); X} X Xmp_outline(outfd, asheet) X FILE *outfd; X struct sheet *asheet; X{ X if (opt_outline) { X (*asheet->sh_outline)(outfd); X } X} END_OF_FILE echo shar: NEWLINE appended to \"'mp_page.c'\" if test 5453 -ne `wc -c <'mp_page.c'`; then echo shar: \"'mp_page.c'\" unpacked with wrong size! fi # end of 'mp_page.c' fi if test -f 'mp_sample.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mp_sample.c'\" else echo shar: Extracting \"'mp_sample.c'\" \(2579 characters\) sed "s/^X//" >'mp_sample.c' <<'END_OF_FILE' X# include X# include X X# ifndef lint Xstatic char *rcs_id = X "@(#) $Header: mp_sample.c,v 1.1 89/05/25 08:58:34 mark Exp $"; X# endif X X# include "mp_head.h" X X/* $Log: mp_sample.c,v $ X * Revision 1.1 89/05/25 08:58:34 mark X * Initial revision X * */ X Xmain( argc, argv) X int argc; X char **argv; X{ X int currarg; X X /* X * examine the environment for PRINTER and MPAGE environment variables X */ X if (do_env() == 0) { X fprintf(stderr, usage, MPAGE); X exit(1); X } X X currarg = do_args(argc, argv, 0); X if (currarg < 0) { X fprintf(stderr, usage, MPAGE); X exit(1); X } X X do_sample(); X} X Xdo_sample() X{ X printf("%%!PS-mpage-layout\n"); X printf("/Courier findfont 8 scalefont setfont\n"); X printf("0 setlinewidth\n"); X X outline_8(stdout); X X urshow(xbase1(), ybase1()); X urshow(xbase1(), ybase2()); X urshow(xbase1(), ybase3()); X urshow(xbase1(), ybase4()); X lrshow(xbase1(), ytop1()); X lrshow(xbase1(), ytop2()); X lrshow(xbase1(), ytop3()); X lrshow(xbase1(), ytop4()); X ulshow(xbase1()+xwid2(), ybase1()); X ulshow(xbase1()+xwid2(), ybase2()); X ulshow(xbase1()+xwid2(), ybase3()); X ulshow(xbase1()+xwid2(), ybase4()); X llshow(xbase1()+xwid2(), ytop1()); X llshow(xbase1()+xwid2(), ytop2()); X llshow(xbase1()+xwid2(), ytop3()); X llshow(xbase1()+xwid2(), ytop4()); X X urshow(xbase2(), ybase1()); X urshow(xbase2(), ybase2()); X urshow(xbase2(), ybase3()); X urshow(xbase2(), ybase4()); X lrshow(xbase2(), ytop1()); X lrshow(xbase2(), ytop2()); X lrshow(xbase2(), ytop3()); X lrshow(xbase2(), ytop4()); X ulshow(xbase2()+xwid2(), ybase1()); X ulshow(xbase2()+xwid2(), ybase2()); X ulshow(xbase2()+xwid2(), ybase3()); X ulshow(xbase2()+xwid2(), ybase4()); X llshow(xbase2()+xwid2(), ytop1()); X llshow(xbase2()+xwid2(), ytop2()); X llshow(xbase2()+xwid2(), ytop3()); X llshow(xbase2()+xwid2(), ytop4()); X printf("showpage\n"); X} X Xurshow(x, y) X{ X printf("%%- point %d,%d\n", x, y); X box(x, y); X printf("\t%d %d moveto (%d,%d) show\n", x+2, y+2, x, y); X} X Xlrshow(x, y) X{ X printf("%%- point %d,%d\n", x, y); X box(x, y); X printf("\t%d %d moveto (%d,%d) show\n", x+2, y-6, x, y); X} X Xulshow(x, y) X{ X printf("%%- point %d,%d\n", x, y); X box(x, y); X printf("\t%d %d moveto\n", x-2, y+2); X printf("\t(%d,%d) dup stringwidth pop -1 mul 0 rmoveto show\n", x, y); X} X Xllshow(x, y) X{ X printf("%%- point %d,%d\n", x, y); X box(x, y); X printf("\t%d %d moveto\n", x-2, y-6); X printf("\t(%d,%d) dup stringwidth pop -1 mul 0 rmoveto show\n", x, y); X} X Xbox(x, y) X{ X printf("\t%d %d moveto %d %d lineto\n", x-1, y, x+1, y); X printf("\t%d %d moveto %d %d lineto\n", x, y-1, x, y+1); X printf("\tstroke\n"); X} END_OF_FILE echo shar: NEWLINE appended to \"'mp_sample.c'\" if test 2580 -ne `wc -c <'mp_sample.c'`; then echo shar: \"'mp_sample.c'\" unpacked with wrong size! fi # end of 'mp_sample.c' fi if test -f 'mpage.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mpage.1'\" else echo shar: Extracting \"'mpage.1'\" \(3717 characters\) sed "s/^X//" >'mpage.1' <<'END_OF_FILE' X.TH MPAGE Local 1/13/87 X.SH NAME Xmpage \- print muliple pages per sheet on POSTSCRIPT printer X.SH SYNOPSIS X\fBmpage [-1248povsnluaA] [-Llines] [-Wwidth] [-hheader] [-Pprinter] X[files...]\fR X.SH DESCRIPTION X.I Mpage Xreads plain text files or POSTSCRIPT documents and prints them on a XPOSTSCRIPT printer with the text reduced in size so that several Xpages apperar on one sheet of paper. This is useful for Xviewing large printouts on a small amount of paper. X.PP XThe following options are recognized: X.TP X.B -8 XPrint 8 normal pages per sheet. X.TP X.B -4 XPrint 4 normal pages per sheet X.I [default]. X.TP X.B -2 XPrint 2 normal pages per sheet. X.TP X.B -1 XPrint 1 normal page per sheet (included for symmetry). X.TP X.B -p XPipe input through X.BR pr ( 1 ) Xbefore printing (assumes the input is a text file). X.TP X.B -o XPrint an outline around each reduced page. X.I [default]. X.TP X.B -b XDon't print an outline, so the reduced pages appear on a blank Xbackground. X.TP X.B -v XPrint to the standard error output a count of the number of sheets Xproduced for printing (verbose mode) X.I [default]. X.TP X.B -s XDon't print the count of sheets (silent mode). X.TP X.B -n XPrint in normal (portrait) mode. The page is 66 lines long by 80 Xcharacters wide by default X.I [default]. X.TP X.B -l XPrint in landscape mode. The page is 55 lines long by 132 Xcharacters wide by default. X.TP X.B -u XLayout the pages on the sheet so that sucessively numbered pages run Xdown the sheet (as opposed to left to right) X.I [default]. X.TP X.B -a XLayout the pages on the sheet so that sucessively numbered pages run Xaccross the page from left to right. X.TP X.B -A XPrepare output for European A4 sized paper. X.TP X.BI -P printer XSpecify the printer to which the POSTSCRIPT output will be sent. XUsing X.B -P Xwith no printer specified will send the POSTSCRIPT to the standard Xoutput. X.I [default: X.BI PostScript\c X.I ]. X.TP X.BI -L lines XAdjust the page reduction parameters so that X.I lines Xlines will fit in the space of one page. XThis overides the default values normally supplied. (See the X.B -l Xand X.B -n Xoptions.) XIf used in conjunction with the X.B -p Xoption then this value is passed to pr as well. X.TP X.BI -W width XAdjust the page reduction parameters so that a line X.I width Xcharacters long will fit in the space of one page. XThis overides the default values normally supplied. (See the X.B -l Xand X.B -n Xoptions.) XIf used in conjunction with the X.B -p Xoption then this value is passed to pr as well. X.TP X.BI -h header XThis is used only when the X.B -p Xswitch is used and is passed as the "\fB-h\fI\ header\fR" option to X.BR pr ( 1 ). X.PP XThe defaults are: mpage -4onuPPostScript. X.SH ENVIRONMENT X.I Mpage Xexamines the X.B PRINTER Xenvironment variable to override its default printer. X.PP X.ne 10 X.I Mpage Xalso examine the X.B MPAGE Xenvironment variable for default option settings. Any option or Xcombination of options can be specified in the X.B MPAGE Xenvironment variable. For example, if MPAGE is set to the string: X.in +1i X.B -2oPqms -L60 X.br X.in -1i Xit would (in the absence of other command line arguments) print 2 Xpages per sheet, 60 lines per page, with outlines, on the printer Xnamed X.B "qms" X(overriding the X.B PRINTER Xenvironment variable, if it exists.) In the environment variable, Xwhite space is used as an option delimeter, and no quoting is Xrecognized. X.PP XAny command line options will override both the X.B PRINTER Xand X.B MPAGE Xenvironment variables. X.SH FILES X/bin/pr /bin/fold X.br X/usr/tmp/mpageXXXXXX X.SH BUGS X.PP XSuffers under the burden of far too many switches. (But X.B I Xwanted the choices!) X.PP XMany others, I'm sure. X.SH VERSION XVersion 2, Released June 1989. X.SH AUTHORS XMark P. Hahn (uunet!pyrdc!mark), Pyramid Technology Corportation END_OF_FILE echo shar: NEWLINE appended to \"'mpage.1'\" if test 3718 -ne `wc -c <'mpage.1'`; then echo shar: \"'mpage.1'\" unpacked with wrong size! fi # end of 'mpage.1' fi echo shar: End of archive 2 \(of 2\). cp /dev/null ark2isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- ...!uunet!\ Mark Hahn, Sr Systems Engineer >pyrdc!mark Pyramid Technology Corporation ...!pyramid!/ Vienna, Va (703)848-2050