ajcd@cs.ed.ac.uk (Angus Duggan) (05/22/91)
Can't remember if I've posted this before; this program rearranges TeX's DVI files into signature ordering, for printing books and booklets. It uses Chris Torek's DVI library (I have version 2.16.1), available in the SeeTeX distribution (look around for a local ftp site for this, or ask Dirk Grunwald (grunwald@edu.colorado.foobar) where to find it. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: Imakefile dvibook.c dvibook.man # Wrapped by ajcd@davaar on Thu Apr 18 20:34:18 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f Imakefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Imakefile\" else echo shar: Extracting \"Imakefile\" \(608 characters\) sed "s/^X//" >Imakefile <<'END_OF_Imakefile' XOBJS =dvibook.o XSRCS =dvibook.c X X LIBTEXROOT= ../ X LIBTEXSRC = ../libtex X LIBTEX = $(LIBTEXSRC)/libtex.a X DEPLIBTEX = $(LIBTEX) X DEPLIBS = $(DEPLIBTEX) XawClientDepLibs XLOCAL_LIBRARIES = $(LIBTEX) X X DEFINES = -I$(LIBTEXROOT) X XFILES =Imakefile dvibook.man Makefile.raw $(SRCS) X Xall: dvibook X XNormalProgramTarget(dvibook,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),$(SYSLIBS)) XInstallProgram(dvibook, $(BINDIR)) XInstallManPage(dvibook,$(MANDIR)) XDependTarget() XTagsTarget() X Xtar: X cd ../..;\ X for file in $(FILES); \ X do \ X tar rf $(TARFILE) $(PRODUCT)/Dvibook/$$file; \ X done END_OF_Imakefile if test 608 -ne `wc -c <Imakefile`; then echo shar: \"Imakefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f dvibook.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"dvibook.c\" else echo shar: Extracting \"dvibook.c\" \(19274 characters\) sed "s/^X//" >dvibook.c <<'END_OF_dvibook.c' X/* X * Copyright (c) 1987, 1989 University of Maryland X * Department of Computer Science. All rights reserved. X * Permission to copy for any purpose is hereby granted X * so long as this copyright notice remains intact. X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/dvi/RCS/dviselect.c,v 3.1 89/08/22 17:16:13 chris Exp $"; X#endif X X/* X * DVI page rearrangement program X * X * Reads DVI version 2 files and rearranges pages into signatures, X * writing a new DVI file. X */ X X#include "libtex/types.h" X#include "libtex/dviclass.h" X#include "libtex/dvicodes.h" X#include "libtex/error.h" X#include "libtex/fio.h" X#include "libtex/gripes.h" X#include "libtex/search.h" X#include <stdio.h> X#include <ctype.h> X#include "libtex/seek.h" X X#define white(x) ((x) == ' ' || (x) == '\t' || (x) == ',') X X#define MAXDVIPAGES 1000 /* max (absolute) pages in DVI file */ X Xchar *ProgName; Xextern char *optarg; Xextern int optind; X X/* Globals */ Xchar serrbuf[BUFSIZ]; /* buffer for stderr */ X X/* X * We will try to keep output lines shorter than MAXCOL characters. X */ X#define MAXCOL 75 X X/* X * We use the following structure to keep track of fonts we have seen. X * The final DVI file lists only the fonts it uses. X */ Xstruct fontinfo { X i32 fi_newindex; /* font number in output file */ X int fi_reallyused; /* true => used on a page we copied */ X i32 fi_checksum; /* the checksum */ X i32 fi_mag; /* the magnification */ X i32 fi_designsize; /* the design size */ X short fi_n1; /* the name header length */ X short fi_n2; /* the name body length */ X char *fi_name; /* the name itself */ X}; X Xint Signature; /* #pages per signature (multiple of 4) */ X Xint SFlag; /* true => -s, silent operation */ X Xstruct search *FontFinder; /* maps from input indicies to fontinfo */ Xi32 NextOutputFontIndex; /* generates output indicies */ Xi32 CurrentFontIndex; /* current (old) index in input */ Xi32 OutputFontIndex; /* current (new) index in ouput */ X Xchar *DVIFileName; /* name of input DVI file */ XFILE *inf; /* the input file itself */ XFILE *outf; /* the output DVI file */ X Xlong StartOfPage[MAXDVIPAGES]; /* The file positions of the X input pages */ X Xlong StartOfLastPage; /* The file position just before we X started the last page */ Xlong CurrentPosition; /* The current position of the file */ X Xint UseThisPage; /* true => current page is selected */ X Xi32 InputPageNumber; /* current absolute page in old DVI file */ Xint NumberOfOutputPages; /* number of pages in new DVI file */ X Xi32 Numerator; /* numerator from DVI file */ Xi32 Denominator; /* denominator from DVI file */ Xi32 DVIMag; /* magnification from DVI file */ X Xi32 Count[10]; /* the 10 \count variables */ X X/* save some string space: we use this a lot */ Xchar writeerr[] = "error writing DVI file"; X Xchar *malloc(), *realloc(); X/* X * You may get lint warnings about sprintf's return value. X * Older versions of 4BSD have `char *sprintf()'. ANSI and X * SysV use `int sprintf()'; so ignore the warnings. X */ X X/* X * Lint gets somewhat confused over putc. X */ X#ifdef lint X#undef putc X#ifdef ultrix /* grr */ X#define putc(c, f) fputc((char)(c), f) X#else X#define putc(c, f) fputc((int)(c), f) X#endif X#endif X X/* X * Print a message to stderr, with an optional leading space, and handling X * long line wraps. X */ Xmessage(space, str, len) X int space; X register char *str; X register int len; X{ X static int beenhere; X static int col; X X if (!beenhere) X space = 0, beenhere++; X if (len == 0) X len = strlen(str); X col += len; X if (space) { X if (col >= MAXCOL) X (void) putc('\n', stderr), col = len; X else X (void) putc(' ', stderr), col++; X } X while (--len >= 0) X (void) putc(*str++, stderr); X (void) fflush(stderr); X} X X/* X * Start a page (process a DVI_BOP). X */ XBeginPage() X{ X register i32 *i; X X OutputFontIndex = -1; /* new page requires respecifying font */ X for (i = Count; i < &Count[10]; i++) X fGetLong(inf, *i); X (void) GetLong(inf); /* previous page pointer */ X X if (!UseThisPage) X return; X X putbyte(outf, DVI_BOP); X for (i = Count; i < &Count[10]; i++) X PutLong(outf, *i); X PutLong(outf, StartOfLastPage); X if (ferror(outf)) X error(1, -1, writeerr); X X StartOfLastPage = CurrentPosition; X CurrentPosition += 45; /* we just wrote this much */ X X if (!SFlag) { /* write nice page usage messages */ X register int z = 0; X register int mlen = 0; X char msg[80]; X X (void) sprintf(msg, "[%ld", (long)Count[0]); X mlen = strlen(msg); X for (i = &Count[1]; i < &Count[10]; i++) { X if (*i == 0) { X z++; X continue; X } X while (--z >= 0) X msg[mlen++] = '.', msg[mlen++] = '0'; X z = 0; X (void) sprintf(msg + mlen, ".%ld", (long)*i); X mlen += strlen(msg + mlen); X } X message(1, msg, mlen); X } X} X X/* X * End a page (process a DVI_EOP). X */ XEndPage() X{ X X if (!UseThisPage) X return; X if (!SFlag) X message(0, "]", 1); X putbyte(outf, DVI_EOP); X if (ferror(outf)) X error(1, -1, writeerr); X CurrentPosition++; X NumberOfOutputPages++; X} X X/* X * For each of the fonts used in the new DVI file, write out a definition. X */ X/* ARGSUSED */ Xvoid XPostAmbleFontEnumerator(addr, key) X char *addr; X i32 key; X{ X X if (((struct fontinfo *)addr)->fi_reallyused) X WriteFont((struct fontinfo *)addr); X} X XHandlePostAmble() X{ X register i32 c; X X (void) GetLong(inf); /* previous page pointer */ X if (GetLong(inf) != Numerator) X GripeMismatchedValue("numerator"); X if (GetLong(inf) != Denominator) X GripeMismatchedValue("denominator"); X if (GetLong(inf) != DVIMag) X GripeMismatchedValue("\\magnification"); X X putbyte(outf, DVI_POST); X PutLong(outf, StartOfLastPage); X PutLong(outf, Numerator); X PutLong(outf, Denominator); X PutLong(outf, DVIMag); X c = GetLong(inf); X PutLong(outf, c); /* tallest page height */ X c = GetLong(inf); X PutLong(outf, c); /* widest page width */ X c = GetWord(inf); X PutWord(outf, c); /* DVI stack size */ X PutWord(outf, NumberOfOutputPages); X StartOfLastPage = CurrentPosition; /* point at post */ X CurrentPosition += 29; /* count all those `put's */ X#ifdef notdef X (void) GetWord(inf); /* skip original number of pages */ X#endif X X /* X * just ignore all the incoming font definitions; we are done with X * input file X */ X X /* X * run through the FontFinder table and dump definitions for the X * fonts we have used. X */ X SEnumerate(FontFinder, PostAmbleFontEnumerator); X X putbyte(outf, DVI_POSTPOST); X PutLong(outf, StartOfLastPage); /* actually start of postamble */ X putbyte(outf, DVI_VERSION); X putbyte(outf, DVI_FILLER); X putbyte(outf, DVI_FILLER); X putbyte(outf, DVI_FILLER); X putbyte(outf, DVI_FILLER); X CurrentPosition += 10; X while (CurrentPosition & 3) { X putbyte(outf, DVI_FILLER); X CurrentPosition++; X } X if (ferror(outf)) X error(1, -1, writeerr); X} X X/* X * Write a font definition to the output file X */ XWriteFont(fi) X register struct fontinfo *fi; X{ X register int l; X register char *s; X X if (fi->fi_newindex < 256) { X putbyte(outf, DVI_FNTDEF1); X putbyte(outf, fi->fi_newindex); X CurrentPosition += 2; X } else if (fi->fi_newindex < 65536) { X putbyte(outf, DVI_FNTDEF2); X PutWord(outf, fi->fi_newindex); X CurrentPosition += 3; X } else if (fi->fi_newindex < 16777216) { X putbyte(outf, DVI_FNTDEF3); X Put3Byte(outf, fi->fi_newindex); X CurrentPosition += 4; X } else { X putbyte(outf, DVI_FNTDEF4); X PutLong(outf, fi->fi_newindex); X CurrentPosition += 5; X } X PutLong(outf, fi->fi_checksum); X PutLong(outf, fi->fi_mag); X PutLong(outf, fi->fi_designsize); X putbyte(outf, fi->fi_n1); X putbyte(outf, fi->fi_n2); X l = fi->fi_n1 + fi->fi_n2; X CurrentPosition += 14 + l; X s = fi->fi_name; X while (--l >= 0) X putbyte(outf, *s++); X} X X/* X * Handle the preamble. Someday we should update the comment field. X */ XHandlePreAmble() X{ X register int n, c; X X c = getc(inf); X if (c == EOF) X GripeUnexpectedDVIEOF(); X if (c != DVI_PRE) X GripeMissingOp("PRE"); X if (getc(inf) != DVI_VERSION) X error(1, 0, "%s is not a DVI version %d file", X DVIFileName, DVI_VERSION); X Numerator = GetLong(inf); X Denominator = GetLong(inf); X DVIMag = GetLong(inf); X putbyte(outf, DVI_PRE); X putbyte(outf, DVI_VERSION); X PutLong(outf, Numerator); X PutLong(outf, Denominator); X PutLong(outf, DVIMag); X X n = UnSign8(GetByte(inf)); X CurrentPosition = 15 + n; /* well, almost */ X putbyte(outf, n); X while (--n >= 0) { X c = GetByte(inf); X putbyte(outf, c); X } X} X Xmain(argc, argv) X int argc; X register char **argv; X{ X register int c; X register char *s; X char *outname = NULL; X X Signature = 0; X X ProgName = *argv; X setbuf(stderr, serrbuf); X X while ((c = getopt(argc, argv, "i:o:s:q")) != EOF) { X switch (c) { X X case 'q': /* silent */ X SFlag++; X break; X X case 'i': X if (DVIFileName != NULL) X goto usage; X DVIFileName = optarg; X break; X X case 'o': X if (outname != NULL) X goto usage; X outname = optarg; X break; X X case 's': X if (Signature != 0) X goto usage; X Signature = atoi(optarg); X if (Signature <= 0) X error(1, -1, "-s parameter must be > 0"); X if (Signature % 4 != 0) X error(1, -1, X "-s parameter must be a multiple of 4"); X break; X X case '?': Xusage: X (void) fprintf(stderr, "\ XUsage: %s [-s signature] [-q] [-i infile] [-o outfile] [infile [outfile]]\n", X ProgName); X (void) fflush(stderr); X exit(1); X } X } X X while (optind < argc) { X s = argv[optind++]; X c = *s; X if (DVIFileName == NULL) X DVIFileName = s; X else if (outname == NULL) X outname = s; X else X goto usage; X } X if (DVIFileName == NULL) { X DVIFileName = "`stdin'"; X inf = stdin; X } else if ((inf = fopen(DVIFileName, "r")) == 0) X error(1, -1, "cannot read %s", DVIFileName); X if (outname == NULL) X outf = stdout; X else if ((outf = fopen(outname, "w")) == 0) X error(1, -1, "cannot write %s", outname); X X if ((FontFinder = SCreate(sizeof(struct fontinfo))) == 0) X error(1, 0, "cannot create font finder (out of memory?)"); X X /* copy inf to TEMP file if not seekable */ X if ((inf = SeekFile(inf)) == NULL) { X error(1, 0, "can't seek file"); X } X InputPageNumber = 0; X StartOfLastPage = -1; X HandlePreAmble(); X ScanDVIFile(); X HandleDVIFile(); X HandlePostAmble(); X if (!SFlag) X (void) fprintf(stderr, "\nWrote %d page%s, %ld bytes\n", X NumberOfOutputPages, NumberOfOutputPages == 1 ? "" : "s", X (long)CurrentPosition); X exit(0); X /* NOTREACHED */ X} X X/* X * Handle a font definition. X */ XHandleFontDef(index) X i32 index; X{ X register struct fontinfo *fi; X register int i; X register char *s; X int def = S_CREATE | S_EXCL; X X if (!UseThisPage) { X if ((fi = (struct fontinfo *)SSearch(FontFinder, index, &def)) == 0) X if (def & S_COLL) X error(1, 0, "font %ld already defined", (long)index); X else X error(1, 0, "cannot stash font %ld (out of memory?)", X (long)index); X fi->fi_reallyused = 0; X fi->fi_checksum = GetLong(inf); X fi->fi_mag = GetLong(inf); X fi->fi_designsize = GetLong(inf); X fi->fi_n1 = UnSign8(GetByte(inf)); X fi->fi_n2 = UnSign8(GetByte(inf)); X i = fi->fi_n1 + fi->fi_n2; X if ((s = malloc((unsigned)i)) == 0) X GripeOutOfMemory(i, "font name"); X fi->fi_name = s; X while (--i >= 0) X *s++ = GetByte(inf); X } else { X (void) GetLong(inf); X (void) GetLong(inf); X (void) GetLong(inf); X i = UnSign8(GetByte(inf)); X i += UnSign8(GetByte(inf)); X while (--i >= 0) X (void) GetByte(inf); X } X} X X/* X * Handle a \special. X */ XHandleSpecial(c, l, p) X int c; X register int l; X register i32 p; X{ X register int i; X X if (UseThisPage) { X putbyte(outf, c); X switch (l) { X X case DPL_UNS1: X putbyte(outf, p); X CurrentPosition += 2; X break; X X case DPL_UNS2: X PutWord(outf, p); X CurrentPosition += 3; X break; X X case DPL_UNS3: X Put3Byte(outf, p); X CurrentPosition += 4; X break; X X case DPL_SGN4: X PutLong(outf, p); X CurrentPosition += 5; X break; X X default: X panic("HandleSpecial l=%d", l); X /* NOTREACHED */ X } X CurrentPosition += p; X while (--p >= 0) { X i = getc(inf); X putbyte(outf, i); X } X if (feof(inf)) X GripeUnexpectedDVIEOF(); X if (ferror(outf)) X error(1, -1, writeerr); X } else X while (--p >= 0) X (void) getc(inf); X} X XReallyUseFont() X{ X register struct fontinfo *fi; X int look = S_LOOKUP; X X fi = (struct fontinfo *)SSearch(FontFinder, CurrentFontIndex, &look); X if (fi == NULL) X error(1, 0, "DVI file requested font %ld without defining it", X (long)CurrentFontIndex); X if (fi->fi_reallyused == 0) { X fi->fi_reallyused++; X fi->fi_newindex = NextOutputFontIndex++; X WriteFont(fi); X } X if (fi->fi_newindex != OutputFontIndex) { X PutFontSelector(fi->fi_newindex); X OutputFontIndex = fi->fi_newindex; X } X} X X/* X * Write a font selection command to the output file X */ XPutFontSelector(index) X i32 index; X{ X X if (index < 64) { X putbyte(outf, index + DVI_FNTNUM0); X CurrentPosition++; X } else if (index < 256) { X putbyte(outf, DVI_FNT1); X putbyte(outf, index); X CurrentPosition += 2; X } else if (index < 65536) { X putbyte(outf, DVI_FNT2); X PutWord(outf, index); X CurrentPosition += 3; X } else if (index < 16777216) { X putbyte(outf, DVI_FNT3); X Put3Byte(outf, index); X CurrentPosition += 4; X } else { X putbyte(outf, DVI_FNT4); X PutLong(outf, index); X CurrentPosition += 5; X } X} X X/* X * The following table describes the length (in bytes) of each of the DVI X * commands that we can simply copy, starting with DVI_SET1 (128). X */ Xchar oplen[128] = { X 0, 0, 0, 0, /* DVI_SET1 .. DVI_SET4 */ X 9, /* DVI_SETRULE */ X 0, 0, 0, 0, /* DVI_PUT1 .. DVI_PUT4 */ X 9, /* DVI_PUTRULE */ X 1, /* DVI_NOP */ X 0, /* DVI_BOP */ X 0, /* DVI_EOP */ X 1, /* DVI_PUSH */ X 1, /* DVI_POP */ X 2, 3, 4, 5, /* DVI_RIGHT1 .. DVI_RIGHT4 */ X 1, /* DVI_W0 */ X 2, 3, 4, 5, /* DVI_W1 .. DVI_W4 */ X 1, /* DVI_X0 */ X 2, 3, 4, 5, /* DVI_X1 .. DVI_X4 */ X 2, 3, 4, 5, /* DVI_DOWN1 .. DVI_DOWN4 */ X 1, /* DVI_Y0 */ X 2, 3, 4, 5, /* DVI_Y1 .. DVI_Y4 */ X 1, /* DVI_Z0 */ X 2, 3, 4, 5, /* DVI_Z1 .. DVI_Z4 */ X 0, /* DVI_FNTNUM0 (171) */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 172 .. 179 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 180 .. 187 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 188 .. 195 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 196 .. 203 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 204 .. 211 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 212 .. 219 */ X 0, 0, 0, 0, 0, 0, 0, 0, /* 220 .. 227 */ X 0, 0, 0, 0, 0, 0, 0, /* 228 .. 234 */ X 0, 0, 0, 0, /* DVI_FNT1 .. DVI_FNT4 */ X 0, 0, 0, 0, /* DVI_XXX1 .. DVI_XXX4 */ X 0, 0, 0, 0, /* DVI_FNTDEF1 .. DVI_FNTDEF4 */ X 0, /* DVI_PRE */ X 0, /* DVI_POST */ X 0, /* DVI_POSTPOST */ X 0, 0, 0, 0, 0, 0, /* 250 .. 255 */ X}; X X/* X * Here we scan the input DVI file and record pointers to the pages. X */ XScanDVIFile() X{ X UseThisPage = 0; X X StartOfPage[InputPageNumber] = ftell(inf); X while (HandlePage()) { /* scan DVI file */ X StartOfPage[++InputPageNumber] = ftell(inf); X } X} X X/* X * Here we read the input DVI file and write relevant pages to the X * output DVI file. We also keep track of font changes, handle font X * definitions, and perform some other housekeeping. X */ XHandleDVIFile() X{ X int CurrentPage, ActualPage, MaxPage; X X UseThisPage = 1; X X MaxPage = InputPageNumber + (4-InputPageNumber%4)%4; X X if (!Signature) X Signature = MaxPage; X for (CurrentPage = 0; CurrentPage < MaxPage; CurrentPage++) { X ActualPage = CurrentPage - CurrentPage%Signature; X switch (CurrentPage%4) { X case 0: X case 3: X ActualPage += Signature-1-(CurrentPage%Signature)/2; X break; X case 1: X case 2: X ActualPage += (CurrentPage%Signature)/2; X break; X } X if (ActualPage < InputPageNumber) { X if (fseek(inf, StartOfPage[ActualPage], 0) == -1) X error(1, -1, X "can't seek page %d", ActualPage+1); X HandlePage(); X } else X PutEmptyPage(); X } X if (fseek(inf, StartOfPage[InputPageNumber]+1, 0) == -1) X error(1, -1, "can't seek last page"); X} X Xint XHandlePage() X{ X register int c, l; X register i32 p; X register int CurrentFontOK = 0; X int doingpage = 0; X X /* Only way out is via "return" statement */ X for (;;) { X c = getc(inf); /* getc() returns unsigned values */ X if (DVI_IsChar(c)) { X /* X * Copy chars, note font usage, but ignore if X * page is not interesting. X */ X if (!UseThisPage) X continue; X if (!CurrentFontOK) { X ReallyUseFont(); X CurrentFontOK++; X } X putbyte(outf, c); X CurrentPosition++; X continue; X } X if (DVI_IsFont(c)) { /* note font change */ X CurrentFontIndex = c - DVI_FNTNUM0; X CurrentFontOK = 0; X continue; X } X if (c == EOF) X GripeUnexpectedDVIEOF(); X if ((l = (oplen - 128)[c]) != 0) { /* simple copy */ X if (!UseThisPage) { X while (--l > 0) X (void) getc(inf); X continue; X } X CurrentPosition += l; X putbyte(outf, c); X while (--l > 0) { X c = getc(inf); X putbyte(outf, c); X } X if (ferror(outf)) X error(1, -1, writeerr); X continue; X } X if ((l = DVI_OpLen(c)) != 0) { X /* X * Handle other generics. X * N.B.: there should only be unsigned parameters X * here (save SGN4), for commands with negative X * parameters have been taken care of above. X */ X switch (l) { X X case DPL_UNS1: X p = getc(inf); X break; X X case DPL_UNS2: X fGetWord(inf, p); X break; X X case DPL_UNS3: X fGet3Byte(inf, p); X break; X X case DPL_SGN4: X fGetLong(inf, p); X break; X X default: X panic("HandleDVIFile l=%d", l); X } X X /* X * Now that we have the parameter, perform the X * command. X */ X switch (DVI_DT(c)) { X X case DT_SET: X case DT_PUT: X if (!UseThisPage) X continue; X if (!CurrentFontOK) { X ReallyUseFont(); X CurrentFontOK++; X } X putbyte(outf, c); X switch (l) { X X case DPL_UNS1: X putbyte(outf, p); X CurrentPosition += 2; X continue; X X case DPL_UNS2: X PutWord(outf, p); X CurrentPosition += 3; X continue; X X case DPL_UNS3: X Put3Byte(outf, p); X CurrentPosition += 4; X continue; X X case DPL_SGN4: X PutLong(outf, p); X CurrentPosition += 5; X continue; X } X X case DT_FNT: X CurrentFontIndex = p; X CurrentFontOK = 0; X continue; X X case DT_XXX: X HandleSpecial(c, l, p); X continue; X X case DT_FNTDEF: X HandleFontDef(p); X continue; X X default: X panic("HandleDVIFile DVI_DT(%d)=%d", X c, DVI_DT(c)); X } X continue; X } X X switch (c) { /* handle the few remaining cases */ X X case DVI_BOP: X if (doingpage) X GripeUnexpectedOp("BOP (during page)"); X BeginPage(); X doingpage = 1; X break; X X case DVI_EOP: X if (!doingpage) X GripeUnexpectedOp("EOP (outside page)"); X EndPage(); X doingpage = 0; X return(1); X X case DVI_PRE: X GripeUnexpectedOp("PRE"); X /* NOTREACHED */ X X case DVI_POST: X if (doingpage) X GripeUnexpectedOp("POST (inside page)"); X return(0); X X case DVI_POSTPOST: X GripeUnexpectedOp("POSTPOST"); X /* NOTREACHED */ X X default: X GripeUndefinedOp(c); X /* NOTREACHED */ X } X } X} X X/* write an empty page to fill out space */ XPutEmptyPage() X{ X int i; X X putbyte(outf, DVI_BOP); X PutLong(outf, -1L); X for (i = 1; i < 10; i++) /* set all sub counts to 0 */ X PutLong(outf, 0L); X PutLong(outf, StartOfLastPage); X putbyte(outf, DVI_EOP); X if (!SFlag) { /* write nice page usage messages */ X char *msg = "[*]"; X message(1, msg, strlen(msg)); X } X if (ferror(outf)) X error(1, -1, writeerr); X X StartOfLastPage = CurrentPosition; X CurrentPosition += 46; /* we just wrote this much */ X NumberOfOutputPages++; X} END_OF_dvibook.c if test 19274 -ne `wc -c <dvibook.c`; then echo shar: \"dvibook.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f dvibook.man -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"dvibook.man\" else echo shar: Extracting \"dvibook.man\" \(1308 characters\) sed "s/^X//" >dvibook.man <<'END_OF_dvibook.man' X.TH DVIBOOK 1 X.SH NAME Xdvibook \- rearrange pages in DVI file into signatures X.SH SYNOPSIS X.B dvibook X[ X.B \-q X] [ X.B \-s\fI<num> X] [ X.B \-i X.I infile X] [ X.B \-o X.I outfile X] X[ X.I infile X[ X.I outfile X] ] X.SH DESCRIPTION X.I Dvibook Xrearranges pages from a DVI file produced by TeX into ``signatures'' for Xprinting books or booklets, creating a new DVI file Xusable by any of the TeX conversion programs. X.PP XThe X.I \-s Xoption selects the size of signature which will be used. The signature size is Xthe number of sides which will be folded and bound together; the number given Xshould be a multiple of four. The default is to use one signature for the Xwhole file. Extra blank sides will be added if the file does not contain a Xmultiple of four pages. X.PP XDvibook normally prints the page numbers of the pages rearranged; the X.I \-q Xoption suppresses this. X.SH AUTHOR XAngus Duggan, from dviselect(1), by XChris Torek, University of Maryland X.SH "SEE ALSO" Xdviconcat(1), dviselect(1), latex(1), tex(1) X.br X.I "MC-TeX User's Guide" X.br X.I "The TeXbook" X.I Dvibook Xdoes not adjust the parameters in the postamble; however, since these Xvalues are normally used only to size certain structures in the output Xconversion programs, and the parameters never need to be adjusted upward, Xthis has not proven to be a problem. END_OF_dvibook.man if test 1308 -ne `wc -c <dvibook.man`; then echo shar: \"dvibook.man\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 1 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 a. -- Angus Duggan, Department of Computer Science, | I'm pink, therefore I'm Spam. University of Edinburgh, JCMB, | JANET: ajcd@uk.ac.ed.lfcs The King's Buildings, Mayfield Road, | VOICE: (UK) 031 650 5126 Edinburgh, EH9 3JZ, Scotland. | OR: ajcd%lfcs.ed.ac.uk@nsfnet-relay.ac.uk