home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource5
/
331_01
/
roff.c
< prev
next >
Wrap
Text File
|
1990-06-01
|
16KB
|
657 lines
/*
HEADER
*/
/* Reform paragraphs. Dot commands in the text are interpreted and
* left in the result. Adapted from CUG .. 3/15/87 G. Osborn.
*
* All automatic pagination output is suppressed until a .he command
* is processed. The text portion of the .he command may be null.
*
* dot commands to not contribute to the line count if left
* in the output.
*/
#include <ctype.h>
#include <stdio.h>
#include "ged.h"
#define PAGEWIDTH 72 /* default page width */
#define PAGELINES 66 /* default page length */
#define PAGECHAR '#' /* page number escape char */
static int fill; /* in fill mode if YES */
static int lsval; /* current line spacing */
static int inval; /* current indent; >= 0 */
static int rmval; /* current right margin */
static int ceval; /* number of lines to center */
static int ulval; /* number of lines to underline */
static int curpag; /* current output page number */
static int newpag; /* next output page number */
static int pageline; /* next line to be printed */
static int plval; /* page length in lines */
static int m1val; /* top margin, including header */
static int m2val; /* margin after header */
static int m3val; /* margin after last text line */
static int m4val; /* bottom margin, including footer */
static int bottom; /* last live line on page: */
static int dir; /* directions flag */
static char *header; /* top of page title */
static char *footer; /* bottom of page title */
static char *outbuf; /* lines to be filled go here */
static int inline, outline;
static int outp;
static int para1; /* excess paragraph indentation of 1st line of paragraph */
static int paraphase;
/* ----------------------------- */
/* keep dot commands if keep not 0.
*/
roff(keep)
int keep;
{
register i;
char inbuf[LLIM];
int c, ncline, msgline, lastlsav;
char *sp;
char *getline();
char temp[81];
char buf1[LLIM];
char buf2[LLIM];
char buf3[LLIM];
/* the large buffers are automatic so that they do not occupy permanent
* storage. The pointers to them are global within this file.
*/
header = &buf1[0];
footer = &buf2[0];
outbuf = &buf3[0];
/* don't retain memory of state after previous call */
fill = YES;
lsval = 1;
inval = 0;
rmval = PAGEWIDTH;
ceval = 0;
ulval = 0;
curpag = 0;
newpag = 1;
pageline = 0;
plval = PAGELINES;
m1val = 2;
m2val = 3;
m3val = 2;
m4val = 3;
bottom = plval - m3val - m4val; /* invariant */
header[0] = '\0';
footer[0] = '\0';
/* Old lines are deleted in blocks of 100 because deltp is slow for large
* documents. Its execution time is independent of the number of
* lines deleted.
*/
inline = 1;
lastlsav = lastl;
msgline = 0;
outline = lastl;
outbuf[0] = '\0';
outp = 0;
paraphase = 0; /* expecting first line of paragraph */
while (inline <= lastlsav) {
strcpy(inbuf,getline(inline));
if ( (inline + msgline ) == 1 || (inline % 100) == 0) {
sprintf(temp,"Reforming per dot commands. Line %d", inline+msgline);
putmess(temp);
}
if ((inline % 100) == 0) {
deltp(1,100);
inline -= 100;
lastlsav -= 100;
outline -= 100;
msgline += 100;
}
if (inline + msgline == cline)
ncline = outline - lastlsav;
inline++;
/* it is necessary to flush the output buffer before dot commands
* if they are left in the output.
*/
if (inbuf[0] == '.' && isalpha(inbuf[1]) ) {
if (keep) {
putwrd(""); /* flush the output buffer */
inject(outline++,inbuf); /* leave the dot commands in for further editing */
}
command(inbuf);
}
else {
proctext(inbuf);
}
}
putwrd(""); /* round it out */
space(10000);
if (lastlsav > 0)
deltp(1,lastlsav); /* delete the last of the old */
plast = -1;
moveline (ncline-cline); /* go back to the original point, which is not now at the same line number */
blankedmess = YES;
return;
}
/* perform formatting command */
command(buf)
char *buf;
{
int val, spval;
char *argtyp;
val = getval(buf,argtyp); /* get numerical argument and type */
/* begin page */
if (lookup(buf, "bp")) {
if (pageline > 0)
space(10000); /* maxint overflows */
set(&curpag, val, argtyp, curpag+1, -MAXINT, MAXINT);
newpag = curpag;
}
/* break */
else if (lookup(buf,"br"))
putwrd("");
/* center */
else if (lookup(buf,"ce")) {
putwrd("");
set(&ceval,val,argtyp,1,0,MAXINT);
}
/* fill */
else if (lookup(buf,"fi")) {
putwrd("");
fill = YES;
}
/* footnote */
else if (lookup(buf,"fo")) {
putwrd("");
strcpy(footer,buf+3);
}
/* header */
else if (lookup(buf,"he")) {
putwrd("");
strcpy(header,buf+3);
if (header[0] == '\0')
strcpy(header," "); /* activate pagination */
}
/* indent */
else if (lookup(buf,"in")) {
set(&inval, val, argtyp, 0, 0, rmval-1);
}
else if (lookup(buf,"ls"))
set(&lsval,val,argtyp,1,1,MAXINT);
/* need at least n lines before new page */
else if (lookup(buf, "ne")) {
if (val + pageline - 1 > bottom)
space(10000);
}
else if (lookup(buf,"nf")) {
putwrd(""); /* runout */
fill = NO;
}
else if (lookup(buf,"pl")) {
set(&plval, val, argtyp, PAGELINES, m1val+m2val+m3val+m4val+1, MAXINT);
bottom=plval-m3val-m4val;
}
else if (lookup(buf,"rm")) {
putwrd("");
set(&rmval, val, argtyp, PAGEWIDTH, inval+1, MAXINT);
}
else if (lookup(buf,"sp")) {
set(&spval,val,argtyp,1,0,MAXINT);
putwrd("");
space(spval);
}
else if (lookup(buf,"ul"))
set(&ulval,val,argtyp,0,1,MAXINT);
else
return; /* ignore unknown commands */
}
/* lookup routine for commands */
lookup(buf,string)
char *buf, *string;
{
return (buf[1] == string[0]) && (buf[2] == string[1]);
}
/* evaluate optional numeric argument */
getval(buf,argtyp)
char *buf, *argtyp;
{
int i;
i = 3;
/* ..find argument.. */
while (buf[i] == ' ' || buf[i] == '\t')
++i;
*argtyp = buf[i];
if (*argtyp == '+' || *argtyp=='-')
i++;
return(atoi(buf+i));
}
/* set parameter and check range */
set(param,val,argtyp,defval,minval,maxval)
int *param,val,defval,minval,maxval;
char *argtyp;
{
if (*argtyp == '\0')
*param = defval;
else if (*argtyp == '+')
*param += val;
else if (*argtyp == '-')
*param -= val;
else
*param = val;
*param = min(*param,maxval);
*param = max(*param,minval);
}
/* ------------- reformat text lines ------------------- */
proctext(inbuf)
char *inbuf;
{
char wrdbuf[LLIM];
char *nl;
int save, inpoint;
int i, j;
for (inpoint = 0; inbuf[inpoint] == ' '; inpoint++)
;
if (fill) {
/* determine additional indentation for first line of paragraph, if any */
if (inbuf[0] == '\0') {
paraphase = 0; /* looking for 1st line of paaragraph */
}
else if (paraphase == 0) {
paraphase = 1;
if (inline <= lastl) { /* use preceeding value if last line */
nl = getline(inline); /* next line */
for (j = 0; nl[j] == ' '; j++)
;
pa