📄 epr.c
字号:
lines = 0;
do {
c = putline (&tl, 1);
/* DBG(fprintf(dfp,"Got %03o\n",c&0377);) */
if (c == LF) { putc(c,ofp); lines++; }
} while (c != EOH);
return (lines);
}
#ifdef Dbug
showtl (s)
register char *s;
/*
* Display the text line to be output for debugging.
*/
{
fprintf(dfp,"showtl[");
while (*s) {
if (*s < SP || *s == DEL) fprintf(dfp,"^%c",*s ^ 0100);
else if (*s < DEL) fprintf(dfp,"%c",*s);
else fprintf(dfp,"\\%03o ",*s & 0377);
s++;
}
fprintf(dfp,"]\n");
}
#endif
initialize ()
/*
* Obtains current date and time information and places it in a global
* structure. Establishes default values for formatting options, validates
* them, and if output is to printer, outputs appropriate format information.
* These defaults may be changed to suit individual preferences.
*/
{
timestmp (&timeinfo); /* gets date and time */
/* The Epson FX-80 has three basic pitches: pica (the default),
* elite, and compressed. They are mutually exclusive (but may
* be enabled by seperate commands, in which case elite has
* priority over compressed, which is over pica). All three
* basic pitches may be "expanded", for a total of six pitches.
*
* In addition to the six pitches there are other modes (italic,
* double-strike, emphasized, proportional, and underlined) which
* may be combined with each other and the six pitches in various
* patterns (but not arbitrarily).
*
* Since the FX-80 has a printing width of 8.0 inches, the following
* table gives the number of characters per line in each of the
* six pitches (it doesn't apply when proportional mode is turned on,
* of course):
*
* Basic Pitch Expanded? Chars/Line
* ----------- --------- ----------
* pica no 80
* elite no 96
* compressed no 137
* pica yes 40
* elite yes 48
* compressed yes 68
*/
DBG(fprintf(dfp,"Before respmode, pmode = %o, qmode = %o\n",pmode,qmode);)
pmode = respmode(pmode); /* Resolve Epson FX-80 conflicts. */
qmode = respmode(qmode);
DBG(fprintf(dfp,"Resolved pmode = %o, qmode = %o\n",pmode,qmode);)
if (pmode & F_l) {
phycpl = 96;
} else if (pmode & F_c) {
phycpl = 137;
} else {
phycpl = 80;
}
if (pmode & F_e) phycpl = phycpl / 2;
DBG(fprintf(dfp,"Physical characters per line = %d\n",phycpl);)
if (leftmar < 0) leftmar = 0;
if (cpl <= 0) cpl = phycpl - leftmar;
if (nohead) hlines = 0; /* inhibit header */
else formatheader (); /* build actual header string */
phylpp = (space8 ? 88 : 66); /* number lines per 11 inch page */
if (topmar < 0) topmar = 0;
/*
* lpp counts number of actual text lines, top margin, and number of
* lines in header (i.e., everything but bottom margin).
*/
if (lpp <= 0) lpp = phylpp - 5; /* subtract bottom margin */
else lpp += hlines + topmar;
/* Open printer or output file. Unless printer codes have been
* suppressed, output them to condition the printer.
*/
if (outfile[0] == EOS) ofp = stdout; /* use stdout */
else {
ofp = fopen (outfile,"w");
if (ofp == NULL) abort ("Can't open %s for output!",outfile);
}
if (!nopcc) { /* control codes, unless inhibited */
putc(ESC,ofp); putc('O',ofp); /* turn off auto-skip over
* perforation */
/* Page pause also means deselecting out-of-paper detector */
putc(ESC,ofp);
if (pagpaus) putc('8',ofp);
else putc('9',ofp);
}
}
sendpcc(mode)
int mode; /* The mode to use. */
/*
* This routine sends the printer control codes that are set before
* and after each page header (allowing the page header to set different
* values).
*/
{
if (!nopcc) { /* control codes, unless inhibited */
putc(ESC,ofp); /* line spacing, 6 or 8 per inch */
if (space8) putc('0',ofp);
else putc('2',ofp);
putc(ESC,ofp); /* alternate character set */
if (altset) putc('4',ofp);
else putc('5',ofp);
putc(ESC,ofp); /* "master print mode" */
putc('!',ofp);
putc((mode|UPMODE) &0377,ofp);
putc(ESC,ofp); /* underline mode */
putc('-',ofp);
if (mode & F_u) putc('1',ofp);
else putc('0',ofp);
putc(ESC,ofp); /* italic mode */
if (mode & F_i) putc('4',ofp);
else putc('5',ofp);
putc(ESC,ofp); /* Super/sub-script mode */
if (mode & F_t) { /* Superscript mode. */
putc('S',ofp);
putc('0',ofp);
} else if (mode & F_s) { /* Subscript mode. */
putc('S',ofp);
putc('1',ofp);
} else putc('T',ofp); /* Neither. */
putc(ESC,ofp); /* proportional mode */
putc('p',ofp);
if (mode & F_p) putc('1',ofp);
else putc('0',ofp);
/* Select international character set */
putc(ESC,ofp);
putc('R',ofp);
putc(cmode,ofp);
}
}
formatheader ()
/*
* Creates the header format string from the source string in array header.
*/
{
char *s, *h, c;
int v; /* Builds an ASCII character value. */
s = header; /* source string */
h = hformat; /* final format string */
hlines = 0; /* number of newlines in header */
while (c = *s++) { /* Repeat for each character in header. */
switch (c) { /* Dispatch on this character. */
case '%': /* Percent lead-in. */
h += percent (h, *s++);
break;
case '\\': /* Backslash-quoted char. */
c = *s++; /* Get the next char. */
casecvt(c); /* Lower its case. */
switch (c) { /* Dispatch it. */
case '\\': *h++ = '\\'; break;
case 'n': *h++ = '\n'; hlines++; break;
case 't': *h++ = '\t'; break;
case 'r': *h++ = '\r'; break;
case 'b': *h++ = '\b'; break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
v = c - '0'; /* Ugh! ASCII-specific. */
c = *s;
if (isdigit(c)) {
s++;
v = (v * 8) + (c - '0');
c = *s;
if (isdigit(c)) {
s++;
v = (v * 8) + (c - '0');
}
}
*h++ = v;
break;
default: /* Unknown backslashed char. */
*h++ = '\\';
*h++ = c;
}
break;
default: /* Neither backslash nor percent. */
*h++ = c;
}
}
*h++ = '\n'; hlines++;
*h++ = EOH;
*h++ = EOS;
headpf &= 1; /* save only order flag */
}
/*
* Need to keep track of whether %p and %f appear in header, and if
* both do, in which order, so we can pick the right sprintf when
* printing the header.
*/
#define hp_f 02 /* %f seen */
#define hp_p 04 /* %p seen */
percent (h, c)
char c, *h;
/*
* Process one of the special %x options in the header source, where
* c gives the option (char following the %). Returns number of
* chars inserted in h.
*/
{
casecvt(c);
DBG(fprintf(dfp,"percent(%c)\n",c);)
switch (c) {
case ' ': *h = ' '; return (1);
case '%': *h = '%'; return (1);
case 'd': return (getdate (h));
case 't': return (gettime (h));
case 'f':
if (headpf & hp_f) Abort ("%%f given twice in header string");
headpf |= hp_f;
if (headpf & hp_p) headpf |= 1;
*h++ = '%'; *h++ = 's'; return (2);
case 'p':
if (headpf & hp_p) Abort ("%%p given twice in header string");
headpf |= hp_p;
if (!(headpf & hp_f)) headpf |= 1;
*h++ = '%'; *h++ = 'd'; return (2);
default: return (0);
}
}
gettime (s)
char *s;
/*
* Gets current time in the form "hh:mm" and places it in string s.
* Returns number of chars inserted.
*/
{
sprintf (s,"%2d:%02d",timeinfo.tim_hr,timeinfo.tim_min);
return (5);
}
getdate (s)
char *s;
/*
* Gets date in the form "dd mon yyyy" and puts it into string s.
* Returns the length of the string inserted.
*/
{
sprintf (s,"%2d %s %4d",timeinfo.tim_dat,
timemon[timeinfo.tim_mon],timeinfo.tim_yr);
return (11);
}
getline (ifp, s)
FILE *ifp;
register char *s;
/*
* Fills array s with chars from stream ifp. Stops when it reads
* LF, FF, or EOF. Returns the terminator (one of these three)
* but inserts a LF as the last character in s (plus a EOS).
* Does special processing:
* CR LF, CR FF, CR EOF all ignore the CR;
* FF at end of line with no preceding text gets turned into LF FF;
* EOF at end of line with no preceding text gets turned into LF EOF.
* Returns of FF and EOF happen only when they are read at the
* beginning of the line.
*/
{
register int c;
static int firstc = 0;
int n;
if (firstc) { c = firstc; firstc = 0; }
else c = getc(ifp);
/* Skip initial CR's */
while (c == CR) c = getc(ifp);
if (c == EOF || c == FF) return (c);
n = 0; /* use as flag if any text chars seen */
while (c != LF) {
/* DBG(fprintf(dfp,"GET %3o ",c);) */
if (c == CR) {
c = getc(ifp);
/* CR followed by terminator is ignored */
if (c != LF && c != FF && c != EOF) *s++ = CR;
}
if (c == FF || c == EOF) {
/*
* If no text chars have been processed yet, then return c.
* Otherwise, simulate LF and save c for next call.
*/
if (n == 0) return (c);
firstc = c;
c = LF;
}
if (c != LF) { /* Normal text char or LF */
*s++ = c;
n++;
c = getc(ifp); /*next char */
}
}
*s++ = LF;
*s++ = EOS; /* for safety's sake */
return (LF);
}
putline (sp, sflg)
char **sp;
int sflg; /* !=0 ==> pass specials through. */
/*
* Process one line's worth of input, from the string pointed to by sp,
* after printing blanks for the left margin. Stops when termination
* condition met:
* (1) when LF is seen, returns LF;
* (2) when CR is seen, returns CR;
* (3) when EOH is seen (only when printing header), returns EOH;
* (4) when cpl chars have been printed, returns LF.
* Updates sp to point to the next char to be read. Expands tabs into
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -