home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-01-09 | 51.6 KB | 2,015 lines |
- /* -*-C-*- LPTOPS.C */
- /*-->lptops*/
- /**********************************************************************/
- /******************************* lptops *******************************/
- /**********************************************************************/
-
- /***********************************************************************
-
- NB: In order to handle overprinting of input of the form
-
- ...text...<CR>...overtext...<CR><LF>
-
- this must be loaded with a special version of the C library I/O routine
- (PCC:IOCR.REL on the DEC-20) which permits reading and writing of <CR>.
- No special action need be taken on Unix systems, since <CR> is not
- filtered out, and is normally absent. On PC-DOS, open options of "rb"
- will usually be necessary (this is the default on all systems but
- TOPS-20).
- ***********************************************************************/
-
- /***********************************************************************
-
- Line printer file to PostScript converter
- [03-Jul-85]
- [12-Nov-85]
- [07-Apr-86]
- [03-May-88]
- [22-Dec-89]
-
- lptops converts normal text files into PostScript for printing on the
- Apple LaserWriter, or any other PostScript-compatible printing device.
- It supports selection of a variety of fonts at arbitrary point sizes,
- margin specification, portrait and landscape page orientation, automatic
- page numbering, page outlining, and multi-column printing. It can also
- handle overstruck text used by many document formatters for underlining.
-
- Usage:
-
- lptops [switches] <infile >outfile
- lptops [switches] filelist >outfile
-
- In the switch descriptions below, physical dimensions described as # may
- be specified as a single number with an optional fractional part, and a
- required two-letter unit designator. Letter case is ignored. Possible
- forms are:
-
- #.##bp big point (1in = 72bp) [Courier: 120.000/Pbp cpi]
- #.##cc cicero (1cc = 12dd) [Courier: 9.381/Pcc cpi]
- #.##cm centimeter [Courier: 4.233/Pcm cpi]
- #.##dd didot point (1157dd = 1238pt)[Courier: 112.569/Pdd cpi]
- #.##in inch [Courier: 1.667/Pin cpi]
- #.##mm millimeter (10mm = 1cm) [Courier: 42.333/Pmm cpi]
- #.##pc pica (1pc = 12pt) [Courier: 10.038/Ppc cpi]
- #.##pt point (72.27pt = 1in) [Courier: 120.450/Ppt cpi]
- #.##sp scaled point (65536sp = 1pt) [Courier: 7.893/(Psp/1000000) cpi]
-
- The bracketed values give the number of characters per inch (cpi) for a
- point size of P units with the fixed-width Courier font. For example,
- with point size 8bp, there are 120/8 = 15 characters per inch. With
- point size 1000000sp, there are 7.893 characters/inch.
-
- The optional switches are (letter case is ignored):
-
- -A Turn Scribe-like bold and italic requests (@b[...] and
- @i[...]) into bold or italic text.
-
- -B# Bottom margin of #.
-
- -Cn Print n copies of each page.
-
- -D[tb][n]
- Display header or footer in the following format:
-
- Date/Time File Name Page #
-
- The position can be selected explicitly by t (top) or
- b (bottom). If n is given, start numbering with that
- value, and otherwise with 1. If an initial top margin
- value is given with the -I# option, numbering will be
- omitted on the first page if it is at the top. Pages
- are unnumbered if this option or the N option is not
- specified.
-
- -Ffontname
- PostScript fontname. Possible values with acceptable
- short abbreviations formed from the upper-case letters
- in the font names, and the ditroff and Adobe TranScript
- abbreviations are as follows. The first 13 are
- available on all PostScript printers; the remainder are
- available only on enhanced printers, such as the Apple
- LaserWriter Plus.
-
- ==================== ===== ====== ==========
- full name short ditroff TranScript
- ==================== ===== ====== ==========
- Courier C C C
- Courier-Bold CB CB CB
- Courier-BoldOblique CBO CD CD
- Courier-Oblique CO CO CO
- Helvetica H he he
- Helvetica-Bold HB He He
- Helvetica-BoldOblique HBO HE HE
- Helvetica-Oblique HO hE hE
- Symbol S S S
- Times-Bold TB R ti
- Times-BoldItalic TBI BI TI
- Times-Italic TI I tI
- Times-Roman T R ti
-
- AvantGarde-Book AGB ag ag
- AvantGarde-BookOblique AGBO aG aG
- AvantGarde-Demi AGD Ag Ag
- AvantGarde-DemiOblique AGDO AG AG
- Bookman-Demi BD Bo Bo
- Bookman-DemiItalic BDI BO BO
- Bookman-Light BL bo bo
- Bookman-LightItalic BLI bO bO
- Helvetica-Narrow HN hn hn
- Helvetica-Narrow-Bold HNB Hn Hn
- Helvetica-Narrow-BoldOblique HNBO HN HN
- Helvetica-Narrow-Oblique HNO hN hN
- NewCenturySchlbk-Bold NCSB Nc Nc
- NewCenturySchlbk-BoldItalic NCSBI NC NC
- NewCenturySchlbk-Italic NCSI nC nC
- NewCenturySchlbk-Roman NCSR nc nc
- Palatino-Bold PB Pa Pa
- Palatino-BoldItalic PBI PA PA
- Palatino-Italic PI pA pA
- Palatino-Roman PR pa pa
- ZapfChancery-MediumItalic ZCMI ZC ZC
- ZapfDingbats ZD ZD ZD
- ==================== ===== ====== ==========
-
- The ditroff and TranScript abbreviations are the same,
- except for the Courier and Times fonts. They are based
- on two-letter mnemonics, where upper-case in the first
- letter means bold, and upper-case in the second letter
- means italic.
-
- Only the Courier fonts are fixed-width like typewriter
- and line printer fonts are. The others are proportional
- spaced for improved readability, and consequently,
- tabular material will not line up properly with them.
- The Courier fonts have a width equal to 0.6 of their
- point size, so to fill a line W inches wide with up to N
- characters, one must have point size <= (W/(0.6 * N *
- 72)) = (W*120)/N pt. Equivalently, with a point size P
- pt, the output spacing is 120/P char/inch.
-
- -H Horizontal page orientation (landscape mode) instead of
- vertical page (portrait mode).
-
- -I# Top margin of # for initial page (for letterheads); if
- not specified, it will default to the value given for
- the top margin by default or by the -T# command.
-
- -L# Left margin of #.
-
- -Mn Multiple column output (n columns). In multiple column
- mode, formfeeds cause column breaks instead of page
- breaks.
-
- -N[tb][lcr][n]
- Number output pages. The number is placed by default in
- the center of the top margin, but the margin can be
- selected explicitly by t (top) or b (bottom), and the
- position of the page number can be further specified by
- l (left), c (center), or r (right). If n is given,
- start numbering with that value, and otherwise with 1.
- If an initial top margin value is given with the -I#
- option, numbering will be omitted on the first page if
- it is at the top. Pages are unnumbered if this option
- or the D is not specified.
-
- -O[#] Outline pages (and columns) with a # units wide. A
- narrow line of 0.4pt width is assumed if # is omitted;
- this particular width is what TeX uses in typesetting.
-
- -P# Font point size (default 10bp). The baseline skip
- (spacing between successive character baselines) is
- conventionally chosen to be 6/5 of this value, so that
- with 10bp type, we have 12bp between lines, or 6
- lines/inch, the same as standard printer output.
-
- -R# Right margin of #.
-
- -S[n] special handling (i.e. manual paper feed) for the first
- n pages of the output. If N multiple copies are in
- effect, then N*n sheets must be fed manually. If n is
- omitted, then all pages are to be fed manually. For
- example, -S1 is convenient to get the first page of a
- letter on letterhead paper fed manually, with remaining
- pages from the paper cassette.
-
- -T# Top margin of #.
-
- -U Output pages in unsorted (first to last) order instead
- of in sorted (page reversed) order; some PostScript
- printers have page handlers that stack the paper in this
- order. The default is sorted because this is
- appropriate for the most common PostScript printer, the
- Apple LaserWriter.
-
- Defaults are:
-
- -B1.0in -C1 -FCourier -L1.0in -M1 -P10bp -R1.0in -S0 -T1.0in
-
-
- Revision history (reverse time order):
-
- [22-Dec-89] Ported to the Amiga and added header-footer option. Also
- fixed initial page numbering options which never worked.
- - Pat Empleo -
-
- [03-May-88] Add ditroff and Adobe TranScript font abbreviations.
-
- [19-Apr-86] Change page/line status report from output in End_Page()
- only to output in Beg_Page() and End_Column().
-
- [07-Apr-86] Fix some incorrect font names, put font names into
- table, add font abbreviations and new font names, change
- default font to Courier (because most printing expects
- fixed-width fonts). Add usage message if bad options,
- and print fontnames if bad font switch given. Allow
- multiple filenames on command line instead of just using
- stdin -- this added new function Do_File() and changed
- argument lists of inchar() and Copy_Plist(). Add
- save/restore around each page image following new 1986
- PostScript Language Reference Manual recommendation, and
- change multiple copies sequence from repeat loop to
- setting of standard variable #copies. Add -U option for
- unsorted output.
-
- [03-Feb-86] Fix setting of final entry of page_table[]. It should
- only be done when End_Page() is called, since otherwise
- Beg_Page() has already set the final entry, and we just
- have an empty page to be discarded. Without this fix,
- this left a hole (0), so the entire file got copied in
- its entirety to the last page of the sorted file.
-
- [18-Jan-86] Add (void) to fprintf()/printf(), test for disk storage
- full at end of page, add OUTSTR() macro using fputs()
- instead of fprintf() for efficiency.
-
- [20-Dec-85] Change getchar() to inchar(); the latter supplies a
- trailing LF at EOF in the event it is missing.
- Otherwise, the output PostScript has two tokens
- jammed together (P 1 {copypage} --> P1 {copypage})
-
- [20-Dec-85] Following recommendation of Allan Hetzel on LASER-LOVERS
- ARPA BBOARD, added "() pop" at top of every page. This
- is selected by the switch FIX31OCT85:
-
- --------------------------------------------------------
- From: Allan Hetzel <SYSAL%UKCC.BITNET@WISCVM.ARPA>
- Subject: Re: Apple Laserwriter XON/XOFF problem
- To: <LASER-LOVERS@WASHINGTON.ARPA>
-
- The note posted to Laser-Lovers on Oct 28 by Joseph
- Goldstone of Symbolics Cambridge Research Center was
- helpful but I didn't try his suggested fix correctly and
- so I called Adobe. They were very helpful (much more so
- than Apple) and explained the problem and how to bypass
- it.
-
- My apologies to Adobe if this not an accurate
- description of the problem. The problem apparently is
- due to the PostScript interpreter getting confused by
- what it thinks is an excess of white space characters.
-
- The bypass is to place a special character (parenthesis,
- bracket, brace, slash, etc.) to the right of some token,
- but without an intervening white space character. As the
- PostScript scanner reads the token it also reads the
- special character which acts as a delimiter. The scanner
- then has to back up one character so that it can
- reprocess the special character after it has processed
- the preceding token. During this backing up process a
- number of internal values are recalculated, including
- some pointer into the input buffer. This causes the
- XON/XOFF protocol to work properly. Doing this once per
- page seems to keep everybody happy.
-
- Each page in the PostScript file built by our word
- processing program is surrounded by a "save restore"
- sequence. We changed the beginning save sequence
- "/saveobj save def" to read "/saveobj save def() pop".
- The "() pop" is effectively a no-op and we are assured
- that the necessary recalculations are done on each page.
- This seems to have corrected the problem completely.
-
- Allan Hetzel (sysal@ukcc.bitnet)
- --------------------------------------------------------
-
- [11-Dec-85] Fix problem with extra () around overstruck text.
-
- [13-Nov-85] Insert FASTIO conditional compilation option to speed up
- page reversal. Under VAX 4.2BSD, fread() and fwrite()
- are already fast enough, and need not be replaced.
-
- [12-Nov-85] Add reversal of pages, storing output on intermediate
- file which is deleted before exiting.
-
- [02-Nov-85] Add code to write output on temporary file, then
- retrieve in reverse page order and output on stdout.
-
- [30-Oct-85] Add code to handle overstruck lines:
- ...text...<CR>...overtext...<CR><LF>
- will appear as
- (...text...) O
- (...overtext...) P
-
- Macro definitions and font selection now repeated
- on each page to allow selective reprinting.
-
- [07-Oct-85] Add code to discard input NUL's from word-padded files,
- since the LaserWriter prints them as blanks.
-
- [27-Sep-85] Added missing 'N' switch, fixed Page_Switch() (it scanned
- beyond last digit of page number)
-
- [11-Jul-85] Original version.
-
-
- ***********************************************************************/
-
-
- #ifndef OS_AMIGA
- #define OS_AMIGA 0
- #endif
-
- #ifndef OS_TOPS20
- #define OS_TOPS20 0
- #endif
-
- #ifndef KCC_20
- #define KCC_20 0
- #endif
-
- #ifndef PCC_20
- #define PCC_20 0
- #endif
-
- #if (KCC_20 | PCC_20)
- #ifndef OS_TOPS20
- #define OS_TOPS20 1
- #endif
- #endif
-
- #ifndef OS_VAXVMS
- #define OS_VAXVMS 0
- #endif
-
- #ifndef OS_ATARI
- #define OS_ATARI 0
- #endif
-
- #ifndef OS_PCDOS
- #define OS_PCDOS 0
- #endif
-
- #ifndef IBM_PC_AZTEC
- #define IBM_PC_AZTEC 0
- #endif
-
- #ifndef IBM_PC_LATTICE
- #define IBM_PC_LATTICE 0
- #endif
-
- #ifndef IBM_PC_MICROSOFT
- #define IBM_PC_MICROSOFT 0
- #endif
-
- #ifndef IBM_PC_WIZARD
- #define IBM_PC_WIZARD 0
- #endif
-
- #if (IBM_PC_AZTEC | IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
- #ifndef OS_PCDOS
- #define OS_PCDOS 1
- #endif
- #endif
-
- #if (OS_AMIGA | OS_ATARI | OS_TOPS20 | OS_PCDOS | OS_VAXVMS)
- #define OS_UNIX 0
- #else
- #define OS_UNIX 1
- #endif
-
- #if (OS_AMIGA | OS_ATARI | PCC_20)
- #define DISKFULL(fp) ferror(fp) /* PCC-20 does not always set errno */
- #else
- #define DISKFULL(fp) (ferror(fp) && (errno == ENOSPC))
- #endif
-
- #if OS_VAXVMS
- #define EXIT vms_exit
- #else
- #define EXIT exit
- #endif
-
- #if IBM_PC_LATTICE
- typedef int void; /* Lattice C does not have this */
- #endif
-
- #if IBM_PC_MICROSOFT
- #define ANSI_PROTOTYPES 1
- #endif
-
- #ifndef ANSI_PROTOTYPES
- #define ANSI_PROTOTYPES 0
- #endif
-
- #ifndef ANSI_LIBRARY
- #define ANSI_LIBRARY 0
- #endif
-
- /*
- ************************************************************************
- On TOPS-20, fread()/fwrite() are implemented as loops around
- getc()/putc() calls, and these in turn also do CR/LF translation. Calls
- to _read() and _write() translate into direct calls to the Monitor for
- fast efficient block I/O. FASTIO selects this option. It is used in
- Copy_Block when the temporary file is output in reverse page order to
- stdout.
- ************************************************************************
- */
-
- #if OS_AMIGA
- extern int strcmp();
- #endif
-
- #if OS_TOPS20
- #if PCC_20
- #define FASTIO 1 /* TOPS-20 use only */
- #undef DISKFULL
- #define DISKFULL(fp) ferror(fp) /* PCC-20 does not always set errno */
- extern int strcmp();
- #endif
- #endif
-
- #define FIX31OCT85 1 /* Allan Hetzel's XON/XOFF fix */
-
- typedef int BOOLEAN;
-
- #define FALSE 0
- #define TRUE 1
-
- #ifndef FASTIO
- #define FASTIO 0
- #endif
-
- #define PXLID 0 /* used in inch.h */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- #ifndef OS_AMIGA
- #include <string.h>
- #endif
-
- #if IBM_PC_MICROSOFT
- /* int errno; */ /* not in errno.h */
- #include <stdlib.h>
- #include <time.h>
- #endif
-
- #if OS_TOPS20
- #include <time.h>
- #endif
-
- #if FASTIO
- #include <file.h>
- #include <jsys.h>
- #include <mon_s.h>
- #endif
-
- #if (OS_AMIGA | OS_TOPS20 | OS_UNIX | OS_VAXVMS | IBM_PC_AZTEC)
- #define FOPEN_W "w"
- #define FOPEN_R "r"
- #else
- #define FOPEN_W "wb"
- #define FOPEN_R "rb"
- #endif
-
- /***********************************************************************
- PostScript's basic units are big points (72bp = 1in). Everything in
- this routine works in terms of "Quite Small Units": 1 inch = QSU qsu.
- ***********************************************************************/
-
-
- #define NUL '\0'
-
- #define QSU 100000L /* quite small units per inch -- */
- /* should be large to avoid */
- /* truncation error accumulation */
-
- #define INCH_TO_QSU(x) ((COORDINATE)(x * (float)QSU))
- /* inch to QSU conversion */
-
- #define LEFT_X (left_margin + col_margin)
- #define BOT_Y (bottom_margin + col_margin)
- #define TOP_Y(margin) (page_height - (margin) - baseline_skip - col_margin)
-
- #if OS_TOPS20 /* want <CR><LF> */
- #define NEWLINE(fp) {(void)putc((char)'\r',fp);(void)putc((char)'\n',fp);}
- #else
- #define NEWLINE(fp) (void)putc((char)'\n',fp) /* want bare <LF> */
- #endif
-
- #define OUTCHAR(c) (void)putc((char)(c),tf)
- #define OUTOCTAL(c) (void)fprintf(tf,"\\%03o",(c))
- #define OUTSTR(s) (void)fputs(s,tf)
-
- #define MAX(a,b) ((a) > (b) ? (a) : (b))
- #define MIN(a,b) ((a) < (b) ? (a) : (b))
-
- #define HEIGHT (11L * QSU) /* page height in QSU */
- #define MAXBLOCK 4096L /* block size for file copy */
- #define MAXLEN 256 /* font name length */
- #define MAXPAGE 1024 /* size of page location table */
- #define WIDTH ((85L * QSU)/10L) /* page width in QSU */
- #define COL_TWIDDLE 40L /* 1/fraction of column width for */
- /* column margin */
-
- #define PAGE_T 001 /* flag bits for page_flag */
- #define PAGE_B 002
- #define PAGE_L 010
- #define PAGE_R 020
- #define PAGE_C 040
-
- #define TEMPFILE "lptops.tmp" /* temporary output file */
-
-
- /* global functions */
- #if ANSI_PROTOTYPES
- int main(int ,char *[]);
- void Beg_Column(void);
- void Beg_Line(void);
- void Beg_Page(void);
- void Beg_Text(char);
- void Copy_Block(long ,long);
- void Copy_Plist(char, FILE *);
- void Do_File(FILE *);
- void End_Column(void);
- void End_Page(void);
- void End_Line(void);
- void End_Text(char);
- float inch(char *);
- int inchar(FILE *);
- void Page_Switch(char *);
-
- #if ANSI_LIBRARY
- int atoi(const char *);
- char* ctime(const time_t *);
- #else /* NOT ANSI_LIBRARY */
- int atoi(char *);
- char* ctime(long *);
- #endif /* ANSI_LIBRARY */
-
- char *cuserid(char *);
- void EXIT(int);
- char *getlogin(void);
-
- #if ANSI_LIBRARY
- void perror(const char *);
- char *strcpy(char *,const char *);
- int strcm2(char *,char *);
- size_t strlen(const char *);
- char *strncpy(char *,const char *,size_t);
- time_t time(time_t *);
- int unlink(const char *);
- #else /* NOT ANSI_LIBRARY */
- void perror(char *);
- char *strcpy(char *,char *);
- int strcm2(char *,char *);
- int strlen(char *);
- char *strncpy(char *,char *,int);
- long time(long *);
- int unlink(char *);
- #endif /* ANSI_LIBRARY */
-
- #else
- void Beg_Column();
- void Beg_Line();
- void Beg_Page();
- void Beg_Text();
- void Copy_Block();
- void Copy_Plist();
- void Do_File();
- void End_Column();
- void End_Page();
- void End_Line();
- void End_Text();
- void Head_Foot_Switch();
- float inch();
- int inchar();
- int main();
- void Page_Switch();
-
- int atoi();
- char *ctime();
- char *cuserid();
- void EXIT();
- char *getlogin();
- void perror();
- char *strcpy();
- int strcm2();
- int strlen();
- char* strncpy();
- long time();
- int unline();
- #endif
-
- typedef long COORDINATE; /* variables in QSU need >=32 bits */
-
-
- /* global variables */
-
- FILE *tf; /* temporary output file */
- BOOLEAN bad_option; /* bad option flag */
- COORDINATE baseline_skip; /* inter-line spacing */
- COORDINATE bottom_margin; /* bottom margin width in QSU */
- int column; /* current text column (1..numcol) */
- COORDINATE col_margin; /* column margin (extra space */
- /* between column borders in */
- /* multi-column mode) */
- COORDINATE col_width; /* column width in QSU */
- int copies; /* number of copies of each page */
- BOOLEAN do_headerfooter; /* header-footer flag */
- BOOLEAN do_page_number; /* page numbering flag */
- char *filename; /* file name */
- char font_name[MAXLEN+1]; /* font name -- normal */
- char font_bold[MAXLEN+1]; /* font name -- bold */
- char font_italic[MAXLEN+1]; /* font name -- italic */
- BOOLEAN found; /* search flag */
- int in_col; /* input line column */
- int init_page_number; /* initial page number */
- COORDINATE init_top_margin; /* initial page top margin in QSU */
- BOOLEAN landscape_mode; /* horizontal landscape mode output */
- COORDINATE left_margin; /* left margin in QSU */
- int level; /* parenthesis level */
- int line_number; /* current line number */
- int manual_feed; /* manual feed page count */
- int numcol; /* number of text columns */
- COORDINATE outline; /* page and column outline linewidth */
- int page_flag; /* page number location flag */
- COORDINATE page_height; /* page height in QSU */
- int page_number; /* current page number */
- long page_table[MAXPAGE+1]; /* page location table (with space */
- /* for extra entry marking EOF) */
- char timestr[27]; /* result of ctime() */
- long timeval; /* result of time() */
-
- COORDINATE page_width; /* page width in QSU */
- COORDINATE point_size; /* font point size in big points */
- BOOLEAN reverse; /* page reversal flag */
- COORDINATE right_margin; /* right margin in QSU */
- BOOLEAN scribe; /* recognize bold/italic sequences */
- COORDINATE top_margin; /* top margin in QSU */
- COORDINATE x; /* current horizontal coordinate */
- COORDINATE y; /* current vertical coordinate */
-
- /***********************************************************************
- Built-in PostScript font tables. The first column in each list contains
- the full (case sensitive) PostScript names, the second column contains
- convenient short abbreviations which can be used in the command line
- -ffontname option, the third and fourth columns contain ditroff and
- Adobe TranScript abbreviations.
-
- The first four lines of entries are available on the regular
- LaserWriter, and the remainder are available only on the LaserWriter
- Plus.
- ***********************************************************************/
-
- char* ps_normal[] =
- {
- /* fullname short ditroff TranScript */
- "Courier", "C", "C", "C",
- "Helvetica", "H", "he", "he",
- "Times-Roman", "T", "R", "ti",
- "Symbol", "S", "S", "S",
- "AvantGarde-Book", "AGB", "ag", "ag",
- "AvantGarde-Demi", "AGD", "Ag", "Ag",
- "Bookman-Demi", "BD", "Bo", "Bo",
- "Bookman-Light", "BL", "bo", "bo",
- "Helvetica-Narrow", "HN", "hn", "hn",
- "NewCenturySchlbk-Roman", "NCSR", "nc", "nc",
- "Palatino-Roman", "PR", "pa", "pa",
- "ZapfChancery-MediumItalic", "ZCMI", "ZC", "ZC",
- "ZapfDingbats", "ZD", "ZD", "ZD"
- };
-
- char* ps_bold[] =
- {
- /* fullname short ditroff TranScript */
- "Courier-Bold", "CB", "CB", "CB",
- "Helvetica-Bold", "HB", "He", "He",
- "Times-Bold", "TB", "B", "Ti",
- "Symbol", "S", "S", "S",
- "AvantGarde-Book", "AGB", "ag", "ag",
- "AvantGarde-Demi", "AGD", "Ag", "Ag",
- "Bookman-Demi", "BD", "Bo", "Bo",
- "Bookman-Light", "BL", "bo", "bo",
- "Helvetica-Narrow-Bold", "HNB", "Hn", "Hn",
- "NewCenturySchlbk-Bold", "NCSB", "Nc", "Nc",
- "Palatino-Bold", "PB", "Pa", "Pa",
- "ZapfChancery-MediumItalic", "ZCMI", "ZC", "ZC",
- "ZapfDingbats", "ZD", "ZD", "ZD"
- };
-
- char* ps_italic[] =
- {
- /* fullname short ditroff TranScript */
- "Courier-Oblique", "CO", "CO", "CO",
- "Helvetica-Oblique", "HO", "hE", "hE",
- "Times-Italic", "TI", "I", "tI",
- "Symbol", "S", "S", "S",
- "AvantGarde-BookOblique", "AGBO", "aG", "aG",
- "AvantGarde-DemiOblique", "AGDO", "AG", "AG",
- "Bookman-DemiItalic", "BDI", "BO", "BO",
- "Bookman-LightItalic", "BLI", "bO", "bO",
- "Helvetica-Narrow-Oblique", "HNO", "hN", "hN",
- "NewCenturySchlbk-Italic", "NCSI", "nC", "nC",
- "Palatino-Italic", "PI", "pA", "pA",
- "ZapfChancery-MediumItalic", "ZCMI", "ZC", "ZC",
- "ZapfDingbats", "ZD", "ZD", "ZD"
- };
-
- char* ps_both[] =
- {
- /* fullname short ditroff TranScript */
- "Courier-BoldOblique", "CBO", "CD", "CD",
- "Helvetica-BoldOblique", "HBO", "HE", "HE",
- "Times-BoldItalic", "TBI", "BI", "TI",
- "Symbol", "S", "S", "S",
- "AvantGarde-BookOblique", "AGBO", "aG", "aG",
- "AvantGarde-DemiOblique", "AGDO", "AG", "AG",
- "Bookman-DemiItalic", "BDI", "BO", "BO",
- "Bookman-LightItalic", "BLI", "bO", "bO",
- "Helvetica-Narrow-BoldOblique", "HNBO", "HN", "HN",
- "NewCenturySchlbk-BoldItalic", "NCSBI","NC", "NC",
- "Palatino-BoldItalic", "PBI", "PA", "PA",
- "ZapfChancery-MediumItalic", "ZCMI", "ZC", "ZC",
- "ZapfDingbats", "ZD", "ZD", "ZD"
- };
-
-
- #define PS_DEFAULT 0 /* index of default font in ps_normal[] */
- #define MAXFONT (sizeof(ps_normal)/sizeof(char *)) /* size of font table */
-
-
- int
- main(argc,argv)
- int argc;
- char* argv[];
- {
- register int k; /* loop index */
- register char *p; /* temporary pointer */
- register int m,n; /* loop indices */
- FILE *fp; /* input file pointer */
- long last,next; /* result of fseek() for */
- /* page_table[] construction */
- int (*compare)();
-
- /* establish defaults for all parameters */
- bottom_margin = 1L * QSU;
- column = 1;
- col_margin = 0L;
- copies = 1;
- do_headerfooter = FALSE;
- do_page_number = FALSE;
- init_page_number = 1;
- init_top_margin = -1; /* negative value flags unset state */
- in_col = 0;
- landscape_mode = FALSE;
- left_margin = 1L * QSU;
- manual_feed = 0;
- numcol = 1;
- outline = 0L;
- page_height = HEIGHT;
- page_width = WIDTH;
- point_size = INCH_TO_QSU(inch("10bp"));
- reverse = TRUE;
- right_margin = 1L * QSU;
- scribe = FALSE;
- top_margin = 1L * QSU;
-
- strcpy(font_name,ps_normal[PS_DEFAULT]);
- strcpy(font_bold,ps_bold[PS_DEFAULT]);
- strcpy(font_italic,ps_italic[PS_DEFAULT]);
-
- bad_option = FALSE;
- for (k = 1; k < argc; ++k)
- {
- p = argv[k];
- if (argv[k][0] == '-')
- {
- switch(argv[k][1])
- {
- case 'a':
- case 'A':
- scribe = TRUE;
- break;
-
- case 'b':
- case 'B':
- bottom_margin = INCH_TO_QSU(inch(&argv[k][2]));
- break;
-
- case 'c':
- case 'C':
- copies = atoi(&argv[k][2]);
- break;
-
- case 'd':
- case 'D':
- Head_Foot_Switch(&argv[k][1]);
- break;
-
- case 'f':
- case 'F':
- (void)strncpy(font_name,&argv[k][2],MAXLEN);
- font_name[MAXLEN] = '\0';
- found = FALSE;
- for (n = 0; n < MAXFONT; n += 4)
- {
- for (m = 3; m >= 0; --m)
- {
- /* compare case-sensitive ditroff and TranScript
- names before case-insensitive ones */
- compare = (m > 1) ? strcmp : strcm2;
- if ((*compare)(font_name,ps_normal[n+m]) == 0)
- {
- strcpy(font_name,ps_normal[n]);
- strcpy(font_bold,ps_bold[n]);
- strcpy(font_italic,ps_italic[n]);
- found = TRUE;
- break;
- }
- else if ((*compare)(font_name,ps_bold[n+m]) == 0)
- {
- strcpy(font_name,ps_bold[n]);
- strcpy(font_bold,ps_bold[n]);
- strcpy(font_italic,ps_italic[n]);
- found = TRUE;
- break;
- }
- else if ((*compare)(font_name,ps_italic[n+m]) == 0)
- {
- strcpy(font_name,ps_italic[n]);
- strcpy(font_bold,ps_both[n]);
- strcpy(font_italic,ps_normal[n]);
- found = TRUE;
- break;
- }
- else if ((*compare)(font_name,ps_both[n+m]) == 0)
- {
- strcpy(font_name,ps_both[n]);
- strcpy(font_bold,ps_italic[n]);
- strcpy(font_italic,ps_normal[n]);
- found = TRUE;
- break;
- }
- }
- }
- if (!found)
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "?Illegal font name [%s]. Possible values are:",
- font_name);
- NEWLINE(stderr);
-
- NEWLINE(stderr);
- (void)fprintf(stderr,"Normal fonts");
- NEWLINE(stderr);
- for (m = 0; m < MAXFONT; m += 4)
- {
- (void)fprintf(stderr,"\t%-30s %-10s %-10s %-10s",
- ps_normal[m],ps_normal[m+1],ps_normal[m+2],
- ps_normal[m+3]);
- NEWLINE(stderr);
- }
-
- NEWLINE(stderr);
- (void)fprintf(stderr,"Bold fonts");
- NEWLINE(stderr);
- for (m = 0; m < MAXFONT; m += 4)
- {
- (void)fprintf(stderr,"\t%-30s %-10s %-10s %-10s",
- ps_bold[m],ps_bold[m+1],ps_bold[m+2],
- ps_bold[m+3]);
- NEWLINE(stderr);
- }
-
- NEWLINE(stderr);
- (void)fprintf(stderr,"Oblique/Italic fonts");
- NEWLINE(stderr);
- for (m = 0; m < MAXFONT; m += 4)
- {
- (void)fprintf(stderr,"\t%-30s %-10s %-10s %-10s",
- ps_italic[m],ps_italic[m+1],ps_italic[m+2],
- ps_italic[m+3]);
- NEWLINE(stderr);
- }
-
- NEWLINE(stderr);
- (void)fprintf(stderr,"BoldOblique/BoldItalic fonts");
- NEWLINE(stderr);
- for (m = 0; m < MAXFONT; m += 4)
- {
- (void)fprintf(stderr,"\t%-30s %-10s %-10s %-10s",
- ps_both[m],ps_both[m+1],ps_both[m+2],
- ps_both[m+3]);
- NEWLINE(stderr);
- }
- NEWLINE(stderr);
- bad_option = TRUE;
- }
- break;
-
- case 'h':
- case 'H':
- landscape_mode = TRUE;
- break;
-
- case 'i':
- case 'I':
- init_top_margin = INCH_TO_QSU(inch(&argv[k][2]));
- break;
-
- case 'l':
- case 'L':
- left_margin = INCH_TO_QSU(inch(&argv[k][2]));
- break;
-
- case 'm':
- case 'M':
- numcol = atoi(&argv[k][2]);
- break;
-
- case 'n':
- case 'N':
- Page_Switch(&argv[k][1]);
- break;
-
- case 'o':
- case 'O':
- if (argv[k][2]) /* have -O# */
- outline = INCH_TO_QSU(inch(&argv[k][2]));
- else /* have -O, so give default */
- outline = INCH_TO_QSU(inch("0.4pt")); /* from TeX */
- break;
-
- case 'p':
- case 'P':
- point_size = INCH_TO_QSU(inch(&argv[k][2]));
- break;
-
- case 'r':
- case 'R':
- right_margin = INCH_TO_QSU(inch(&argv[k][2]));
- break;
-
- case 's':
- case 'S':
- if (argv[k][2]) /* have count field */
- manual_feed = atoi(&argv[k][2]);
- else /* omitted count ==> large number */
- manual_feed = 32767;
- break;
-
- case 't':
- case 'T':
- top_margin = INCH_TO_QSU(inch(&argv[k][2]));
- break;
-
- case 'u':
- case 'U':
- reverse = FALSE;
- break;
-
- default:
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Unrecognized option [%s]",p);
- NEWLINE(stderr);
- bad_option = TRUE;
- }
- }
- else
- {
- if(!filename)
- {
- filename = argv[k];
- }
- }
- }
-
- page_number = init_page_number;
-
- if (bad_option)
- {
- (void)fprintf(stderr,
- "Usage: %s -A -B# -Cn -Ffontname -H -I# -L# -Mn -N[tb][lcr]n \
- -O[#] -P# -R# -S[n] -T# -U filelist >outfile",argv[0]);
- NEWLINE(stderr);
-
- (void)fprintf(stderr,"Default options: -B1.0in -C1 -FCourier -L1.0in \
- -M1 -P10bp -R1.0in -S0 -T1.0in");
- NEWLINE(stderr);
-
- EXIT(1);
- }
-
-
- if (reverse)
- {
- if ((tf = fopen(TEMPFILE,FOPEN_W)) == (FILE *)NULL)
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Cannot open temporary file [%s]",TEMPFILE);
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
- }
- else
- tf = stdout;
-
- /*******************************************************************
- Make the PostScript File Structure header according to Version 1.0,
- First Edition (January 1985) of the PostScript File Structuring
- Conventions manual. We add one additional field at the end after
- the %%Pages: n field:
-
- %%PageTable: m1 n1 p1 ... mk nk pk
-
- where the triples (mj nj pj) contain the page number pair (mj nj)
- like the field
-
- %%Page: mj nj
-
- and pj is the byte position in the file of the beginning of that
- "%%Page" command. A spooler can then easily position to arbitrary
- pages in the file for reprinting.
- *******************************************************************/
-
- OUTSTR("%!PS-Adobe-1.0"); /* magical file header */
- NEWLINE(tf);
-
- OUTSTR("%%DocumentFonts: ");
- OUTSTR(font_name); /* only use one font */
- NEWLINE(tf);
-
- OUTSTR("%%Dimensions: 0 0 612 792"); /* 8.5 x 11 inch page size */
- NEWLINE(tf);
-
- OUTSTR("%%Title:"); /* this contains our command line */
- for (k = 0; k < argc; ++k)
- {
- OUTCHAR(' ');
- OUTSTR(argv[k]);
- }
- NEWLINE(tf); /* end of %%Title line */
-
- timeval = time((long *)NULL);
- strcpy(timestr,ctime(&timeval));
- k = strlen(timestr) - 1; /* ctime has its own \n */
- timestr[k] = NUL; /* so kill it */
- OUTSTR("%%CreationDate: ");
- OUTSTR(timestr);
- NEWLINE(tf);
-
- /* Under TOPS-20, JSYS GFUST% cannot be used to obtain file owner string
- of a terminal file, which stdout always is, so just use job login name */
-
- OUTSTR("%%Creator: ");
- #ifndef OS_AMIGA
- if (cuserid((char*)NULL) != (char*)NULL)
- OUTSTR(cuserid((char*)NULL));
- #else
- OUTSTR("lptops (Amiga version - 12/22/89)");
- #endif
- NEWLINE(tf);
-
- OUTSTR("%%Pages: (atend)");
- NEWLINE(tf);
- OUTSTR("%%EndComments");
- NEWLINE(tf);
- OUTSTR("save"); /* has matching "restore" at end */
- NEWLINE(tf);
- OUTSTR("%%EndProlog");
- NEWLINE(tf);
-
- /* validate input settings */
- copies = MAX(1,copies);
- numcol = MAX(1,numcol);
- point_size = MAX(INCH_TO_QSU(inch("3bp")),point_size);
- if (point_size > INCH_TO_QSU(0.25))
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "%warning -- font point size > 18pt is unusually large!");
- NEWLINE(stderr);
- }
- outline = MAX(0L,outline);
-
- if (landscape_mode) /* switch sizes for landscape mode */
- {
- page_height = WIDTH;
- page_width = HEIGHT;
- }
- if (((left_margin + right_margin) >= page_width) ||
- ((top_margin + bottom_margin) >= page_height) ||
- ((init_top_margin + bottom_margin) >= page_height))
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Margin values too large for page");
- NEWLINE(stderr);
- EXIT(1);
- }
-
- col_width = (page_width - left_margin - right_margin)/numcol;
- col_margin = ((numcol == 1) && (outline == 0)) ?
- 0L : (col_width/COL_TWIDDLE);
-
- /* TeX's baselineskip is 12pt for 10pt type; we preserve the same ratio */
- baseline_skip = (point_size * 12L) / 10L;
-
- m = 0; /* count of file names */
- for (k = 1; k < argc; ++k)
- {
- if (*argv[k] != '-')
- {
- m++; /* count file name */
- if ((fp = fopen(argv[k],FOPEN_R)) != (FILE *)NULL)
- {
- Do_File(fp);
- (void)fclose(fp);
- }
- else
- {
- (void)fprintf(stderr,"?Open failure on [%s] -- file skipped",
- argv[k]);
- NEWLINE(stderr);
- }
- }
- }
- if (m == 0)
- Do_File(stdin);
-
- if (reverse)
- {
- /* Now close the temporary file and reopen for input, then transfer */
- /* complete pages in reverse order to stdout using large blocks */
-
- if (fclose(tf))
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Close failure on temporary file [%s]",
- TEMPFILE);
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
-
- if ((tf = fopen(TEMPFILE,FOPEN_R)) == (FILE *)NULL)
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Cannot reopen temporary file [%s]",TEMPFILE);
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
-
- NEWLINE(stderr);
- (void)fprintf(stderr,"[Reversing pages");
- Copy_Block(0L,page_table[0]-1); /* first page is file header stuff */
- last = page_table[MIN(MAXPAGE,page_number-init_page_number+1)];
- for (k = MIN(MAXPAGE,page_number-init_page_number+1)-1; k >= 0; --k)
- { /* copy remainder in reverse order */
- (void)putc('.',stderr);
- next = (long)ftell(stdout);
- Copy_Block(page_table[k],last-1);
- last = page_table[k];
- page_table[k] = next;
- }
- (void)putc(']',stderr);
- if (fclose(tf))
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Close failure on temporary file [%s]",
- TEMPFILE);
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
-
- unlink(TEMPFILE); /* delete the temporary file */
- }
- /* add file trailer stuff */
-
- tf = stdout; /* so OUTSTR() macro works */
-
- OUTSTR("%%Trailer");
- NEWLINE(stdout);
- OUTSTR("restore"); /* matches "save" in prolog */
- NEWLINE(stdout);
- (void)printf("%%%%Pages: %d",page_number-init_page_number);
- NEWLINE(stdout);
- OUTSTR("%%PageTable: ");
- for (k = 0; k < MIN(MAXPAGE,page_number-init_page_number+1); ++k)
- (void)printf(" %d %d %ld",init_page_number+k,init_page_number+k,
- page_table[k]);
- NEWLINE(stdout);
- if (putchar('\004') == EOF) /* CTL-D for EOF signal */
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Output error -- disk storage probably full");
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
- (void)fprintf(stderr," [ok]");
- NEWLINE(stderr);
- EXIT(0);
- return (0); /* keep lint and compilers happy */
- }
-
- void
- Beg_Column()
- {
- (void)fprintf(tf,"%ld %ld moveto",x,y);
- NEWLINE(tf);
- }
-
- void
- Beg_Line()
- {
- if (scribe)
- {
- OUTCHAR('S');
- OUTCHAR(' ');
- }
- }
-
- void
- Beg_Page()
- {
- int k;
-
- column = 1;
- (void)fflush(tf);
- k = page_number-init_page_number;
- if (k < MAXPAGE)
- page_table[k] = (long)ftell(tf);
- (void)fprintf(tf,"%%%%Page: %d %d",k+1,page_number);
- NEWLINE(tf);
- OUTSTR("save"); /* will be matched by "restore" from End_Page() */
- NEWLINE(tf);
- if (scribe)
- {
- (void)fprintf(tf,"/B {/%s findfont %ld scalefont setfont} def",
- font_bold,point_size);
- NEWLINE(tf);
-
- (void)fprintf(tf,"/E {grestore 0 %ld rmoveto} def",
- -baseline_skip); /* End of line */
- NEWLINE(tf);
-
- (void)fprintf(tf,"/I {/%s findfont %ld scalefont setfont} def",
- font_italic,point_size);
- NEWLINE(tf);
-
- (void)fprintf(tf,"/N {/%s findfont %ld scalefont setfont} def",
- font_name,point_size);
- NEWLINE(tf);
-
- OUTSTR("/O {gsave show grestore} def"); /* OverPrint macro */
- NEWLINE(tf);
-
- OUTSTR("/S {gsave} def"); /* Start of line */
- NEWLINE(tf);
-
- OUTSTR("/W {show} def"); /* show text */
- NEWLINE(tf);
- }
- else
- {
- OUTSTR("/O {gsave show grestore} def"); /* OverPrint macro */
- NEWLINE(tf);
-
- (void)fprintf(tf,"/P {gsave show grestore 0 %ld rmoveto} def",
- -baseline_skip); /* Print macro */
- NEWLINE(tf);
-
- (void)fprintf(tf,"/N {/%s findfont %ld scalefont setfont} def",
- font_name,point_size);
- NEWLINE(tf);
- }
- (void)fprintf(tf,"72 %ld div 72 %ld div scale",QSU,QSU);
- NEWLINE(tf);
- OUTCHAR('N'); /* select normal font */
-
- #if FIX31OCT85
- OUTSTR("()pop"); /* no-op for XON/XOFF bug workaround */
- #endif
-
- NEWLINE(tf);
-
- if (landscape_mode)
- {
- (void)fprintf(tf,"%ld %ld translate",0L,HEIGHT);
- NEWLINE(tf);
- OUTSTR("-90 rotate");
- NEWLINE(tf);
- }
- (void)fprintf(stderr,
- " [%d",page_number); /* begin [p.l.l...] status report */
- }
-
- void
- Beg_Text(c)
- char c;
- {
- if (c)
- {
- OUTCHAR(' ');
- OUTCHAR(c);
- OUTCHAR(' ');
- }
- OUTCHAR('(');
- level++;
- }
-
- void
- Copy_Block(b1,b2) /* copy bytes b1..b2 from tf to stdout */
- long b1,b2; /* start,end byte positions */
- {
- static char block[MAXBLOCK]; /* static to save stack space */
- long k; /* loop index */
- long length; /* number of bytes to copy */
-
- #if FASTIO
- (void)fflush(stdout); /* empty any buffered output */
- #endif
- for (k = b1; k <= b2; k += MAXBLOCK)
- {
- length = MIN(MAXBLOCK,b2-k+1);
-
- (void)fseek(tf,k,0); /* position to desired block */
-
- #if FASTIO
- if (_read(jfnof(fileno(tf)),block,(int)length) != (int)length)
- #else
- if (fread(block,1,(int)length,tf) != (int)length)
- #endif
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "?Input block length error on temporary file [%s]",TEMPFILE);
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
- #if FASTIO
- if (_write(jfnof(fileno(stdout)),block,(int)length) != (int)length)
- #else
- if (fwrite(block,1,(int)length,stdout) != (int)length)
- #endif
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "?Output block length error on stdout");
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
- }
- (void)fflush(stdout);
- }
-
- void
- Copy_Plist(fontc,fp) /* copy parenthesized list to tf */
- char fontc;
- FILE *fp;
- {
- static char p_open[] = {'(','[','<','{',NUL};
- static char p_close[] = {')',']','>','}',NUL};
- register int match;
- register int c;
-
- c = inchar(fp);
- match = 0;
- while (p_open[match] && (p_open[match] != (char)c))
- match++;
-
- if (!p_open[match])
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?@b or @i not followed by open parenthesis!");
- NEWLINE(stderr);
- EXIT(1);
- }
-
- Beg_Text(fontc);
- while (((c = inchar(fp)) != EOF) && ((char)c != p_close[match]))
- {
- if (c < ' ')
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "?@b[...] or @i[...] contains control character!");
- NEWLINE(stderr);
- EXIT(1);
- }
- in_col++;
- switch(c)
- {
- case '(':
- OUTCHAR('\\');
- OUTCHAR(c);
- break;
-
- case ')':
- OUTCHAR('\\');
- OUTCHAR(c);
- break;
-
- case '\\':
- OUTCHAR('\\');
- OUTCHAR(c);
- break;
-
- default:
- OUTCHAR(c);
- break;
- }
- }
- End_Text('N');
- OUTCHAR(' ');
- }
-
- void
- Do_File(fp)
- FILE *fp;
- {
- register int c; /* character */
-
- /**********************************************************************/
- /* PostScript Output Section */
- /**********************************************************************/
-
- x = LEFT_X;
- if (init_top_margin > 0)
- y = TOP_Y(init_top_margin);
- else
- y = TOP_Y(top_margin);
-
- Beg_Page();
- Beg_Column();
- level = 0;
- in_col = 0;
- line_number = 1;
-
- if ((c = inchar(fp)) != '\f') /* discard any initial FF */
- (void)ungetc(c,fp);
-
- while ((c = inchar(fp)) != EOF)
- {
- switch (c)
- {
- case NUL:
- break; /* discard NUL's from word-padded files */
-
- case '\b':
- if (in_col > 0)
- {
- in_col--;
- OUTCHAR('\\');
- OUTCHAR('b');
- }
- break;
-
- case '\f':
- in_col = 0;
- End_Text(NUL);
- NEWLINE(tf);
- End_Column();
- if (column > numcol)
- Beg_Page();
- Beg_Column();
- line_number = 1;
- break;
-
- case '\n':
- line_number++;
- if (in_col == 0)
- {
- Beg_Line();
- Beg_Text(NUL);
- }
- End_Text(NUL);
- End_Line();
- in_col = 0;
- y -= baseline_skip;
- if (y < BOT_Y)
- {
- End_Column();
- if (column > numcol)
- Beg_Page();
- Beg_Column();
- line_number = 1;
- }
- break;
-
-
- case '\r': /* check for special case of overprinting */
- if ((c = inchar(fp)) != '\n') /* peek ahead one character */
- { /* and if not LF, have overstrike */
- while (level > 0)
- {
- OUTCHAR(')');
- level--;
- }
- in_col = 0;
- OUTCHAR('O');
- NEWLINE(tf); /* this lines up under previous line */
- }
- (void)ungetc(c,fp); /* put back the peeked-at character */
- break;
-
- case '\t':
- if (in_col == 0)
- {
- Beg_Line();
- Beg_Text(NUL);
- }
- do
- {
- in_col++;
- OUTCHAR(' ');
- }
- while (in_col & 07); /* blank fill to multiple of 8 columns */
- break;
-
- case '(':
- if (in_col == 0)
- {
- Beg_Line();
- Beg_Text(NUL);
- }
- in_col++;
- OUTCHAR('\\');
- OUTCHAR('(');
- break;
-
- case ')':
- if (in_col == 0)
- {
- Beg_Line();
- Beg_Text(NUL);
- }
- in_col++;
- OUTCHAR('\\');
- OUTCHAR(')');
- break;
-
- case '\\':
- if (in_col == 0)
- {
- Beg_Line();
- Beg_Text(NUL);
- }
- in_col++;
- OUTCHAR('\\');
- OUTCHAR('\\');
- break;
-
- case '@':
- if (scribe)
- {
- c = inchar(fp);
- if ((c == 'b') || (c == 'B'))
- {
- if (in_col == 0)
- Beg_Line();
- else
- End_Text(NUL);
- Copy_Plist('B',fp);
- Beg_Text(NUL);
- break;
- }
- else if ((c == 'i') || (c == 'I'))
- {
- if (in_col == 0)
- Beg_Line();
- else
- End_Text(NUL);
- Copy_Plist('I',fp);
- Beg_Text(NUL);
- break;
- }
- (void)ungetc(c,fp); /* put back the peeked-at character */
- c = (int)'@'; /* and restore original character */
- }
- /* ELSE fall through to default! */
-
- default:
- if (in_col == 0)
- {
- Beg_Line();
- Beg_Text(NUL);
- }
- in_col++;
- if ((c < 040) || (0176 < c))
- OUTOCTAL(c);
- else
- OUTCHAR(c);
- break;
- }
- }
- if (in_col > 0)
- End_Line();
- End_Text(NUL);
- column = numcol; /* to force End_Page() action */
- End_Column();
-
- /* Normally, Beg_Page() sets the page_table[] entry. Since this is
- the last output for this file, we must set it here manually. If
- more files are printed, this entry will be overwritten (with the
- same value) at the next call to Beg_Page(). */
- page_table[page_number-init_page_number] = (long)ftell(tf);
- }
-
- void
- End_Column()
- {
- if (outline > 0)
- {
- NEWLINE(tf);
- OUTSTR("gsave");
- NEWLINE(tf);
- (void)fprintf(tf,"%ld setlinewidth",outline);
- NEWLINE(tf);
- (void)fprintf(tf,"newpath %ld %ld moveto",x - col_margin,bottom_margin);
- (void)fprintf(tf,
- " %ld %ld rlineto %ld %ld rlineto %ld %ld rlineto closepath stroke",
- col_width,0,
- 0,page_height-bottom_margin-top_margin,
- -col_width,0);
- NEWLINE(tf);
- OUTSTR("grestore");
- NEWLINE(tf);
- }
- (void)fprintf(stderr,
- ".%d",line_number); /* continue [p.l.l...] status report */
- if (++column > numcol) /* columns filled, so start new page */
- {
- (void)putc(']',stderr); /* close [p.l.l...] report */
- End_Page();
- }
- else /* just start new column */
- {
- x += col_width;
- y = TOP_Y(top_margin);
- }
- }
-
- void
- End_Page()
- {
- register int k;
-
- if(do_headerfooter)
- {
- if((init_top_margin > 0) && (page_number == init_page_number)
- && (page_flag | PAGE_T)); /* omit leading top pagenumber */
- else
- switch (page_flag)
- {
- case (PAGE_T | PAGE_C):
- (void)fprintf(tf,"%ld %ld moveto",left_margin,
- page_height-top_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%s) show",timestr);
- NEWLINE(tf);
- (void)fprintf(tf,"%ld %ld moveto",page_width/2,
- page_height-top_margin/2-baseline_skip/2);
- (void)fprintf(tf,
- " (%s) stringwidth pop 2 div neg 0 rmoveto",
- filename);
- (void)fprintf(tf," (%s) show",filename);
- NEWLINE(tf);
- (void)fprintf(tf,"%ld %ld moveto",page_width-left_margin,
- page_height-top_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%d) stringwidth pop neg 0 rmoveto",
- page_number);
- (void)fprintf(tf," (%d) show",page_number);
- NEWLINE(tf);
- break;
-
- case (PAGE_B | PAGE_C):
- (void)fprintf(tf,"%ld %ld moveto",left_margin,
- bottom_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%s) show",timestr);
- NEWLINE(tf);
- (void)fprintf(tf,"%ld %ld moveto",page_width/2,
- bottom_margin/2-baseline_skip/2);
- (void)fprintf(tf,
- " (%s) stringwidth pop 2 div neg 0 rmoveto",
- filename);
- (void)fprintf(tf," (%s) show",filename);
- NEWLINE(tf);
- (void)fprintf(tf,"%ld %ld moveto",page_width-left_margin,
- bottom_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%d) stringwidth pop neg 0 rmoveto",
- page_number);
- (void)fprintf(tf," (%d) show",page_number);
- NEWLINE(tf);
- break;
-
- default:
- break;
- }
- }
- else if (do_page_number)
- {
- if ((init_top_margin > 0) && (page_number == init_page_number)
- && (page_flag | PAGE_T))
- ; /* omit leading top pagenumber */
- else
- switch (page_flag)
- {
- case (PAGE_T | PAGE_L):
- (void)fprintf(tf,"%ld %ld moveto",left_margin,
- page_height-top_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%d) show",page_number);
- NEWLINE(tf);
- break;
-
- case (PAGE_T | PAGE_C):
- (void)fprintf(tf,"%ld %ld moveto",page_width/2,
- page_height-top_margin/2-baseline_skip/2);
- (void)fprintf(tf,
- " (- %d -) stringwidth pop 2 div neg 0 rmoveto",
- page_number);
- (void)fprintf(tf," (- %d -) show",page_number);
- NEWLINE(tf);
- break;
-
- case (PAGE_T | PAGE_R):
- (void)fprintf(tf,"%ld %ld moveto",page_width-left_margin,
- page_height-top_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%d) stringwidth pop neg 0 rmoveto",
- page_number);
- (void)fprintf(tf," (%d) show",page_number);
- NEWLINE(tf);
- break;
-
- case (PAGE_B | PAGE_L):
- (void)fprintf(tf,"%ld %ld moveto",left_margin,
- bottom_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%d) show",page_number);
- NEWLINE(tf);
- break;
-
- case (PAGE_B | PAGE_C):
- (void)fprintf(tf,"%ld %ld moveto",page_width/2,
- bottom_margin/2-baseline_skip/2);
- (void)fprintf(tf,
- " (- %d -) stringwidth pop 2 div neg 0 rmoveto",
- page_number);
- (void)fprintf(tf," (- %d -) show",page_number);
- NEWLINE(tf);
- break;
-
- case (PAGE_B | PAGE_R):
- (void)fprintf(tf,"%ld %ld moveto",page_width-left_margin,
- bottom_margin/2-baseline_skip/2);
- (void)fprintf(tf," (%d) stringwidth pop neg 0 rmoveto",
- page_number);
- (void)fprintf(tf," (%d) show",page_number);
- NEWLINE(tf);
- break;
-
- default: /* else no numbering */
- break;
- }
- }
- page_number++;
-
- if (manual_feed > 0)
- {
- OUTSTR("statusdict begin");
- NEWLINE(tf);
- OUTSTR("statusdict /manualfeed true put");
- NEWLINE(tf);
- }
-
- if ((fprintf(tf,"/#copies %d def showpage",copies) == EOF) ||
- DISKFULL(tf))
- {
- NEWLINE(stderr);
- (void)fprintf(stderr,"?Output error -- disk storage probably full");
- NEWLINE(stderr);
- (void)perror("?perror() says");
- EXIT(1);
- }
- NEWLINE(tf);
-
- if (manual_feed > 0)
- {
- OUTSTR("end");
- NEWLINE(tf);
- }
- manual_feed--;
-
- OUTSTR("restore");
- NEWLINE(tf);
-
- for (k = 1; k <= copies; ++k)
- OUTCHAR('\f'); /* output FF's for print spooler page accounting */
-
- x = LEFT_X;
- y = TOP_Y(top_margin);
- }
-
- void
- End_Line()
- {
- if (scribe)
- {
- OUTCHAR(' ');
- OUTCHAR('E');
- }
- NEWLINE(tf);
- }
-
-
- void
- End_Text(c)
- char c;
- {
- register int k;
-
- k = level;
- while (level > 0)
- {
- OUTCHAR(')');
- level--;
- }
- if (k > 0)
- {
- if (scribe)
- OUTCHAR('W');
- else
- OUTCHAR('P');
- }
- if (c)
- {
- OUTCHAR(' ');
- OUTCHAR(c);
- }
- }
-
- #include "inch.h"
-
- int
- inchar(fp)
- FILE *fp;
- {
- static int lastc = NUL; /* memory of previous input character */
- register int c;
-
- /* output is incorrect if the file does not end with a LF; this
- routine supplies one at EOF if it is lacking */
-
- c = getc(fp);
- if ((c == EOF) && (lastc != '\n'))
- c = '\n';
- lastc = c;
- return (c);
- }
-
- void
- Head_Foot_Switch(parg) /* parg -> "Dxnnn" */
- register char *parg;
- {
- register char *porg;
-
- porg = parg;
- do_headerfooter = TRUE;
- do_page_number = FALSE;
- init_page_number = 1;
- page_flag = (PAGE_T | PAGE_C); /* default location */
- while (*++parg)
- {
- switch(*parg)
- {
- case 't':
- case 'T':
- page_flag &= ~(PAGE_B | PAGE_T);
- page_flag |= PAGE_T;
- break;
-
- case 'b':
- case 'B':
- page_flag &= ~(PAGE_B | PAGE_T);
- page_flag |= PAGE_B;
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- init_page_number = atoi(parg);
- while (isdigit(*parg))
- ++parg;
- if (*parg == NUL)
- break;
- /* else fall through to error exit */
- default: /* else fall through to error exit */
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "?Unrecognized header, footer option [%s]",porg);
- NEWLINE(stderr);
- EXIT(1);
- }
- if (*parg == NUL)
- break;
- }
- }
-
- void
- Page_Switch(parg) /* parg -> "Nxxxnnn" */
- register char *parg;
- {
- register char *porg;
-
- porg = parg;
- do_headerfooter = FALSE;
- do_page_number = TRUE;
- init_page_number = 1;
- page_flag = (PAGE_T | PAGE_C); /* default location */
- while (*++parg)
- {
- switch(*parg)
- {
- case 't':
- case 'T':
- page_flag &= ~(PAGE_B | PAGE_T);
- page_flag |= PAGE_T;
- break;
-
- case 'b':
- case 'B':
- page_flag &= ~(PAGE_B | PAGE_T);
- page_flag |= PAGE_B;
- break;
-
- case 'l':
- case 'L':
- page_flag &= ~(PAGE_L | PAGE_C | PAGE_R);
- page_flag |= PAGE_L;
- break;
-
- case 'c':
- case 'C':
- page_flag &= ~(PAGE_L | PAGE_C | PAGE_R);
- page_flag |= PAGE_C;
- break;
-
- case 'r':
- case 'R':
- page_flag &= ~(PAGE_L | PAGE_C | PAGE_R);
- page_flag |= PAGE_R;
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- init_page_number = atoi(parg);
- while (isdigit(*parg))
- ++parg;
- if (*parg == NUL)
- break;
- /* else fall through to error exit */
- default:
- NEWLINE(stderr);
- (void)fprintf(stderr,
- "?Unrecognized page number field [%s]",porg);
- NEWLINE(stderr);
- EXIT(1);
- }
- if (*parg == NUL)
- break;
- }
- }
-
- #include "strcm2.h"
-