home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-09-11 | 59.6 KB | 1,507 lines |
- Subject: v07i022: TeX DVI driver for TTY's, etc.
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: seismo!enea!ttds!zap (Svante Lindahl)
- Mod.sources: Volume 7, Issue 22
- Archive-name: texdvi2tty
-
- [ I have only verified that this unpacks correctly. Non-4.[23] sites
- note: this script uses 'echo -n' --r$ ]
-
- : This shar archive as submitted to mod.sources contains the
- : following files: README
- : dvitty.1
- : Makefile
- : dvitty.p
- : sys.h
- : sys.c
- :
- : This is a shar archive. Extract with sh, not csh.
- : This archive ends with exit, so do not worry about trailing junk.
- echo 'Extracting README'
- sed 's/^X//' > README << '+ END-OF-FILE README'
- Xdvitty is intended for previewing dvi-files on text-only devices
- X(terminals and lineprinters). The output is not very pretty many
- Xtimes, but it still saves quite a lot of work, especially if you
- Xhave a little ways to walk to a laserprinter, for example.
- X
- XThe program was originally written in Hedrick-Pascal, running on
- XTOPS-20, and was later ported to UNIX (BSD, Berkeley-pascal).
- X
- XIt is not very smart in all situations, but still serves it pur-
- Xpose fairly well.
- X
- XFor information on how to use see the man-page.
- X
- XBefore compiling and installing inspect the "compile-time cust-
- Xomization constants" and change them to suit your site.
- XThese constants configure default pager and a little more.
- X
- XPlease report complaints, suggestions, bugs and/or fixes to:
- X
- XSvante Lindahl, NADA, KTH Numerical Analysis & Computer Science
- XUUCP: {seismo,mcvax}!enea!ttds!zap Royal Institute of Technology, Sweden
- XARPA: enea!ttds!zap@seismo.CSS.GOV EAN: zap@cs.kth.sunet
- X
- XThe TOPS-20 version of the program can also be obtained from the above
- Xaddress.
- + END-OF-FILE README
- chmod 'u=rw,g=rw,o=r' 'README'
- echo ' -rw-rw-r-- 1 zap 1050 Aug 15 22:11 README (as sent)'
- echo -n ' '
- /bin/ls -l README
- echo 'Extracting dvitty.1'
- sed 's/^X//' > dvitty.1 << '+ END-OF-FILE dvitty.1'
- X.TH DVITTY Local "7 June 1986"
- X.SH NAME
- Xdvitty \- preview a dvi\-file on an ordinary ascii terminal
- X.SH SYNOPSIS
- X.B dvitty
- X[ options ] dvi\-file
- X.SH DESCRIPTION
- X.I dvitty
- Xconverts a TeX DVI\-file to a format that is apprporiate for terminals
- Xand lineprinters. The program is intended to be used for
- Xpreliminary proofreading of TeX:ed documents.
- XBy default the output is directed to the terminal,
- Xpossibly through a pager (depending on how the program was installed),
- Xbut it can be directed to a file or a pipe.
- X.PP
- XThe output leaves much to be desired, but is still
- Xusefull if you want to avoid walking to the
- Xlaserprinter (or whatever) for each iteration of your
- Xdocument.
- X.br
- XSince
- X.I dvitty
- Xproduces output for terminals and lineprinters the
- Xrepresentation of documents is naturally quite primitive.
- XFontchanges are totally ignored, which implies that
- Xspecial symbols, such as mathematical symbols, get mapped into the
- Xcharacters at the corresponding positions in the "standard" fonts.
- X.PP
- XIf the width of the output text requires more columns than fits
- Xin one line (c.f. the \-w option) it is broken into several lines by
- X.I dvitty
- Xalthough they will be printed as one line on regular TeX output
- Xdevices (e.g.laserprinters). To show that a broken line is really
- Xjust one logical line an asterisk (``*'') in the last position
- Xmeans that the logical line is continued on the next physical
- Xline output by
- X.I dvitty.
- XSuch a continuation line is started with a a space and an asterisk
- Xin the first two columns.
- X.PP
- XOptions may be specified in the environment variable DVITTY.
- XAny option on the commandline, conflicting with one in the
- Xenvironment, will override the one from the environment.
- X.PP
- X.B Options:
- X.PP
- X.TP
- X.B \-o file
- XWrite output to file ``file''.
- X.TP
- X.B \-p list
- XPrint the pages chosen by list.
- XNumbers refer to TeX\-page numbers (known as \\count0).
- XAn example of format for list is ``1,3:6,8''
- Xto choose pages 1, 3 through 6 and 8.
- XNegative numbers can be used exactly as in TeX,
- Xe g \-1 comes before \-4 as in ``\-p-1:-4,17''.
- X.TP
- X.B \-P list
- XLike \-p except that page numbers refer to
- Xthe sequential ordering of the pages in the dvi\-file.
- XNegative numbers don't make a lot of sense here...
- X.TP
- X.B \-w n
- XSpecify terminal width
- X.I n.
- XLegal range 16\-132.
- XDefault is 80. If your terminal has the
- Xability to display in 132 columns it might
- Xbe a good idea to use \-w132 and toggle the
- Xterminal into this mode as output will
- Xprobably look somewhat better.
- X.TP
- X.B \-q
- XDon't pipe the output through a pager.
- XThis may be the default on some systems
- X(depending on the whims of the SA installing the program).
- X.TP
- X.B \-f
- XPipe through a pager, $PAGER if defined, or whatever your SA compiled
- Xin (often ``more''). This may be the default, but it is still okay
- Xto redirect output with ``>'', the pager will not be used if output
- Xis not going to a terminal.
- X.TP
- X.B \-Fprog
- XUse ``prog'' as program to pipe output into. Can be used to choose an
- Xalternate pager (e g ``-Fless'').
- X.TP
- X.B \-l
- XMark pagebreaks with the two-character sequence ``^L''. The defualt is
- Xto mark them with a formfeed character.
- X.TP
- X.B \-u
- XDon't make any attempts to find special Scandinavian characters.
- XIf such characters are in the text they will map to ``a'' and ``o''.
- XThis is probably the default outside of Scandinavia. (The SA made
- Xthe decision when the program was installed.)
- X.TP
- X.B \-s
- XTry to find the special Scandinavian characters that on most (?)
- Xterminals in Scandinavia are mapped to ``{|}[\\]''.
- XThis can be the default, and output from files not containing these
- Xspecial characters will be identical regardless of this option.
- X.SH FILES
- X/usr/ucb/more \ \ \ \
- Xprobably the default pager.
- X.SH ENVIRONMENT
- XPAGER \ \ \ \ \ \ \ \ \ \ \ \
- Xthe pager to use.
- X.br
- XDVITTY \ \ \ \ \ \ \ \ \ \ \
- Xcan be set to hold commandline options.
- X.SH "SEE ALSO"
- XTeX, dvi2ps
- X.SH AUTHOR
- XSvante Lindahl, Royal Institute of Technology, Stockholm
- X.br
- X{seismo, mcvax}!enea!ttds!zap
- X.SH BUGS
- XBlanks between words get lost quite easy. This is less
- Xlikely if you are using a wider output than the default 80.
- X.PP
- XOnly one file may be specified on the commandline.
- + END-OF-FILE dvitty.1
- chmod 'u=rw,g=rw,o=r' 'dvitty.1'
- echo ' -rw-rw-r-- 1 zap 4127 Aug 15 20:02 dvitty.1 (as sent)'
- echo -n ' '
- /bin/ls -l dvitty.1
- echo 'Extracting Makefile'
- sed 's/^X//' > Makefile << '+ END-OF-FILE Makefile'
- Xall: dvitty
- X
- Xdvitty: sys.o dvitty.o
- X pc -O -w -o dvitty dvitty.o sys.o
- X
- Xdvitty.o: dvitty.p
- X pc -c -w -O dvitty.p
- X
- Xsys.o: sys.c
- X cc -c -O sys.c
- + END-OF-FILE Makefile
- chmod 'u=rw,g=r,o=r' 'Makefile'
- echo ' -rw-r--r-- 1 zap 143 Aug 8 00:32 Makefile (as sent)'
- echo -n ' '
- /bin/ls -l Makefile
- echo 'Extracting dvitty.p'
- sed 's/^X//' > dvitty.p << '+ END-OF-FILE dvitty.p'
- X(******************************************************************************
- X * bogart:/usr/alla/zap/dvitty/dvitty.p 1986-08-15 20:24:31,
- X * Version to be sent to mod.sources ready.
- X * New option since last version:
- X * -Fprog Pipe output to prog. Can be used to get a different
- X * pager than the default.
- X * bogart:/usr/alla/zap/dvitty/dvitty.p 1986-01-13 21:49:31,
- X * Environment variable DVITTY is read and options can be set from it.
- X * These are the currently implemented options:
- X * -ofile Write output to file, else write to stdout,
- X * possibly piped through a pager if stdout is a tty.
- X * -plist Print pages whos TeX-page-number are in list.
- X * List is on the form 1,3:6,8 to choose pages
- X * 1,3-6 and 8. TeX-nrs can be negative: -p-1:-4,4
- X * -Plist Print pages whos sequential number are in list.
- X * -wn Print the lines with width n characters, default is
- X * 80. Wider lines gives better results.
- X * -q Don't try to pipe to a pager.
- X * -f Try to pipe to a pager if output is a tty.
- X * Default of -q and -f is a compile time option, a constant.
- X * -l Write '^L' instead of formfeed between pages.
- X * -u Don't try to find Scandinavian characters (they will
- X * print as a:s and o:s if this option is choosen).
- X * -s Scandinavian characters printed as }{|][\.
- X * Default of -s and -u is a compile time option, a constant.
- X * bogart:/usr/alla/zap/dvitty/dvitty.p 1986-01-10 18:51:03,
- X * Argument parsing, and random access functions (external, in C)
- X * and other OS-dependent stuff (in C). Removed private 'pager' &
- X * tries to pipe through PAGER (environment var) or, if PAGER not
- X * defined, /usr/ucb/more. Some changes for efficency.
- X * bogart:/usr/alla/svante/dvitty/dvitty.p 1985-07-15 20:51:00,
- X * The code for processing dvi-files running on UNIX (UCB-Pascal)
- X * but no argument parsing.
- X * VERA::SS:<SVANTE-LINDAHL.WORK>DVITTY.PAS.140, 30-Mar-85 05:43:56,
- X * Edit: Svante Lindahl
- X * VERA::SS:<SVANTE-LINDAHL.WORK>DVITTY.PAS.136, 15-Jan-85 13:52:59,
- X * Edit: Svante Lindahl, final Twenex version !!!??
- X * VERA::SS:<SVANTE-LINDAHL.WORK>DVITTY.PAS.121, 14-Jan-85 03:10:22,
- X * Edit: Svante Lindahl, cleaned up and fixed a lot of little things
- X * VERA::SS:<SVANTE-LINDAHL.WORK>DVITTY.PAS.25, 15-Dec-84 05:29:56,
- X * Edit: Svante Lindahl, COMND-interface, including command line scanning
- X * VERA::SS:<SVANTE-LINDAHL.WORK>DVITTY.PAS.23, 10-Dec-84 21:24:41,
- X * Edit: Svante Lindahl, added command line scanning with Rscan-JSYS
- X * VERA::<SVANTE-LINDAHL.DVITTY>DVITTY.PAS.48, 8-Oct-84 13:26:30,
- X * Edit: Svante Lindahl, fixed switch-parsing, destroyed by earlier patches
- X * VERA::<SVANTE-LINDAHL.DVITTY>DVITTY.PAS.45, 29-Sep-84 18:29:53,
- X * Edit: Svante Lindahl
- X *
- X * dvitty - get an ascii representation of a dvi-file, suitable for ttys
- X *
- X * This program, and any documentation for it, is copyrighted by Svante
- X * Lindahl. It may be copied for non-commercial use only, provided that
- X * any and all copyright notices are preserved.
- X *
- X * Please report any bugs and/or fixes to:
- X *
- X * UUCP: {seismo,mcvax,cernvax,diku,ukc,unido}!enea!ttds!zap
- X * ARPA: enea!ttds!zap@seismo.CSS.GOV
- X * or Svante_Lindahl_NADA%QZCOM.MAILNET@MIT-MULTICS.ARPA
- X * EAN: zap@cs.kth.sunet
- X *)
- X
- Xprogram dvitty(input, output);
- X
- Xconst Copyright = 'dvitty.p Copyright (C) 1984, 1985, 1986 Svante Lindahl.';
- X
- X
- X {-----------------------------------------------------------------------}
- X { The following two constants may be toggled before compilation to }
- X { customize the default behaviour of the program for your site. }
- X { Whichever their settings are, the defaults can be overridden at }
- X { runtime. }
- X {-----------------------------------------------------------------------}
- X
- X defscand = true; { default is Scandinavian, toggle this if you }
- X { don't have terminals with Scand. nat. chars }
- X defpage = true; { default: try to pipe through a pager (like }
- X { more) if stdout is tty and no -o switch }
- X pathlen = 40; { length of string for path to pager program }
- X defpath = '/usr/ucb/more '; { pathlen chars }
- X
- X {------------------ end of customization constants ---------------------}
- X
- X versionid = 2; { version number of dvifiles that pgm handles }
- X stackmax = 100; { allows 100 dvi-pushes }
- X verticalepsilon = 450000; { crlf when increasing v more than this }
- X
- X rightmargin = 152; { nr of columns allowed to the right of h=0 }
- X leftmargin = -50; { give some room for negative h-coordinate }
- X
- X stringlength = 100; { size of char-arrays for strings }
- X
- X advance = true; { if advancing h when outputing a rule }
- X stay = false; { if not advancing h when outputing a rule }
- X
- X absolute = 0;
- X relative = 1;
- X
- X chffd = 12; { formfeed }
- X chspc = 32; { space }
- X chdel = 127; { delete }
- X
- X { some dvi op-codes (digit at end tells dvi-version-#) }
- X nop2 = 138; { no-op }
- X bop2 = 139; { beginning of page }
- X eop2 = 140; { end of page }
- X post2 = 248; { post-amble }
- X pre2 = 247; { pre-amble }
- X postpost2 = 249; { post-post-amble }
- X lastchar = 127; { highest char-code }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xtype ubyte = 0..255; { dvi-files consists of eight-bit-bytes }
- X sbyte = -128..127; { UCB-pascal reads 16 bits if unsigned byte }
- X
- X string = packed array [1..stringlength] of char;
- X pathtype = packed array [1..pathlen] of char;
- X charset = set of char;
- X
- X stackitem = record
- X hh, vv, ww, xx, yy, zz : integer;
- X end;
- X stacktype = record { stack for dvi-pushes }
- X items : array [1..stackmax] of stackitem;
- X top : 0..stackmax;
- X end; { stacktype }
- X
- X lineptr = ^linetype;
- X linetype = record { the lines of text to be output to outfile }
- X vv : integer; { vertical position of the line }
- X charactercount : integer; { pos of last char on line }
- X prev : lineptr; { preceding line }
- X next : lineptr; { succeding line }
- X text : packed array [leftmargin..rightmargin] of char;
- X end; { linetype }
- X
- X printlistptr = ^printlisttype;
- X printlisttype = record { list of pages selected for output }
- X pag : integer; { the nr of the page }
- X all : boolean; { pages in intervall selected }
- X prv : printlistptr; { previous item in list }
- X nxt : printlistptr; { next item in list }
- X adr : integer; { nr of byte in file where bop is }
- X end; { printlisttype }
- X
- X useagecodetype= (wrnge, { width switch arg out of range }
- X ign, { ignore cause, print'Usage:..' }
- X nan, { not a number where one expected }
- X gae, { garbage at end }
- X bdlst, { bad page-numberlist }
- X onef, { only one dvifile allowed }
- X bdopt, { bad option }
- X lngpth, { pathname too long (for -F) }
- X noarg); { argument expected }
- X
- X errorcodetype = (illop, { illegal op-code }
- X stkof, { stack over-flow }
- X stkuf, { stack under-flow }
- X stkrq, { stack requirement }
- X badid, { id is not right }
- X bdsgn, { signature is wrong }
- X fwsgn, { too few signatures }
- X nopre, { no pre-amble where expected }
- X nobop, { no bop-command where expected }
- X nopp, { no postpost where expected }
- X bdpre, { unexpected preamble occured }
- X bdbop, { unexpected bop-command occured }
- X bdpst, { unexpected post-command occured }
- X bdpp, { unexpected postpost }
- X nopst, { no post-amble where expected }
- X illch, { character code out of range }
- X filop, { cannot access file }
- X filcr); { cannot creat file }
- X
- X DVIfiletype = file of sbyte;
- X
- X{-----------------------------------------------------------------------------}
- X
- Xvar opcode : ubyte; { dvi-opcodes }
- X foo : integer; { utility variable, "register" }
- X
- X h, v : integer; { coordinates, horizontal and vertical }
- X w, x, y, z : integer; { horizontal and vertical amounts }
- X
- X outputtofile : boolean; { tells if output goes to file or stdout }
- X pager : boolean; { tells if output is piped to a pager }
- X pageswitchon : boolean; { true if user-set pages to print }
- X sequenceon : boolean; { false if pagesw-nrs refers to TeX-nrs }
- X scascii : boolean; { if true make Scand. nat. chars right }
- X noffd : boolean; { if true output ^L instead of formfeed }
- X ttywidth : integer; { max nr of chars per printed line }
- X path : pathtype; { name of the pager to run }
- X pathpgm : boolean; { use 'defpath' if this is true }
- X
- X maxpagewidth : integer; { width of widest page in file }
- X charwidth : integer; { aprox width of charachter }
- X
- X currentpage : printlistptr; { current page to print }
- X firstpage : printlistptr; { first page selected }
- X lastpage : printlistptr; { last page selected }
- X currentline : lineptr; { pointer to current line on current page }
- X firstline : lineptr; { pointer to first line on current page }
- X lastline : lineptr; { pointer to last line on current page }
- X firstcolumn : integer; { 1st column with something to print }
- X
- X stack : stacktype;
- X
- X DVIfile : DVIfiletype;
- X ERRfile : text;
- X DVIfilename : string;
- X OUTfilename : string;
- X
- X{-----------------------------------------------------------------------------}
- X
- X#include "sys.h" { headers for external C-routines }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure errorexit(errorcode : errorcodetype);
- X begin
- X write(ERRfile,'dvitty: ');
- X case errorcode of
- X illop : writeln(ERRfile,'Illegal op-code found: ',opcode:0);
- X stkof : writeln(ERRfile,'Stack overflow.');
- X stkuf : writeln(ERRfile,'Stack underflow.');
- X stkrq : writeln(ERRfile,'Too much stack required : ',foo:0);
- X badid : writeln(ERRfile,'Id-byte is not correct: ',opcode:0);
- X bdsgn : writeln(ERRfile,'Bad signature: ',foo:0,' (not 223).');
- X fwsgn : writeln(ERRfile,foo:0,' signature bytes (min. 4).');
- X nopre : writeln(ERRfile,'Missing preamble.');
- X nobop : writeln(ERRfile,'Missing beginning-of-page command.');
- X nopp : writeln(ERRfile,'Missing post-post command.');
- X bdpre : writeln(ERRfile,'Preamble occured inside a page.');
- X bdbop : writeln(ERRfile,'BOP-command occured inside a page.');
- X bdpst : writeln(ERRfile,'Postamble occured before end-of-page.');
- X bdpp : writeln(ERRfile,'Postpost occured before post-command.');
- X nopst : writeln(ERRfile,'Missing postamble.');
- X illch : writeln(ERRfile,'Character code out of range, 0..127');
- X filop : writeln(ERRfile,'Cannot open dvifile');
- X filcr : writeln(ERRfile,'Cannot create outfile');
- X end;
- X if outputtofile then delete(output);
- X exit(-1);
- X end; { errorexit }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure usage(uerr : useagecodetype);
- X begin
- X if uerr<>ign then begin
- X write(ERRfile,'dvitty: ');
- X case uerr of
- X ign : writeln(ERRfile, Copyright);
- X wrnge : writeln(ERRfile,'width arg out of range:16-132');
- X nan : writeln(ERRfile,'numeric argument expected');
- X gae : writeln(ERRfile,'garbage at end of argument');
- X bdlst : writeln(ERRfile,'mal-formed list of pagenumbers');
- X onef : writeln(ERRfile,'only one infile argument allowed');
- X noarg : writeln(ERRfile,'option argument expected');
- X lngpth : writeln(ERRfile,'path too long for -F');
- X bdopt : writeln(ERRfile,'bad option');
- X end;
- X end;
- X writeln(ERRfile,'Usage: dvitty [ options ] dvifile[.dvi]');
- X writeln(ERRfile,'Options are:');
- X writeln(ERRfile,
- X ' -ofile Write output to file, else write to stdout.');
- X writeln(ERRfile,
- X ' -plist Print pages whos TeX-page-number are in list.');
- X writeln(ERRfile,
- X ' -Plist Print pages whos sequential number are in list.');
- X writeln(ERRfile,
- X ' -wn Print the lines with width n characters, default 80.');
- X write(ERRfile,' -f Try to pipe to a pager if output is a tty');
- X if defpage then writeln(ERRfile,' (default).')
- X else writeln(ERRfile,'.');
- X write(ERRfile,' -q Don''t try to pipe to a pager');
- X if defpage then writeln(ERRfile,'.')
- X else writeln(ERRfile,' (default).');
- X writeln(ERRfile,
- X ' -l Write ''^L'' instead of formfeed between pages.');
- X write(ERRfile,
- X ' -u National Swedish characters printed as aaoAAO');
- X if defscand then writeln(ERRfile,'.')
- X else writeln(ERRfile,' (default).');
- X write(ERRfile,
- X ' -s National Swedish characters printed as }{|][\');
- X if defscand then writeln(ERRfile,' (default).')
- X else writeln(ERRfile,'.');
- X exit(1);
- X end; { usage }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure getname(var str : string);
- X var i : integer;
- X begin
- X i:=stringlength;
- X while (i>1) and (str[i]=' ') do i:=i-1;
- X if (i=1) and (str[1]=' ') then usage(ign);
- X if not ((i>=5) and (str[i]='i') and (str[i-1]='v')
- X and (str[i-2]='d') and (str[i-3]='.')) then begin
- X str[i+1]:='.';
- X str[i+2]:='d';
- X str[i+3]:='v';
- X str[i+4]:='i';
- X end;
- X DVIfilename:=str;
- X end; { getname }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction getinteger(var j: integer; var str : string; def : integer) : integer;
- X var cum : integer;
- X sgn : boolean;
- X begin
- X if not (str[j] in ['0'..'9','-']) then getinteger:=def
- X else begin
- X cum:=0;
- X sgn:=false;
- X if str[j]='-' then begin
- X sgn:=true;
- X j:=j+1;
- X end;
- X if not (str[j] in ['0'..'9']) then getinteger:=def
- X else begin
- X while str[j] in ['0'..'9'] do begin
- X cum:=cum*10+ord(str[j])-ord('0');
- X j:=j+1;
- X end;
- X if sgn then getinteger:=-cum else getinteger:=cum;
- X end;
- X end;
- X end; { getinteger }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure getpages(j : integer; var str : string);
- X var i : integer;
- X
- X procedure plcnxt(pagnr : integer); { place page-nr next in list }
- X begin
- X currentpage:=lastpage;
- X currentpage^.pag:=pagnr;
- X new(lastpage);
- X lastpage^.all:=false;
- X lastpage^.nxt:=nil;
- X lastpage^.pag:=0;
- X currentpage^.nxt:=lastpage;
- X end; { plcnxt }
- X
- X begin { getpages }
- X pageswitchon:=true;
- X new(firstpage);
- X firstpage^.all:=false;
- X firstpage^.nxt:=nil;
- X firstpage^.pag:=0;
- X lastpage:=firstpage;
- X currentpage:=firstpage;
- X if not (str[j] in ['1'..'9','-']) then usage(nan);
- X foo:=getinteger(j,str,0);
- X while foo<>0 do begin
- X plcnxt(foo);
- X if str[j]=',' then begin
- X j:=j+1;
- X if not (str[j] in ['1'..'9','-']) then usage(nan);
- X end else if str[j]=':' then begin
- X j:=j+1;
- X if not (str[j] in ['1'..'9','-']) then usage(nan);
- X foo:=getinteger(j,str,0);
- X if currentpage^.pag<0 then begin
- X if (foo>0) then begin
- X currentpage^.all:=true;
- X plcnxt(foo);
- X end else if foo<currentpage^.pag then
- X for i:=(currentpage^.pag-1) downto foo do plcnxt(i)
- X else usage(bdlst);
- X end else begin
- X if foo<currentpage^.pag then usage(bdlst);
- X for i:=(currentpage^.pag+1) to foo do plcnxt(i);
- X end;
- X if str[j]=',' then begin
- X j:=j+1;
- X if not (str[j] in ['1'..'9','-']) then usage(nan);
- X end;
- X end;
- X foo:=getinteger(j, str, 0);
- X end;
- X if str[j]<>' ' then usage(gae);
- X currentpage:=firstpage;
- X end; { getpages }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure setoption(optch : char; var optset, optwarg : charset;
- X var str : string; var i : integer; j : integer);
- X var k : integer;
- X begin
- X while optch in optset do begin
- X case optch of
- X 'q' : pager:=false;
- X 'f' : pager:=true;
- X 'l' : noffd:=true;
- X 's' : scascii:=true;
- X 'u' : scascii:=false;
- X 'p' : begin
- X optset:=optset-['P']; { can't have both -P & -p }
- X getpages(j, str);
- X end;
- X 'P' : begin
- X sequenceon:=true;
- X optset:=optset-['p']; { can't have both -P & -p }
- X getpages(j, str);
- X end;
- X 'w' : begin
- X if not (str[j] in ['0'..'9','-']) then usage(nan);
- X ttywidth:=getinteger(j, str, 80);
- X if str[j]<>' ' then usage(gae);
- X if (ttywidth<16) or (ttywidth>132) then usage(wrnge);
- X end;
- X 'o' : begin
- X for k:=1 to stringlength-j+1 do
- X OUTfilename[k]:=str[j+k-1];
- X for k:=stringlength-j+2 to stringlength do
- X OUTfilename[k]:=' ';
- X outputtofile:=true;
- X j:=stringlength;
- X end;
- X 'F' : begin
- X for k:=1 to pathlen do
- X path[k]:=str[k+j-1];
- X if path[pathlen]<>' ' then usage(lngpth);
- X j:=stringlength;
- X pathpgm:=false;
- X end;
- X end;
- X optch:=str[j];
- X j:=j+1;
- X if optch in optwarg then if str[j]=' ' then begin
- X i:=i+1;
- X if i>=argc then usage(noarg);
- X argv(i, str);
- X j:=1;
- X end;
- X end;
- X end; { setoption }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure getargs;
- X var i, j : integer;
- X str : string;
- X DVIfilenamefound : boolean;
- X optset, optwarg : charset;
- X optch : char;
- X begin
- X if argc<=1 then usage(ign);
- X pageswitchon:=false; { default: all pages }
- X sequenceon:=false; { default: selected pages are TeX-numbered }
- X outputtofile:=false; { default: write to stdout }
- X noffd:=false; { default: print formfeed between pages }
- X scascii:=defscand; { default: see compile time adjustable const }
- X pager:=defpage; { default: see compile time adjustable const }
- X path:=defpath; { default: use the default path to the pager }
- X pathpgm:=true; { default: - " - }
- X ttywidth:=80; { default }
- X DVIfilenamefound:=false;
- X optset:=['w','p','P','o','u','s','q','l','f','F']; { legal options }
- X optwarg:=['w','p','P','o','F']; { options with args }
- X i:=0;
- X while envargs(optch, str) do { get options from environ var DVITTY }
- X setoption(optch, optset, optwarg, str, i, 1);
- X i:=1;
- X while i<argc do begin
- X argv(i, str);
- X optch:=str[2]; { cache this one }
- X if str[1]<>'-' then begin
- X if DVIfilenamefound then usage(onef);
- X getname(str);
- X DVIfilenamefound:=true;
- X end else if optch in optset then begin
- X j:=3;
- X if (optch in optwarg) and (str[j]=' ') then begin
- X i:=i+1;
- X if i>=argc then usage(noarg);
- X argv(i, str);
- X j:=1;
- X end;
- X setoption(optch, optset, optwarg, str, i, j);
- X end else usage(bdopt);
- X i:=i+1;
- X end;
- X if not DVIfilenamefound then usage(ign)
- X end; { getargs }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction getbyte : integer; { get next byte from dvi-file }
- X var b : sbyte;
- X begin
- X read(DVIfile, b);
- X if b<0 then getbyte:=b+256 else getbyte:=b
- X end; { getbyte }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction get2 : integer; { returns the next two bytes, unsigned }
- X begin
- X foo:=getbyte;
- X get2:=foo*256+getbyte
- X end; { get2 }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction get3 : integer; { returns the next three bytes, unsigned }
- X begin
- X foo:=getbyte;
- X foo:=foo*256+getbyte;
- X get3:=foo*256+getbyte
- X end; { get3 }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction signedbyte : integer; { returns next byte fr dvi-file, signed }
- X var b : sbyte;
- X begin
- X read(DVIfile, b);
- X signedbyte:=b;
- X end; { signedbyte }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction signed2 : integer; { returns the next two bytes, signed }
- X begin
- X read(DVIfile, foo);
- X signed2:=foo*256+getbyte
- X end; { signed2 }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction signed3 : integer; { returns the next three bytes, signed }
- X begin
- X read(DVIfile, foo);
- X foo:=foo*256+getbyte;
- X signed3:=foo*256+getbyte
- X end; { signed3 }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction signed4 : integer; { returns the next four bytes, signed }
- X begin
- X read(DVIfile, foo);
- X foo:=foo*256+getbyte;
- X foo:=foo*256+getbyte;
- X signed4:=foo*256+getbyte
- X end; { signed4 }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction imin(a, b : integer) : integer; { returns the least of two int:s }
- X begin
- X if a<b then imin:=a
- X else imin:=b;
- X end;
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction skipnoops(goal : integer) : boolean; { skips by no-op commands }
- X begin { ret true if opcode=goal }
- X repeat
- X opcode:=getbyte;
- X until opcode<>nop2;
- X skipnoops:=(opcode=goal)
- X end; { skipnoops }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction getline : lineptr; { returns an initialized line-object }
- X var i : integer;
- X temp : lineptr;
- X begin
- X new(temp);
- X with temp^ do begin
- X charactercount:=leftmargin-1; prev:=nil; next:=nil;
- X for i:=leftmargin to rightmargin do text[i]:=' '
- X end;
- X getline:=temp
- X end; { getline }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction findline : lineptr; { find line where text should go, }
- X var temp : lineptr; { generate a new line if needed }
- X begin
- X if ((v>currentline^.vv) and (currentline=lastline))
- X or ((v<currentline^.vv) and (currentline=firstline))
- X or (v-lastline^.vv>verticalepsilon) then begin
- X temp:=getline;
- X with temp^ do begin
- X prev:=lastline;
- X vv:=v;
- X lastline^.next:=temp;
- X lastline:=temp
- X end
- X end else begin
- X temp:=lastline;
- X while (temp^.vv>v) and (temp<>firstline) do temp:=temp^.prev;
- X if abs(temp^.vv-v)>verticalepsilon then begin
- X if temp^.next^.vv-v < verticalepsilon then temp:=temp^.next
- X else if (temp=firstline) and (v<temp^.vv) then begin
- X temp:=getline;
- X with temp^ do begin
- X next:=firstline;
- X vv:=v;
- X firstline^.prev:=temp;
- X firstline:=temp
- X end
- X end else begin
- X currentline:=temp;
- X temp:=getline;
- X with temp^ do begin
- X next:=currentline^.next;
- X prev:=currentline;
- X currentline^.next:=temp;
- X currentline:=temp;
- X temp^.next^.prev:=temp;
- X vv:=v
- X end
- X end
- X end
- X end;
- X findline:=temp
- X end; { findline }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure outchar(ch : char); { output ch to appropriate line }
- X var i, j : integer;
- X begin
- X if abs(v-currentline^.vv)>verticalepsilon
- X then currentline:=findline;
- X if (ord(ch) in [11..17, 25..31, 92, 123..126]) then
- X case ord(ch) of
- X 11 : begin outchar('f'); ch:='f' end; { ligature }
- X 12 : begin outchar('f'); ch:='i' end; { ligature }
- X 13 : begin outchar('f'); ch:='l' end; { ligature }
- X 14 : begin outchar('f');
- X outchar('f'); ch:='i' end; { ligature }
- X 15 : begin outchar('f');
- X outchar('f'); ch:='l' end; { ligature }
- X 16 : ch:='i';
- X 17 : ch:='j';
- X 25 : begin outchar('s'); ch:='s' end; { German double s }
- X 26 : begin outchar('a'); ch:='e' end; { Dane/Norw ae }
- X 27 : begin outchar('o'); ch:='e' end; { Dane/Norw oe }
- X 28 : if scascii then ch:='|' { Dane/Norw /o }
- X else ch:='o';
- X 29 : begin outchar('A'); ch:='E' end; { Dane/Norw AE }
- X 30 : begin outchar('O'); ch:='E' end; { Dane/Norw OE }
- X 31 : if scascii then ch:='\' { Dane/Norw /O }
- X else ch:='O';
- X 92 : ch:='"'; { beginnig qoute }
- X 123 : ch:='-';
- X 124 : ch:='_';
- X 125 : ch:='"';
- X 126 : ch:='"';
- X end;
- X j:=round((h/maxpagewidth)*(ttywidth-1)+1.0);
- X if j>rightmargin then j:=rightmargin
- X else if j<leftmargin then j:=leftmargin;
- X with currentline^ do begin
- X foo:=leftmargin-1;
- X {-------------------------------------------------------------}
- X { The following is very specialized code, it handles national }
- X { Swedish characters. They are respectively: a and o with two }
- X { dots ("a & "o) and a with a circle (Oa). In Swedish "ASCII" }
- X { these characters replace }{|][ and \. TeX outputs these by }
- X { first issuing the dots or circle and then backspace and set }
- X { the a or o. When dvitty finds an a or o it searches in the }
- X { near vicinity for the character codes that represent circle }
- X { or dots and if one is found the corresponding national char }
- X { replaces the special character codes. }
- X {-------------------------------------------------------------}
- X if scascii then begin
- X if (ch='a') or (ch='A') or (ch='o') or (ch='O') then begin
- X for i:=-(imin(-leftmargin, -(j-2)))
- X to imin(rightmargin, j+2) do
- X if ((ord(text[i])=127) or (ord(text[i])=23)) then
- X foo:=i;
- X if foo>=leftmargin then begin
- X j:=foo;
- X case ord(text[j]) of
- X 127 : if ch='a' then ch:='{' else { dots }
- X if ch='A' then ch:='[' else
- X if ch='o' then ch:='|' else
- X if ch='O' then ch:='\';
- X 23 : if ch='a' then ch:='}' else { circle }
- X if ch='A' then ch:=']'
- X end; { case }
- X end;
- X end;
- X end;
- X {----------------- end of 'Scandinavian code' ----------------}
- X if foo=leftmargin-1 then while (text[j]<>' ') and (j<rightmargin)
- X do begin
- X j:=j+1;
- X h:=h+charwidth
- X end;
- X if (scascii and ((ord(ch)>=chspc) or (ord(ch)=23))) or
- X (not scascii and (ord(ch)>=chspc) and (ord(ch)<>chdel)) then
- X begin
- X if j<rightmargin then text[j]:=ch
- X else text[rightmargin]:='@';
- X if j>charactercount then charactercount:=j;
- X if j<firstcolumn then firstcolumn:=j;
- X h:=h+charwidth
- X end
- X end { with currentline^ do }
- X end; { outchar }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure setchar(charnr : integer);
- X { should print characters with character code>127 from current font }
- X { note that the parameter is a dummy, since ascii-chars are<=127 }
- X begin
- X outchar('#')
- X end; { setchar }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure putcharacter(charnr : integer); { output character, don't change h }
- X var saveh : integer;
- X begin
- X saveh:=h;
- X if (charnr>=0) and (charnr<=lastchar) then outchar(chr(charnr))
- X else setchar(charnr);
- X h:=saveh;
- X end; { putcharacter }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure rule(moving : boolean; rulewt, ruleht : integer);
- X { output a rule (vertical or horizontal), increment h if moving is true }
- X var ch : char; { character to set rule with }
- X saveh, savev, wt : integer;
- X
- X procedure ruleaux; { recursive procedure that does the job }
- X var lmh, rmh : integer;
- X begin
- X wt:=rulewt;
- X lmh:=h; { save left margin }
- X if h<0 then begin { let rules that start at negative h }
- X wt:=wt-h; { start at coordinate 0, but let it }
- X h:=0; { have the right length }
- X end;
- X while wt>0 do begin { output the part of the rule that }
- X rmh:=h; { goes on this line }
- X outchar(ch);
- X wt:=wt-(h-rmh); { decrease the width left on line }
- X end;
- X ruleht:=ruleht-verticalepsilon; { decrease the height }
- X if ruleht>verticalepsilon then begin { still more vertical? }
- X rmh:=h; { save current h (right margin) }
- X h:=lmh; { restore left margin }
- X v:=v-(verticalepsilon+(verticalepsilon div 10));
- X ruleaux;
- X h:=rmh; { restore right margin }
- X end;
- X end; { ruleaux }
- X
- X begin { rule -- starts up the recursive routine }
- X if not moving then saveh:=h;
- X if (ruleht<=0) or (rulewt<=0) then h:=h+rulewt
- X else begin
- X savev:=v;
- X if (ruleht div rulewt)>0 then ch:='!'
- X else if ruleht>(verticalepsilon div 2) then ch:='='
- X else ch:='_';
- X ruleaux;
- X v:=savev;
- X end;
- X if not moving then h:=saveh;
- X end; { rule }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure fontdef(param : integer); { ignore font-definition command }
- X begin
- X setpos(DVIfile, param+12, relative);
- X setpos(DVIfile, getbyte+getbyte, relative);
- X end; { fontdef }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure horizontalmove(amount : integer; var worx : integer);
- X begin
- X if amount<>worx then
- X if abs(amount)<=(charwidth div 4) then worx:=amount
- X else begin
- X foo:=3*charwidth div 4;
- X if amount>0 then worx:=((amount+foo) div charwidth)*charwidth
- X else worx:=((amount-foo) div charwidth)*charwidth;
- X end;
- X h:=h+worx
- X end; { horizontalmove }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction inlist(pagenr : integer) : boolean; { ret true if in list of pages }
- X begin
- X inlist:=false;
- X while (currentpage^.pag<0) and (currentpage^.pag<>pagenr)
- X and not currentpage^.all and (currentpage^.nxt<>nil) do
- X currentpage:=currentpage^.nxt;
- X if (currentpage^.all and (pagenr<currentpage^.pag))
- X or (currentpage^.pag=pagenr) then inlist:=true
- X else if pagenr>0 then begin
- X while (currentpage^.pag<>pagenr) and (currentpage^.nxt<>nil) do
- X currentpage:=currentpage^.nxt;
- X if currentpage^.pag=pagenr then inlist:=true
- X end
- X end; { inlist }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xfunction bop(var pagecounter, backpointer, pagenr : integer) : boolean;
- X begin
- X pagecounter:=pagecounter+1;
- X pagenr:=signed4;
- X setpos(DVIfile, 36, relative);
- X backpointer:=signed4;
- X if pageswitchon then
- X if sequenceon then bop:=inlist(pagecounter)
- X else bop:=inlist(pagenr)
- X else bop:=true;
- X end; { bop }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure initpage(backpointer, pagenr, pagecounter : integer);
- X begin
- X h:=0; v:=0; { initialize coordinates }
- X x:=0; w:=0; y:=0; z:=0; { initialize amounts }
- X stack.top:=0; { initialize stack }
- X currentline:=getline; { initialize list of lines }
- X currentline^.vv:=0;
- X firstline:=currentline;
- X lastline:=currentline;
- X firstcolumn:=rightmargin;
- X if pageswitchon then
- X if (sequenceon and (pagecounter<>firstpage^.pag))
- X or (not sequenceon and (pagenr<>firstpage^.pag)) then
- X if noffd then writeln('^L') else writeln(chr(chffd));
- X if not pageswitchon then if backpointer<>-1 then
- X if noffd then writeln('^L') else writeln(chr(chffd));
- X end; { initpage }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure dover2page;
- X begin
- X opcode:=getbyte;
- X while opcode<>eop2 do begin { process page until eop reached }
- X if opcode>postpost2 then errorexit(illop)
- X else if opcode<=lastchar then outchar(chr(opcode))
- X else if opcode in [128..170, 235..249] then
- X case opcode of
- X 128 : setchar(getbyte);
- X 129 : setchar(get2);
- X 130 : setchar(get3);
- X 131 : setchar(signed4);
- X 132 : rule(advance, signed4, signed4);
- X 133 : putcharacter(getbyte);
- X 134 : putcharacter(get2);
- X 135 : putcharacter(get3);
- X 136 : putcharacter(signed4);
- X 137 : rule(stay, signed4, signed4);
- X nop2: ; { no-op }
- X bop2: errorexit(bdbop);
- X 141 : with stack do begin { push }
- X if top>stackmax-1 then errorexit(stkof);
- X top:=top+1;
- X with items[top] do begin
- X hh:=h; vv:=v; ww:=w;
- X xx:=x; yy:=y; zz:=z;
- X end;
- X end;
- X 142 : with stack do begin { pop }
- X if top=0 then errorexit(stkuf);
- X with items[top] do begin
- X h:=hh; v:=vv; w:=ww;
- X x:=xx; y:=yy; z:=zz;
- X end;
- X top:=top-1;
- X end;
- X 143 : h:=h+signedbyte;
- X 144 : h:=h+signed2;
- X 145 : h:=h+signed3;
- X 146 : h:=h+signed4;
- X 147 : horizontalmove(w, w);
- X 148 : horizontalmove(signedbyte, w);
- X 149 : horizontalmove(signed2, w);
- X 150 : horizontalmove(signed3, w);
- X 151 : horizontalmove(signed4, w);
- X 152 : horizontalmove(x, x);
- X 153 : horizontalmove(signedbyte, x);
- X 154 : horizontalmove(signed2, x);
- X 155 : horizontalmove(signed3, x);
- X 156 : horizontalmove(signed4, x);
- X 157 : v:=v+signedbyte;
- X 158 : v:=v+signed2;
- X 159 : v:=v+signed3;
- X 160 : v:=v+signed4;
- X 161 : v:=v+y;
- X 162 : begin y:=signedbyte; v:=v+y end;
- X 163 : begin y:=signed2; v:=v+y end;
- X 164 : begin y:=signed3; v:=v+y end;
- X 165 : begin y:=signed4; v:=v+y end;
- X 166 : v:=v+z;
- X 167 : begin z:=signedbyte; v:=v+z end;
- X 168 : begin z:=signed2; v:=v+z end;
- X 169 : begin z:=signed3; v:=v+z end;
- X 170 : begin z:=signed4; v:=v+z end;
- X 235, 236, 237, { ignore font changes }
- X 238 : setpos(DVIfile, opcode-234, relative);
- X 239 : setpos(DVIfile, getbyte, relative);
- X 240 : setpos(DVIfile, get2, relative);
- X 241 : setpos(DVIfile, get3, relative);
- X 242 : setpos(DVIfile, signed4, relative);
- X 243,244,245,
- X 246 : fontdef(opcode-242);
- X pre2 : errorexit(bdpre);
- X post2 : errorexit(bdpst);
- X postpost2: errorexit(bdpp);
- X end;
- X opcode:=getbyte
- X end
- X end; { dover2page }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure eop; { 'end of page', writes lines of page to output file }
- X var i, j : integer;
- X ch : char;
- X begin
- X if stack.top<>0 then
- X writeln(ERRfile, 'dvitty: warning - stack not empty at eop.');
- X currentline:=firstline;
- X repeat
- X with currentline^ do begin
- X if currentline<>firstline then begin
- X foo:=((vv-prev^.vv) div verticalepsilon)-1;
- X if foo>0 then foo:=imin(foo, 3);
- X for i:=1 to foo do writeln;
- X end;
- X if charactercount>=leftmargin then begin
- X i:=firstcolumn; j:=1; foo:=ttywidth-2;
- X repeat
- X ch:=text[i];
- X if (ord(ch)>=chspc) and (ord(ch)<>chdel) then
- X write(ch);
- X if j>foo then if charactercount>i+1 then begin
- X writeln('*');
- X write(' *');
- X j:=2
- X end;
- X i:=i+1; j:=j+1
- X until i>charactercount;
- X end
- X end;
- X writeln;
- X currentline:=currentline^.next;
- X until currentline^.next=nil;
- X end; { eop }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure skipver2page; { skip past one page }
- X begin
- X opcode:=getbyte;
- X while opcode<>eop2 do begin
- X if opcode>postpost2 then errorexit(illop)
- X else if opcode in [128..170, 235..249] then
- X case opcode of
- X nop2,141, 142, 147, 152, 161, 166 : ;
- X 128, 133, 143, 148, 153, 157, 162, 167, 235 :
- X setpos(DVIfile, 1, relative);
- X 129, 134, 144, 149, 154, 158, 163, 168, 236 :
- X setpos(DVIfile, 2, relative);
- X 130, 135, 145, 150, 155, 159, 164, 169, 237 :
- X setpos(DVIfile, 3, relative);
- X 131, 136, 146, 151, 156, 160, 165, 170, 238 :
- X setpos(DVIfile, 4, relative);
- X 132, 137 : setpos(DVIfile, 8, relative);
- X 139 : errorexit(bdbop);
- X 239 : setpos(DVIfile, getbyte, relative);
- X 240 : setpos(DVIfile, get2, relative);
- X 241 : setpos(DVIfile, get3, relative);
- X 242 : setpos(DVIfile, signed4, relative);
- X 243,244,245,
- X 246 : fontdef(opcode-242);
- X pre2 : errorexit(bdpre);
- X post2 : errorexit(bdpst);
- X postpost2 : errorexit(bdpp);
- X end;
- X opcode:=getbyte;
- X end;
- X end; { skipver2page }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure dopages; { process the pages in the DVI-file }
- X var pagecounter, backpointer, pagenr : integer;
- X begin
- X setpos(DVIfile, 0, absolute); { read the dvifile from the start }
- X pagecounter:=0;
- X if not skipnoops(pre2) then errorexit(nopre);
- X opcode:=getbyte; { check id in preamble, ignore rest of it }
- X if opcode<>versionid then errorexit(badid);
- X setpos(DVIfile, 12, relative);
- X setpos(DVIfile, getbyte, relative);
- X if not skipnoops(bop2) then errorexit(nobop) { should be at start }
- X else while opcode<>post2 do begin { of page now }
- X if opcode<>bop2 then errorexit(nobop)
- X else begin
- X if not bop(pagecounter, backpointer, pagenr) then skipver2page
- X else begin
- X initpage(backpointer, pagenr, pagecounter);
- X dover2page;
- X eop;
- X end;
- X repeat opcode:=getbyte until opcode<>nop2
- X end
- X end;
- X end; { dopages }
- X
- X{-----------------------------------------------------------------------------}
- X
- Xprocedure postamble; { find and process postamble, use random access }
- X var size, count : integer;
- X begin
- X size:=sizef(DVIfile); { get size of file }
- X count:=-1;
- X repeat { back file up past signature bytes (223), to id-byte }
- X if size=0 then errorexit(nopst);
- X size:=size-1;
- X setpos(DVIfile, size, absolute);
- X opcode:=getbyte;
- X count:=count+1; { has to be at least 4 sign-bytes }
- X until opcode<>223;
- X if count<4 then begin foo:=count; errorexit(fwsgn); end;
- X if opcode<>versionid then errorexit(badid);
- X setpos(DVIfile, size-4, absolute); { back up to back-pointer }
- X setpos(DVIfile, signed4, absolute); { back up to start of postamble }
- X if getbyte<>post2 then errorexit(nopst);
- X setpos(DVIfile, 20, relative);
- X maxpagewidth:=signed4;
- X charwidth:=maxpagewidth div ttywidth;
- X foo:=get2;
- X if foo>stackmax then errorexit(stkrq); { too much stack required }
- X end; { postamble }
- X
- X(*****************************************************************************
- X *
- X * M A I N
- X *)
- X
- Xbegin
- X rewrite(ERRfile, '/dev/tty'); { get a pascal file }
- X tostderr(ERRfile); { and redirect it to stderr }
- X getargs; { read the command line arguments }
- X if not readp(DVIfilename) then
- X errorexit(filop); { can't open dvifile }
- X reset(DVIfile, DVIfilename);
- X if outputtofile then begin { open the outfile }
- X if not writep(OUTfilename) then
- X errorexit(filcr); { can't create outfile }
- X rewrite(output, OUTfilename);
- X pager:=false;
- X end else
- X if ttyp(output) and pager then { try to pipe to a pager }
- X pager:=popenp(output, path, pathpgm);
- X postamble; { seek and process the postamble }
- X dopages; { time to do the actual work! }
- X if pager then pcloseit(output); { have to use pclose if popened }
- Xend.
- + END-OF-FILE dvitty.p
- chmod 'u=rw,g=rw,o=r' 'dvitty.p'
- echo ' -rw-rw-r-- 1 zap 47572 Aug 15 20:29 dvitty.p (as sent)'
- echo -n ' '
- /bin/ls -l dvitty.p
- echo 'Extracting sys.h'
- sed 's/^X//' > sys.h << '+ END-OF-FILE sys.h'
- Xprocedure exit(i : integer); external; { in libc }
- X
- Xprocedure setpos(var f : DVIfiletype; p, m : integer); external;
- X
- Xfunction sizef(var f : DVIfiletype) : integer; external;
- X
- Xprocedure delete(var f : text); external;
- X
- Xfunction readp(var filename : string) : boolean; external;
- X
- Xfunction writep(var filename : string) : boolean; external;
- X
- Xprocedure tostdout(var f :text); external;
- X
- Xprocedure tostderr(var f : text); external;
- X
- Xfunction ttyp(var f :text) : boolean; external;
- X
- Xfunction popenp(var f :text; var path : pathtype;
- X pathpgm : boolean) : boolean; external;
- X
- Xprocedure pcloseit(var f :text); external;
- X
- Xfunction envargs(var optch :char; var str :string) : boolean; external;
- + END-OF-FILE sys.h
- chmod 'u=rw,g=r,o=r' 'sys.h'
- echo ' -rw-r--r-- 1 zap 720 Aug 8 00:22 sys.h (as sent)'
- echo -n ' '
- /bin/ls -l sys.h
- echo 'Extracting sys.c'
- sed 's/^X//' > sys.c << '+ END-OF-FILE sys.c'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#define NAMSIZ 76
- X#define SYNC 0x004 /* 1 => window is out of sync */
- X
- Xtypedef enum {FALSE, TRUE} bool;
- X
- Xstruct iorec {
- X char *fileptr; /* ptr to file window */
- X long lcount; /* number of lines printed */
- X long llimit; /* maximum number of text lines */
- X FILE *fbuf; /* FILE ptr */
- X struct iorec *fchain; /* chain to next file */
- X struct iorec *flev; /* ptr to associated file variable */
- X char *pfname; /* ptr to name of file */
- X short funit; /* file status flags */
- X unsigned short fblk; /* index into active file table */
- X long fsize; /* size of elements in the file */
- X char fname[NAMSIZ]; /* name of associated UNIX file */
- X char buf[BUFSIZ]; /* I/O buffer */
- X char window[1]; /* file window element */
- X};
- X
- Xsetpos(f, p, m) /* seek on a pascal file */
- Xstruct iorec *f;
- Xint p, m;
- X{
- X f->funit |= SYNC;
- X (void) fseek (f->fbuf, (long) p, m);
- X}
- X
- Xint
- Xsizef(f) /* return size of file */
- Xstruct iorec *f;
- X{
- X struct stat st;
- X
- X (void) fstat (fileno(f->fbuf), &st);
- X return (st.st_size);
- X}
- X
- Xdelete(f) /* remove a link to a file */
- Xstruct iorec *f;
- X{
- X (void) unlink (f->pfname);
- X}
- X
- Xbool
- Xreadp(filename) /* check if a file may be read */
- Xchar *filename;
- X{
- X register char *p;
- X register bool ok;
- X
- X for(p=filename; *p!=' '; p++) /* pascal strings are space-padded */
- X ;
- X *p='\0'; /* make it a C-string */
- X if (access(filename, 04) == 0) /* check if we can read this file */
- X ok=TRUE;
- X else
- X ok=FALSE;
- X *p=' '; /* "re-pasclify" the string */
- X return(ok);
- X}
- X
- Xbool
- Xwritep(filename) /* check if a file may be written */
- Xchar *filename;
- X{
- X register char *p;
- X register bool ok;
- X int f;
- X
- X for(p=filename; *p!=' '; p++) /* pascal strings are space-padded */
- X ;
- X *p='\0'; /* make it a C-string */
- X if ((f=creat(filename, 0666)) >= 0) { /* can we create this file?*/
- X (void) close(f);
- X ok = TRUE;
- X } else
- X ok = FALSE;
- X *p=' '; /* "re-pasclify" the string */
- X return(ok);
- X}
- X
- Xtostdout(f) /* make file appear on stdout */
- Xstruct iorec *f;
- X{
- X (void) fflush (f->fbuf);
- X f->fbuf = stdout;
- X}
- X
- Xtostderr(f) /* make file appear on stderr */
- Xstruct iorec *f;
- X{
- X (void) fflush (f->fbuf);
- X f->fbuf = stderr;
- X}
- X
- Xbool
- Xttyp(f) /* is file associated with a tty? */
- Xstruct iorec *f;
- X{
- X if (isatty(fileno(f->fbuf))==1)
- X return(TRUE);
- X else
- X return(FALSE);
- X}
- X
- Xbool
- Xpopenp(f, path, pthpgm) /* can this file be piped into a */
- Xstruct iorec *f; /* pager (like more)? */
- Xchar *path;
- Xbool pthpgm;
- X{
- X char *getenv(), *p;
- X FILE *popen(), *g;
- X
- X if (pthpgm==FALSE) { /* -Fpath option used */
- X for(p=path; *p !=' ' && *p != '\0'; p++)
- X ;
- X *p = '\0';
- X } else if ((p=getenv("PAGER"))==NULL) { /* find prefered pager */
- X for(p=path; *p !=' ' && *p != '\0'; p++)
- X ; /* didn't have one, use */
- X *p = '\0'; /* the default one for pgm */
- X } else
- X path = p; /* default pager from env */
- X if ((g=popen(path, "w"))!=NULL) { /* get a pipe to the pager */
- X (void) fflush (f->fbuf); /* make output to f go to */
- X f->fbuf = g; /* the pager */
- X return(TRUE);
- X } else
- X return(FALSE); /* couldn't do it */
- X}
- X
- Xpcloseit(f) /* popend stream has to be */
- Xstruct iorec *f; /* pclosed */
- X{
- X (void) pclose (f->fbuf);
- X}
- X
- Xbool
- Xenvargs(optch, str)
- Xchar *optch, *str;
- X{
- X char *getenv(), *q;
- X static char *p;
- X static int foo = 0;
- X
- X switch (foo) {
- X case 0: if ((p=getenv("DVITTY"))==NULL) /* 1st time only, get var */
- X return(FALSE); /* sorry, no var */
- X foo++; /* remember we've been here to next call */
- X /* fall through */
- X default:
- X if (*p!=' ' && *p!='\0') /* anything here? */
- X *optch = *p++; /* yes, it's our optchar */
- X else
- X return(FALSE); /* sorry, no more */
- X q=str; /* get args or whatever */
- X while (*p!=' ' && *p!='\0')
- X *q++ = *p++;
- X *q=' '; /* the pascal program wants ' ' */
- X while (*p==' ') /* step to next or end */
- X p++;
- X return(TRUE);
- X }
- X}
- + END-OF-FILE sys.c
- chmod 'u=rw,g=r,o=r' 'sys.c'
- echo ' -rw-r--r-- 1 zap 3999 Aug 8 00:24 sys.c (as sent)'
- echo -n ' '
- /bin/ls -l sys.c
- exit 0
-
-