dvidvi-1.0.orig/ 40755 765 144 0 6431315461 12200 5ustar davidusersdvidvi-1.0.orig/a5bookle.hlp100644 765 144 1675 6415674711 14524 0ustar davidusers! This help file assumes the symbol A5BOOKLET has been created. 1 A5BOOKLET USAGE: A5BOOKLET file[.dvi] EXAMPLE: $ latex foo ! foo.tex should use the A5 style $ a5booklet foo ! creates part1.dvi and part2.dvi The A5BOOKLET command reads a given DVI file and creates two new DVI files that can be used to produce an A5 booklet suitable for folding and stapling. It is assumed the given DVI file has a page format suitable for A5 paper. (LaTeX users should have something like "\documentstyle[uacs,a5]{article}" in their source file.) If the two new DVI files are successfully created then information will be displayed showing you how to preview these files and how to PSPRINT them to create the desired booklet. NB: The A5BOOKLET command uses a program called DVIDVI to do the required pagination tricks. This program can be used to produce other types of documents; see disk$utils:[utilities.tex.dvidvi]read.me. dvidvi-1.0.orig/a5test.tex100644 765 144 761 6415674703 14221 0ustar davidusers\documentstyle[a5]{article} \nofiles \begin{document} \Huge This is page 1.\newpage This is page 2.\newpage This is page 3.\newpage This is page 4.\newpage This is page 5.\newpage This is page 6.\newpage This is page 7.\newpage This is page 8.\newpage This is page 9.\newpage This is page 10.\newpage This is page 11.\newpage This is page 12.\newpage This is page 13.\newpage This is page 14.\newpage This is page 15.\newpage This is page 16.\newpage This is page 17.\newpage \end{document} dvidvi-1.0.orig/dvidvi.1100644 765 144 11417 6415674664 13707 0ustar davidusers.TH DVIDVI L "March 1994" .SH NAME .PP dvidvi \- selects and/or re-arranges pages in a TeX dvi file .SH SYNOPSIS .PP dvidvi [param] infile outfile .SH DESCRIPTION .SS Copyright dvidvi 1.0, Copyright (C) 1988-91, Radical Eye Software .SS Introduction .PP The dvidvi program converts a dvi file into another dvi file, with perhaps certain changes. .br .SS Parameters .PP -f n page n is first page selected .br -l n page n is last page selected .in +10 .ti -10 -n n select at most n pages. Notice that n is the number of pages selected, independently of the number of pages actually contained in a sheet .ti -10 -i { n1..n2 | n1 }[,...] .br include pages (ranges allowed). When this option is used, ONLY the specified pages are selected. However, we can exclude from these pages with the option -x .ti -10 -x { n1..n2 | n1 }[,...] .br exclude pages (ranges allowed) .ti -10 -q work in quiet mode, that is do not print in the screen messages of how the work is being done. .ti -10 -r reverse the order of the pages. .PP The page numbers for the above options -f -l -i and -x can be specified in different ways. .in +4 .ti -4 1) If a number n is given, it is interpreted as the n'th page from the begining of the .dvi file. Of course, this number is independent of the page number assigned by TeX. .ti -4 2) TeX page numbers are those who are actually written in the page; these page numbers can be modified, for example, by using the TeX commands \\pagenumbering, \\setcounter{page}{n}, and \\addtocounter{page}{n}. A TeX page number can be specified by preceding the number n with the character @. Thus, if you specify -f @25 -l @30 you select the pages between 25 and 30, these numbers being those assigned by TeX. .ti -4 3) However, several pages can have the same TeX page number in a .dvi file. For example, the introductory pages in a book are numbered i, ii, and so on until the first chapter begins and then, the pages are numbered 1, 2, etc. In this case, the pages numbered i and 1 in the .dvi file have the same TeX page number. If you want to select for example the second occurrence of the page numbered 1, you can specify a page number as (@2)1. Thus @1 is equivalent to (@1)1. For example, if you specify -f (@2)1 -l(@2)10 you select the pages between 1 and 10 of the first chapter, not the introductory pages between i and x. .PP There is another parameter that tells dvidvi how you want to change page layout and specifications. This is the -m parameter. .in +4 .ti -4 * The number preceding the colon is the modulo value. Everything will be done in chunks of pages this big. If there is no colon, than the default value is assumed to be one. The last chunk of pages is padded with as many blank pages as necessary. .ti -4 * Following the colon is a comma-separated list of page numbers. These page numbers are with respect to the current chunk of pages, and must lie in the range zero to the modulo value less one. If a negative sign precedes the number, then the page is taken from the mirror chunk; if there are m chunks, then the mirror chunk of chunk n is the chunk numbered m-n-1. Put simply, it is the chunk numbered the same, only from the end. This can be used to reverse pages. If no number is given, the page number defaults to 1. .ti -4 * Following each page number is an optional offset value in parenthesis, which consists of a pair of comma-separated dimensions. Each dimension is a decimal number with an optional unit of measure. The default unit of measure is inches, or the last unit of measure used. All units are in true dimensions. Allowable units of measure are the same that TeX allows: in, mm, cm, pt, pc, dd, and cc. .SH EXAMPLES .PP .in +10 .ti -10 -m - Reverses the order of the pages. This time, both the modulo and the page number are defaulted. .ti -10 -m 2:0 Selects the first, third, fifth, etc. pages from the file. Print this one after printing the next, taking the paper out of the feed tray and reinserting it into the paper feed. .ti -10 -m 2:-1 Selects the second, fourth, etc. pages, and writes them in reverse order. .ti -10 -m 4:-1,2(4.25in,0in) .ti -10 -m 4:-3,0(4.25in,0in) .br Useful for printing a little booklet, four pages to a sheet, double-sided, for stapling in the middle. Print the first one, put the stack back into the printer upside down, and print the second. The `in' specifications are superfluous. .ti -10 -m ,(1pt,1) .br Scare your system administrator! Actually, things are so blurry with this option, you may want to send enemies letters printed like this. *Long* letters. .ti -10 -m 4:0(5.5in,4.25),3(0,4.25) .ti -10 -m 4:1(0in,4.25),2(5.5,4.25) .br Print a four-page card on one sheet. Print the first, rotate the paper 180 degrees and feed it again. (PostScript people can do funny tricks with PostScript so this isn't necessary.) dvidvi-1.0.orig/dvidvi.c100644 765 144 101147 6415674702 14002 0ustar davidusers/* * This program converts dvi files to dvi files; * the command line options are: * * page n is first page selected -f n * page n is last page selected -l n * print at most n pages -n n * include pages (ranges allowed) -i { n1..n2 | n1 }[,...] * exclude pages (ranges allowed) -x { n1..n2 | n1 }[,...] * work in quiet mode -q * reverse pages -r * select even -m 2:1 * select odd -m 2:0 * print both on same page -m 2:0,1(5.5in,0in) * do folded brochures -m 4:-3,0(5.5in,0in) * -m 4:1,-2(5.5in,0in) * etc. * * The original program is by Tomas Rokicki (version 0.5) but it was * modified and improved by Esteban ZIMANYI ezimanyi@rc1.vub.ac.be * to give version 1.0. * * This version has been tested for the IBM PC and compatibles under * compilers Turbo C 2.0 and Microsoft C 6.0. * */ #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #define BANNER "\nThis is dvidvi 1.0, Copyright (C) 1988-91, Radical Eye Software\n" #define STRINGSIZE (500) /* maximum number of strings in program */ #ifndef VMS #include #include #else /* VMS */ #include "sys$library:stdio.h" /* AKT: added sys$library: */ #include #endif /* VMS */ #define MAXPPERP (32) /* defines READBIN, WRITEBIN, PATHSEP and DIRSEP*/ #ifdef MSDOS #define READBIN "rb" /* MSDOS must use binary mode */ #define WRITEBIN "wb" #define PATHSEP ';' #define DIRSEP '\\' #else #ifdef VMS #define READBIN "rb" /* VMS must use binary mode */ #define WRITEBIN "wb" #define PATHSEP ',' #define DIRSEP ':' #else #define READBIN "r" /* UNIX doesn't care */ #define WRITEBIN "w" #define PATHSEP ':' #define DIRSEP '/' #endif #endif #ifdef XENIX #define SHORTINT #else #undef SHORTINT #endif #ifdef MSDOS #define SHORTINT #endif /* * Type declarations. integer must be a 32-bit signed; shalfword must * be a sixteen-bit signed; halfword must be a sixteen-bit unsigned; * quarterword must be an eight-bit unsigned. */ typedef long integer; typedef char boolean; typedef short shalfword ; typedef unsigned short halfword ; typedef unsigned char quarterword ; typedef short Boolean ; /* * Some globals to keep everyone happy. */ integer numpages ; /* the total number of pages in the dvi file. */ integer TeXfonts[256] ; /* information about each font */ char fontseen[256] ; /* have we defined this font yet? */ int modulo ; /* our mod value */ struct pagespec { int pageno, reversed ; long hoffset, voffset ; /* in scaled points */ } pages[MAXPPERP] ; /* the organization of the pages on output */ int pagesperpage ; /* how many pages crammed onto each page? */ FILE *infile ; /* input dvi file (cannot be a stream) */ FILE *outfile ; /* output dvi file */ char *temp ; /* a temporary place to put things */ char *nextstring, *maxstring ; char *oname=NULL ; /* output dvi file name */ char *iname ; /* input dvi file name */ char *strings ; /* pointer of the string pool */ char banner[] = BANNER ; /* the startup message */ integer inlength ; /* the length of the input dvi file */ integer postloc ; /* location of the postamble */ integer mag ; /* magnification factor */ integer pagecount ; /* number of actual pages */ integer landscape = 0; /* if landscape special, here it is! */ int rem0special ; /* should we remove the first first-page special? */ integer prevpp = -1 ; /* previous page pointer on output */ integer outputpages ; /* number of pages output */ integer dviloc ; /* our position in the output file */ integer pagefake ; /* number of pages, rounded up to multiple of modulo */ Boolean firsttransf = 0, lasttransf = 0; integer firstpage ; /* first page selected (option -p) */ integer lastpage ; /* last page selected (option -l) */ integer maxpages ; /* maximum number of page selected (option -n) */ short quiet ; /* quiet mode (option -q) */ Boolean exctransf[40][2] ; /* if the ranges of pages to exclude (option -x) have to be transformed */ integer exclude[40][2] ; /* the ranges of pages to exclude (option -x) It is supposed that there are at most 40 ranges to exclude in the command line */ short excludeseq ; /* number of ranges to exclude (option -x) */ Boolean inctransf[40][2] ; /* if the ranges of pages to exclude (option -x) have to be transformed */ integer include[40][2] ; /* the ranges of pages to include (option -i) It is supposed that there are at most 40 ranges to include in the command line */ short includeseq ; /* number of ranges to include (option -i) */ integer *pageloc ; integer *pagenumbers ; int prettycolumn ; /* the column we are at when running pretty */ /* * This array holds values that indicate the length of a command, if * we aren't concerned with that command (which is most of them) or * zero, if it is a special case. This makes running through the * dvi file a lot easier (and probably faster) than any form of * dispatch table, especially since we really don't care what the * pages are made of. */ short comlen[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0-15 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 16-31 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 32-47 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 48-63 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 64-79 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80-95 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 96-111 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 112-127 */ 2, 3, 4, 5, 9, 2, 3, 4, 5, 9, 1, 0, 0, 1, 1, 2, /* 128-143 */ 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 2, 3, 4, /* 144-159 */ 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, /* 160-175 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 176-191 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 192-207 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 208-223 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 0, /* 224-239 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };/* 240-255 */ /* * Input bytes from the dvi file. * These routines could probably be sped up significantly; but they are * very machine dependent, so I will leave such tuning to the installer. * They simply get and return bytes in batches of one, two, three, and four, * updating the current position as necessary. */ void abortpage() { error("! unexpected eof on DVI file") ; } shalfword dvibyte() { register shalfword i ; if ((i=getc(infile))==EOF) abortpage() ; return(i) ; } halfword twobytes() { register halfword i ; i = dvibyte() ; return(i*256+dvibyte()) ; } integer threebytes() { register integer i ; i = twobytes() ; return(i*256+dvibyte()) ; } shalfword signedbyte() { register shalfword i ; if ((i=getc(infile))==EOF) abortpage() ; if (i<128) return(i) ; else return(i-256) ; } shalfword signedpair() { register shalfword i ; i = signedbyte() ; return(i*256+dvibyte()) ; } integer signedtrio() { register integer i ; i = signedpair() ; return(i*256+dvibyte()) ; } integer signedquad() { register integer i ; i = signedpair() ; return(i*65536+twobytes()) ; } /* * Routines for the transformation of the pages specified with * the @ parameter into the actual number of page from the file * * trans(p,q) looks for the q'th occurrence of the page numbered p * transformpages makes the transformation for the options -f -i -l -x */ integer transf(p,q) integer p; halfword q; { int i=0, j=0; while( j != q && i < pagecount ) if ( pagenumbers[i++] == p ) j++; if ( j != q ) error ("! Page specified not found"); return (i++); } void transformpages() { int i; if (firsttransf) firstpage=transf(firstpage,firsttransf); if (lasttransf) lastpage=transf(lastpage,lasttransf); for ( i= 0; i< 40; i++) { if (exctransf[i][0]) exclude[i][0]=transf(exclude[i][0],exctransf[i][0]); if (exctransf[i][1]) exclude[i][1]=transf(exclude[i][1],exctransf[i][1]); if (inctransf[i][0]) include[i][0]=transf(include[i][0],inctransf[i][0]); if (inctransf[i][1]) include[i][1]=transf(include[i][1],inctransf[i][1]); } } /* * */ integer fontdeflen(p) integer p; { fseek(infile,p+14,SEEK_SET); return (16L+dvibyte()+dvibyte()); } /* * Simulation of dvibuf, get the character located at the position * p in the input dvi file */ unsigned char dvibuf(p) integer p; { fseek(infile,p,SEEK_SET); return(dvibyte()); } /* * Read a string of length n from the file into the string temp */ void stringdvibuf(p,n) integer p,n; { fseek(infile,p,SEEK_SET); while ( n-- > 0 ) *temp++ = dvibyte(); } /* * Print a usage error messsage, and quit. */ usage() { (void)fprintf(stderr,banner); (void)fprintf(stderr,"Usage: dvidvi [options] input[.dvi] [output]\n"); (void)fprintf(stderr,"where options are:\n"); (void)fprintf(stderr," [-f n] first page printed [-l n] last page printed\n"); (void)fprintf(stderr," [-n n] print at most n pages \n"); (void)fprintf(stderr," [-i {n1..n2 | n3}[,...]] include pages\n"); (void)fprintf(stderr," [-x {n1..n2 | n3}[,...]] exclude pages\n"); (void)fprintf(stderr," [-q] quiet mode [-r] reverse pages\n"); (void)fprintf(stderr," [-m modulo:pagespecs]\n"); #ifndef VMS exit(1) ; #else /* VMS */ exit(0x10000002) ; /* AKT: was exit(1) */ #endif /* VMS */ } /* * Print an error message, and exit if it is fatal. */ error(s) char *s ; { (void)fprintf(stderr, "%s\n", s) ; /* AKT: was dvidvi: %s */ if (*s == '!') #ifndef VMS exit(1) ; #else /* VMS */ exit(0x10000002) ; /* AKT: was exit(1) */ #endif /* VMS */ } /* * This function calculates approximately (whole + num/den) * sf. * No need for real extreme accuracy; one ten thousandth of an * inch should be sufficient. * * No `sf' parameter means to use an old one; inches are assumed * originally. * * Assumptions: * * 0 <= num < den <= 10000 * 0 <= whole */ integer defaultscale = 4736286 ; integer scale(whole, num, den, sf) integer whole, num, den, sf ; { integer v ; if (sf) defaultscale = sf ; else sf = defaultscale ; v = whole * sf + num * (sf / den) ; if (v / sf != whole || v < 0 || v > 0x40000000L) error("! arithmetic overflow in parameter") ; sf = sf % den ; v += (sf * num * 2 + den) / (2 * den) ; return(v) ; } /* * Multiplies *p by 1000 and divides it by mag. Avoiding overflow. * * 1 <= mag <= 1000000 ; * 0 <= *p <= 2^30 * * (Could blow up if a parameter * mag / 1000 > 2^30 sp.) */ scalemag(p) long *p ; { int negative ; negative = 0 ; if (*p < 0) { negative = 1 ; *p = - *p ; } *p = 1000 * (*p / mag) + (2000 * (*p % mag) + mag) / (2 * mag) ; if (negative) *p = - *p ; } /* * Convert a sequence of digits into an integer; return -1 if no digits. * Advance the passed pointer as well. */ integer myatol(s) char **s ; { register char *p ; register integer result ; result = 0 ; p = *s ; while ('0' <= *p && *p <= '9') { if (result > 100000000) error("! arithmetic overflow in parameter") ; result = 10 * result + *p++ - '0' ; } if (p == *s) usage() ; else { *s = p ; return(result) ; } } /* * Get a dimension, allowing all the various extensions, and * defaults. */ integer myatodim(s) char **s ; { register integer w, num, den ; register char *p ; int negative = 0 ; p = *s ; if (**s == '-') { (*s)++ ; negative = 1 ; } w = myatol(s) ; if (w < 0) usage() ; p = *s ; num = 0 ; den = 1 ; if (*p == '.') { p++ ; while ('0' <= *p && *p <= '9') { if (den < 1000) { den *= 10 ; num = num * 10 + *p - '0' ; } p++ ; } } /* * Allowed units are `in', `cm', `mm', `pt', `sp', `cc', `dd', and `pc'; * must be in lower case. */ if (*p == 'c' && p[1] == 'm') { /* centimeters need to be multiplied by 72.27 * 2^16 / 2.54, or 1 864 680 */ w = scale(w, num, den, 1864680L) ; } else if (*p == 'p' && p[1] == 't') { /* real points need to be multiplied by 2^16 */ w = scale(w, num, den, 65536L) ; } else if (*p == 'p' && p[1] == 'c') { /* picas need to be multiplied by 65536 * 12, or 786 432 */ w = scale(w, num, den, 786432L) ; } else if (*p == 'm' && p[1] == 'm') { /* millimeters need to be multiplied by 72.27 * 2^16 / 25.4, or 186 468 */ w = scale(w, num, den, 186468L) ; } else if (*p == 's' && p[1] == 'p') { /* scaled points are already taken care of; simply round */ w = scale(w, num, den, 1L) ; } else if (*p == 'b' && p[1] == 'p') { /* big points need to be multiplied by 72.27 * 65536 / 72, or 65782 */ w = scale(w, num, den, 65782L) ; } else if (*p == 'd' && p[1] == 'd') { /* didot points need to be multiplied by 65536 * 1238 / 1157, or 70124 */ w = scale(w, num, den, 70124L) ; } else if (*p == 'c' && p[1] == 'c') { /* cicero need to be multiplied by 65536 * 1238 / 1157 * 12, or 841 489 */ w = scale(w, num, den, 841489L) ; } else if (*p == 'i' && p[1] == 'n') { /* inches need to be multiplied by 72.27 * 65536, or 4 736 286 */ w = scale(w, num, den, 4736286L) ; } else { /* use default values */ w = scale(w, num, den, 0L) ; p -= 2 ; } p += 2 ; *s = p ; return(negative?-w:w) ; } /* * This function determine if the page has to be printed * depending on the values of options -f, -l, -i and -x */ short selectedpage (n) integer n; { short i; if ( firstpage > n || n > lastpage ) return(0); for ( i=0 ; i < excludeseq ; i++ ) if ( exclude[i][0] <= n && n <= exclude[i][1] ) return(0); if (includeseq == 0) return (1); for ( i=0 ; i < includeseq ; i++ ) if ( include[i][0] <= n && n <= include[i][1] ) return(1); return(0); } /* * Initialize sets up all the globals and data structures. */ void initialize() { int i; /* initialize values in case of option -m is not specified */ modulo = 1 ; pages[0].hoffset = 0 ; pages[0].voffset = 0 ; pages[0].pageno = 0 ; pages[0].reversed = 0 ; pagesperpage = 1 ; for ( i= 0; i< 40; i++) { exctransf[i][0] = exctransf[i][1] = 0; inctransf[i][0] = inctransf[i][1] = 0; } firsttransf = lasttransf = 0; excludeseq = 0; includeseq = 0; firstpage = 1; lastpage = 1000000; maxpages = 1000000; quiet = 0; strings =(char *) malloc(STRINGSIZE) ; if (strings == 0) error("! no memory for strings") ; maxpages = 100000 ; nextstring = strings ; iname = strings ; *nextstring++ = 0 ; maxstring = strings + STRINGSIZE - 200; } /* * Parse the arguments to the routine, and stuff everything away * into those globals above. */ processargs(argc, argv) int argc ; char *argv[] ; { char *p, *q ; int i, pageno, lastext = -1 ; long hoffset, voffset ; int reversed ; initialize (); if (argc < 2 || argc > 8) usage() ; /* * This next whole big section of code is straightforward; we just scan * the options. An argument can either immediately follow its option letter * or be separated by spaces. Any argument not preceded by '-' and an * option letter is considered a file name. */ for (i=1; i MAXPPERP) error("! modulo must lie between 1 and 32") ; p++ ; } /* * This loop grabs all of the page specifications. */ pagesperpage = 0 ; while (*p != 0) { if (pagesperpage >= MAXPPERP) error("! too many page specifications") ; if (*p == '-') { reversed = 1 ; p++ ; } else reversed = 0 ; if (*p == 0 || *p == '(' || *p == ',') pageno = 0 ; else pageno = myatol(&p) ; if (*p == '(') { p++ ; hoffset = myatodim(&p) ; if (*p++ != ',') usage() ; voffset = myatodim(&p) ; if (*p++ != ')') usage() ; } else { hoffset = 0 ; voffset = 0 ; } pages[pagesperpage].hoffset = hoffset ; pages[pagesperpage].voffset = voffset ; pages[pagesperpage].pageno = pageno ; pages[pagesperpage].reversed = reversed ; pagesperpage++ ; if (*p == ',') p++ ; } /* while */ break ; case 'n' : if (*p == 0 && argv[i+1]) p = argv[++i] ; #ifdef SHORTINT if (sscanf(p, "%ld", &maxpages)==0) #else /* ~SHORTINT */ if (sscanf(p, "%d", &maxpages)==0) #endif /* ~SHORTINT */ error("! Bad number of pages option (-n).") ; break ; case 'q' : case 'Q' : quiet = 0 ; break ; case 'r' : case 'R' : pages[0].reversed = 1; break ; case 'x' : if (*p == 0 && argv[i+1]) p = argv[++i] ; while (*p != 0) { if (*p == '(' && *(p+1) == '@' ) { p+=2; exctransf[excludeseq][0] = myatol(&p); p++; } else if (*p == '@') { p++; exctransf[excludeseq][0] = 1 ; } exclude[excludeseq][0]=myatol(&p); if (*p == '.' && *(p+1) == '.' ) { p += 2; if (*p == '(' && *(p+1) == '@' ) { p+=2; exctransf[excludeseq][1] = myatol(&p); p++; } else if (*p == '@') { p++; exctransf[excludeseq][1] = 1 ; } exclude[excludeseq][1] = myatol(&p); } else { exclude[excludeseq][1] = exclude[excludeseq][0]; exctransf[excludeseq][0] = exctransf[excludeseq][1] ; } excludeseq++ ; if (*p != ',' && *p !=0 ) error("! Bad page range option (-x).") ; if (*p == ',' ) p++ ; } /* while */ break ; case '?' : usage() ; break ; default: error("! Bad option, not one of filmnqrx?") ; } /* switch c */ } else { /* this a file name */ if (*iname == 0) { /* input file name */ register char *p ; lastext = 0 ; iname = nextstring ; p = argv[i] ; while (*p) { *nextstring = *p++ ; if (*nextstring == '.') lastext = nextstring - iname ; else if (*nextstring == '/' || *nextstring == ':') lastext = 0 ; nextstring++ ; } if (lastext == 0) { lastext = nextstring - iname ; *nextstring++ = '.' ; *nextstring++ = 'd' ; *nextstring++ = 'v' ; *nextstring++ = 'i' ; } *nextstring++ = 0 ; if ((infile=fopen(iname, READBIN))==NULL) error("! can't open input file") ; } else { /* output file name */ register char *p ; lastext = 0 ; oname = nextstring ; p = argv[i] ; while (*p) { *nextstring = *p++ ; if (*nextstring == '.') lastext = nextstring - oname ; else if (*nextstring == '/' || *nextstring == ':') lastext = 0 ; nextstring++ ; } if (lastext == 0) { lastext = nextstring - oname ; *nextstring++ = '.' ; *nextstring++ = 'd' ; *nextstring++ = 'v' ; *nextstring++ = 'i' ; } *nextstring++ = 0 ; if (freopen(oname, WRITEBIN, stdout)==NULL) error("! can't open output file") ; } /* end output file name */ } /* else argument with '-' */ } /* for */ if (*iname == 0) { (void)fprintf(stderr, banner) ; error("! no input file specified"); } /* Inserted by djc@dsmail.hmi.de 3.8.1994 */ if(!oname) oname="stdout"; if (*oname != 0 && !quiet) { (void)fprintf(stderr, banner) ; (void)fprintf(stderr, "%s -> %s\n",iname,oname); temp = nextstring ; } } /* * Grabs a pointer, and checks it for validity. */ integer ptr(where) register integer where ; { fseek(infile,where,SEEK_SET); where = signedquad() ; if (where < -1L || where > inlength) error("! dvi file malformed; impossible pointer") ; return(where) ; } /* * This routine store the page locations by tracing the pointers backwards. */ void searchpageloc() { integer p,num ; num=pagecount-1; for (p = ptr(postloc+1); num > 0; num--) { if (dvibuf(p) != 139) error("! missed a bop somehow") ; else { pageloc[num]=p; pagenumbers[num]=signedquad(); } p = ptr(p+41) ; } pageloc[num]=p; (void)dvibuf(p); pagenumbers[num]=signedquad(); } /* * This routine simply reads the entire dvi file, and then initializes * some values about it. */ readdvifile() { integer p ; unsigned char c,d,e ; fseek(infile, 0L, 2) ; inlength = ftell(infile) ; if (inlength < 10) error("! dvi file too short") ; fseek(infile,-3L,SEEK_CUR); for (p=inlength - 3; p > 0; p--) { c = dvibyte (); d = dvibyte (); e = dvibyte (); if (c == 2 && d == 0xdf /* dave fuchs */ && e == 0xdf) break ; fseek(infile,-4L,SEEK_CUR); } if (p < 10) error("! rather short dvi file, ain't it?") ; postloc = ptr(p-4) ; fseek(infile,postloc+5L,SEEK_SET); if (signedquad() != 25400000 || signedquad() != 473628672) error("! change this program to support non-TeX num/den values") ; mag = signedquad() ; if (mag < 1 || mag > 1000000) error("! impossible magnification value") ; fseek(infile,postloc+27L,SEEK_SET); pagecount = twobytes() ; if (pagecount < 1 || pagecount > 1000000) error("! impossible page count value") ; /* * That's enough error checking; we probably have a correct dvi file. * Let's convert all the values we got from the command line into * units that we can actually use in the dvi file. */ for (p=0; p> 8)) ; outdvibyte((unsigned char)(v & 255)) ; } /* * Send out a longword. */ outdviquad(v) integer v ; { outdvi2(v >> 16) ; outdvi2(v & 65535) ; } /* * This routine just copies some stuff from the buffer on out. * Suppose the file is positioned correctly before */ putbuf(length) integer length ; { while ( length-- > 0 ) outdvibyte(dvibyte()) ; } /* * This routine outputs a string, terminated by null. */ putstr(s) register unsigned char *s ; { while (*s) outdvibyte(*s++) ; } /* * Here we write the preamble to the dvi file. */ writepreamble() { /* just copy the first 14 bytes of the file */ fseek(infile,0L,SEEK_SET); putbuf(14L) ; /* and put our identifier. */ putstr("\015dvidvi output") ; } /* * This routine writes out a font definition. */ putfontdef(f) int f ; { integer p,q ; p = TeXfonts[f] ; q=fontdeflen(p) ; fseek(infile,p,SEEK_SET); putbuf(q) ; } /* * The postamble is next. */ writepostamble() { int i ; integer p ; p = dviloc ; outdvibyte(248) ; outdviquad(prevpp) ; fseek(infile,postloc+5,SEEK_SET); putbuf(20L) ; outdvi2(twobytes()+1L) ; /* increase stack depth by 1 */ outdvi2(outputpages) ; for (i=0; i<256; i++) if (fontseen[i]) putfontdef(i) ; outdvibyte(249) ; outdviquad(p) ; outdvibyte(2) ; outdviquad(0xdfdfdfdfL) ; while (dviloc & 3) outdvibyte(0xdf) ; fclose(stdout) ; } /* * This routine starts a page, by writing out a bop command. */ beginpage() { int i ; integer p ; p = dviloc ; outdvibyte(139) ; outdviquad(outputpages+1) ; for (i=0; i<9; i++) outdviquad(0L) ; outdviquad(prevpp) ; prevpp = p ; } /* * This routine sends out a page. We need to handle the * landscape special, though. */ dopage(num) integer num ; { register integer p,q ; register int len ; integer v, oldp ; unsigned char c; /* * We want to take the base 10 log of the number. It's probably * small, so we do it quick. */ if (! quiet) { int t = num+1, i = 0 ; if (t < 0) { t = -t ; i++ ; } do { i++ ; t /= 10 ; } while (t > 0) ; if (i + prettycolumn > 76) { fprintf(stderr, "\n") ; prettycolumn = 0 ; } prettycolumn += i + 1 ; #ifdef SHORTINT (void)fprintf(stderr, "[%ld", num+1) ; #else /* ~SHORTINT */ (void)fprintf(stderr, "[%d", num+1) ; #endif /* ~SHORTINT */ (void)fflush(stderr) ; } p = pageloc[num] + 45 ; c=dvibuf(p); while (c != 140) { if ((len=comlen[c]) > 0) { /* most commands are simple */ outdvibyte(c); putbuf((long)len-1) ; p += len ; } else { /* but there are a few we need to treat specially */ len = c ; if (171 <= len && len <= 235) { p++ ; if (len == 235) { len = dvibyte (); p++ ;} else len -= 171 ; if (!fontseen[len]) { putfontdef(len) ; fontseen[len] = 1 ; fseek(infile,p,SEEK_SET); } if (len < 64) outdvibyte(171 + len) ; else { outdvibyte(235) ; outdvibyte(len) ; } } else { v = 0 ; oldp = p++ ; switch(len) { case 242: v = dvibyte() ; p++ ; break ; case 241: v = (v << 8) + dvibyte() ; p++ ; break ; case 240: v = (v << 8) + dvibyte() ; p++ ; break ; case 239: v = (v << 8) + dvibyte() ; p++ ; /* * Remove a landscape special on page 0, if one is found. */ stringdvibuf(oldp + len - 327,9); if (num || ! rem0special || strncmp(temp, "landscape", 9)) { fseek (infile,oldp,SEEK_SET); putbuf(v + len - 237) ; } p = oldp + v + len - 237 ; fseek(infile,p,SEEK_SET); break ; case 243: case 244: case 245: case 246: p += len - 230 ; p += dvibuf(p) ; p += dvibyte() + 2 ; fseek(infile,p,SEEK_SET); break ; default: fprintf(stderr, "Bad dvi command was %d at %ld\n", len, p) ; error("! lost sync dvi in file lost dvi sync file in") ; } } } c=dvibyte(); } if (! quiet) { (void)fprintf(stderr, "] ") ; (void)fflush(stderr) ; prettycolumn += 2 ; } } /* * Here we end a page. Simple enough. */ endpage() { outputpages++ ; outdvibyte(140) ; } /* * This is our main routine for output, which runs through all the * pages we need to output. */ writedvifile() { integer pagenum ; int ppp ; integer actualpageno ; struct pagespec *ps ; integer p ; Boolean beginp ; writepreamble() ; pagefake = (pagecount + modulo - 1) / modulo * modulo ; if ( maxpages < pagefake ) pagefake = maxpages; for (pagenum = 0; pagenum < pagefake; pagenum += modulo) { beginp = 1 ; for (ppp = 0, ps=pages; ppp < pagesperpage; ppp++, ps++) { if (ps->reversed) actualpageno = pagefake - pagenum - modulo + ps->pageno ; else actualpageno = pagenum + ps->pageno ; if (actualpageno < pagecount && selectedpage(actualpageno+1) ) { if (beginp) { beginpage() ; beginp = 0 ; } if (landscape) { fseek(infile,landscape,SEEK_SET); putbuf(dvibuf(landscape+1)+2L) ; landscape = 0 ; } if (pagesperpage) outdvibyte(141) ; if (ps->hoffset) { outdvibyte(146) ; outdviquad(ps->hoffset) ; } if (ps->voffset) { outdvibyte(160) ; outdviquad(ps->voffset) ; } dopage(actualpageno) ; if (pagesperpage) outdvibyte(142) ; } } if (beginp != 1) endpage() ; } writepostamble() ; } main(argc, argv) int argc ; char *argv[] ; { processargs(argc, argv) ; readdvifile() ; writedvifile() ; }