Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!munnari.oz.au!murtoa.cs.mu.oz.au!ditmela!yarra!chris From: chris@yarra.oz.au (Chris Jankowski) Newsgroups: comp.lang.postscript Subject: Summary: saving trees - a tool needed Summary: 3 ways Keywords: mpage Message-ID: <5174@yarra.oz.au> Date: 8 Nov 89 05:47:09 GMT References: <5110@yarra.oz.au> Reply-To: chris@yarra.oz.au (Chris Jankowski) Organization: Pyramid Technology Corp Pty Ltd, Melbourne Lines: 651 Original question: ================= >If I have a simple document (no graphics and other fancies) already >formatted in Postscript how can I print a selection of pages from it? Summary (in order of work required): ======= 1. Use psrev from Transcript package by Adobe (RTFM again). 2. Use a C program, source appended. 3. Write your own program - algorithm outlines appended. Thanks to all who responded. Details: ======= 3. Algorithm. ------------- From: raymond@bosco.Berkeley.EDU (Raymond Chen) raymond@math.berkeley.edu [1] Copy everything from the beginning of the file to the "%%EndProlog" line. [2] When you hit a "%%Page" directive, increment your internal page number counter. If you want this page, start copying, and stop when you hit the next "%%Page" directive. [3] Repeat for each page of the document, until you hit a "%%Trailer" directive. Copy everything after "%%Trailer" to your output file. ----------------- From: J Greely if the first line of the file doesn't start with '%!PS-Adobe', scream bloody murder and die save all lines before the first '%%Page:' line in a file named header parse out the sheet number from the '%%Page:' line save everything before the next '%%Page:' line in a file named . Don't save the '%%Page:' line! keep doing this until you can't find another '%%Page:' line the last page is not followed by another '%%Page:', so stop at the '%%Trailer' line save everything from the '%%Trailer' line on in a file named trailer You now have a set of files (header,1..,trailer). To print them, do the following: print header, inserting '%%Pages: (atend)' as the second line. If you don't do this, your output won't conform. print the desired pages, prefixed by a '%%Page:' comment containing the sheet order. For strict conformance, they *must* be numbered sequentially starting at 1, but printers don't care (Adobe's own software cheats on this) print trailer print the actual pagecount, as a '%%Pages: n' comment. For conformance with version 1.0, this must be the last '%%Pages:' line in the document. Unfortunately, the relevant sentence was deleted from version 2.0, so you're only safe if you delete all other '%%Pages:' lines in the trailer. If you're not interested in rearranging pages, you can speed things up quite a bit by discarding undesired pages as you read them, and hacking '%%Page:' lines on the fly. Note that everything I say ignores some of the advanced comment structures possible in version 2.0, like embedded documents (which may contain their own comment structures, including '%%Trailer'). For details about this, read the Adobe Document Structuring Conventions document, version 2.1. 2. C source code. ================= I compiled the following program in att universe and it does what I want. From: Jingbai Wang /* Here is a program I developed called psscribe.c that is self-instructive*/ /* Copyright (C) 1989 by Jingbai Wang This program is released to public as shareware. Any individual and institution can use, modify and distribute it freely provided the copyright note and the following box are retained. One exeption is that profitable distribution (i.e., charge over the cost of materials and ship&handling) should have author's written permission. */ /* ********************************************************************** * This program is an auxiliary program for Scribe TEC.mak * * desgined by myself. * * It is used to manipulate Scribe PostScript output files * * or equally standard PostScript output from a text formatter * * such that a long .ps file can be cut into shorter ones * * and double-sided documents can be separated into two * * .ps files for even-sided and odd-sided pages * * * * The user can set up the programs for other purposes too * * Copyright by Jingbai Wang August 1988 * ************************************************************************/ /* It is intended to have it adoptable to any systems. It is in my mind for VMS, MSDOS/PC-DOS and unix for the time being. */ #define STRSIZE 1024 #define FILEMAX 100 #define PROLENGTH 3600000 #include #include #include #define CLS fprintf(stderr, "\n\n\n\n"); /* Global variables */ char psfile[80]="", Prolog[PROLENGTH], outfile1[FILEMAX][80], outfile[80], evenfile[80], oddfile[80], prestring[80]=""; FILE *psfileptr, *Oddpage, *Evenpage, *Allpage; int partnum=0, filestart[FILEMAX], fileend[FILEMAX], currentpage=0, file_flag=0; long int prolength=0, pageend[1000]; char string[1024]; get_prolog() { int l; prolength = 0; while(1){ fgets(&Prolog[prolength], 1024, psfileptr); if( memcmp(&Prolog[prolength], "%%EndProlog", 11)==0) {while (Prolog[++prolength] != 0) ; return; } else while (Prolog[++prolength] != 0) ; } } main(argc, argv) int argc; char *argv[]; { start_up(); if (argc>1) {strcpy(psfile, argv[1]); file_flag=1;} pro_info(); } get_file() { int status, len, i, dot_check; dot_check=0; if(file_flag==0) {CLS; fprintf(stdout, "\n PostScript file name (path and name)> "); scanf("%s", psfile); } len=strlen(psfile); for (i=0; i "); fflush(stdin); scanf("%d", &yes); fflush(stdin); switch(yes) { case 1: get_file(); page_map(); break; case 2: partnum=1; get_file(); get_prolog(); extract(); break; case 3: get_file(); get_prolog(); fprintf(stderr, "\n\n How many parts to divide>"); scanf("%d", &partnum); fflush(stdin); divide(); break; case 4: get_file(); get_prolog(); even_odd(); break; case 5: get_file(); get_prolog(); reverse_page(); break; case 6: merge(); break; case 7: get_file(); fix_zeta();break; case 8: exit(-1); default: fprintf(stderr, "%c", 7); goto select; } #if unix|ultrix scanf("%c", &junk); fflush(stdin); #endif hit_continue(); clear_up(); goto start; } even_odd() { long int i; int len; fprintf(stderr, " Output file name odd pages > "); scanf("%s", oddfile); fprintf(stderr, " Output file name even pages > "); scanf("%s", evenfile); Evenpage=fopen(evenfile, "w"); Oddpage=fopen(oddfile, "w"); for (i=0; i "); scanf("%s", outfile); Allpage=fopen(outfile, "w"); fprintf(stderr, " Starting page >"); scanf("%d", &filestart[0]); fflush(stdin); fprintf(stderr, " End page >"); scanf("%d", &fileend[0]); fflush(stdin); while(currentpage ", i+1); scanf("%s", outfile1[i]); if (i==0) { fprintf(stderr, " Part %d starts at page # >", i+1); scanf("%d", &filestart[i]); fflush(stdin); } else filestart[i]=fileend[i-1]+1; fprintf(stderr, " Part %d ends at page # >", i+1); scanf("%d", &fileend[i]); fflush(stdin); } if (filestart[0]>1){ while(currentpage0) { fprintf(Allpage, "%s", prestring); prestring[len-2]=0; fprintf(stderr, "[%s]", &prestring[8]); } while(1) { if( fgets(string, 1024, psfileptr)==NULL) { return; } if (memcmp(string, "%%Page:", 7)==0) {currentpage++; if (currentpage>fileend[number]) {strcpy(prestring, string); return;} len=strlen(string); string[len-2]=0; fprintf(stdout, "[%s]", &string[8]); string[len-2]=32; } fprintf(Allpage, "%s", string); } } page_map() { int count, len; fprintf(stderr, " Map file filename for output (2 for screen)-> "); fflush(stdin); scanf("%s", outfile); if (outfile[0]=='2') Allpage=stdout; else Allpage=fopen(outfile, "w"); fprintf(stderr , "\n\n"); while(1) { if( fgets(string, 1024, psfileptr)==NULL) { fclose(psfileptr); if (Allpage!=stdout) fclose(Allpage); fflush(stdin); return; } if (memcmp(string, "%%Page:", 7)==0) {currentpage++; len=strlen(string); string[len-1]=0; count++; if (count>10) {count=0; fprintf(Allpage, "\n");} fprintf(Allpage, "[%s]", &string[8]); } } } reverse_page() { int i; long int j; fprintf(stderr, " Filename for output file -> "); fflush(stdin); scanf("%s", outfile); Allpage=fopen(outfile, "w"); for (i=0; i0; i--) { for (j=pageend[i-1]; j to continue -->"); scanf("%c", &junk); fflush(stdin); } merge() { int i; fprintf(stderr, "\n\n How many files to merge? "); scanf("%d", &partnum); fflush(stdin); if (file_flag==1) {strcpy(outfile, psfile); fprintf(stderr, "\n Filename for output > %s", outfile); } else { fprintf(stderr, "\n Filename for output > "); scanf("%s", outfile); } Allpage=fopen(outfile, "w"); for (i=0; i", i+1); scanf("%s", outfile1[i]); if ( (psfileptr=fopen(outfile1[i], "r"))==NULL) {fprintf(stderr, " .ps file not found "); goto again;} fclose(psfileptr); } for (i=0; i0) get_prolog(); while(fgets(string, 1024, psfileptr)!=NULL) fprintf(Allpage, "%s", string); fclose(psfileptr); } } fix_zeta() { int i; char ch; fprintf(stderr, "\n Filename for output > "); scanf("%s", outfile); for (i=0; i<685; i++) fgetc(psfileptr); if (fgetc(psfileptr)!='d') { fclose(psfileptr); fprintf(stderr, "\n Wrong version of converted .lps file"); return; } fgetc(psfileptr); fgetc(psfileptr); Allpage=fopen(outfile, "w"); fprintf(Allpage, "%%!\n\ /s { 72 mul 300 div } def /steps { 72 mul 2032 div } def /d { count 0 gt { s exch s exch moveto { count 0 gt \n\ { s exch s exch lineto } { exit } ifelse } loop 0.3 setlinewidth stroke clear } if } def /g { count 0 gt { s exch s exch moveto\n\ { count 0 gt { s exch s exch lineto } { exit } ifelse } loop [3 5] 0 setdash 0.5 setlinewidth stroke clear [] 0 setdash } if } def\n\ /h { /Courier findfont 6 scalefont setfont -6 -26 moveto } def /f { -6 -16 moveto } def\n\ /n { d newpath } def /a0 { arc stroke } def /a1 { arcn stroke } def /mr { moveto rotate } def\n\ /cf { /Courier findfont } def /ss { scalefont setfont } def /ur { rotate } def /dd { [] 0 setdash } def d\n"); while ((ch=fgetc(psfileptr))!=EOF) fprintf(Allpage, "%c", ch); fclose(psfileptr); fclose(Allpage); } hit_continue() { char junk; fprintf(stderr, "\n\n Hit to continue -->"); fflush(stdin); fflush(stdin); fflush(stdin); scanf("%c", &junk); fflush(stdin); } clear_up() { long int i; partnum=0; for (i=0; i