home *** CD-ROM | disk | FTP | other *** search
- /* this file contains the line formatting stuff */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "defs.h"
- #include "externs.c"
-
- format(s,ifile,f)
- char s[];
- FILE *ifile,*f;
- {
- /* The idea is to collect output into a buffer (outbuf)
- and when the buffer is complete, write it.
- The variable s contains the text of the last line
- read from the input file. The output buffer is
- in variable "outbuf". */
-
- int i;
-
- char word[MAXSTR],tstring[MAXSTR];
- int wordlength;
- int diff;
- int chcnt;
-
- /* first "doctor" the line if boldcount or italicscount > 0 */
- if (BOLDCNT > 0) {
- addstr(s,"\\fB","\\fP");
- BOLDCNT--;
- }
- if (ITALCNT > 0) {
- addstr(s,"\\fI","\\fP");
- ITALCNT--;
- }
- if (ULCOUNT > 0) {
- addstr(s,"\\fU","\\fU");
- ULCOUNT--;
- }
-
- /* now if the line should be centered, do it, otherwise just
- format it */
- if (!FILLMODE || CNTRCNT > 0) {
- /* just parse the line to get the length */
- i = 0;
- while (s[i] != '\0') {
- getword(word,s,&i);
- parseword(tstring,word,&wordlength,&chcnt,ifile,f);
- append(tstring,chcnt);
- CURRX = CURRX + wordlength;
- }
- endln();
-
- TEMPINDENT = 0;
- if (CNTRCNT > 0) {
- TEMPINDENT = (RMARGIN - LMARGIN - CURRX)/2;
- CNTRCNT--;
- }
-
- output (ifile,f,0);
- }
- else { /* don't center it */
-
- /* get a word from s */
- i = 0;
- while ( s[i] != '\0') {
- getword(word,s,&i);
- /* now add the word to the buffer */
- /* we have to parse the word to find any
- embedded font changes, and to determine its printable
- length */
- parseword(tstring,word,&wordlength,&chcnt,ifile,f);
-
- diff = RMARGIN - LMARGIN - TEMPINDENT;
- if (( length(' ') + CURRX + wordlength) >= diff) {
- endln();
- output(ifile,f,diff);
- }
- append(tstring,chcnt);
- CURRX = CURRX + wordlength ;
- /* note CURRX is current printable position on line */
-
- }
- } /* of don't center it */
- }
-
-
- /* getword looks inside string s, starts at position i, and returns
- the next word in t */
- VOID getword(t,s,i)
- char t[];
- char s[];
- int *i;
- {
- int j;
- /* first skip any white space */
- while ( s[*i] != '\0' && isspace(s[*i]) ) (*i)++;
-
- /* now copy into string t */
- j = 0;
- while ( s[*i] != '\0' && !isspace(s[*i]) ) {
- t[j] = s[*i];
- (*i)++;
- j++;
- }
- t[j] = '\0';
- /* note that s[*i] is either '\0' or it is white space */
-
- }
-
-
- /* append adds the string to the existing output buffer. Note that
- the buffer does NOT have a NULL at its end. */
- VOID append(s,chcnt)
- char s[];
- int chcnt;
- {
- int j;
- if (shadd && obufpos != 0 && s[0] != '\0') {
- outbuf[obufpos] = ' ';
- obufpos++;
- outbuf[obufpos] = SHIFTOUT;
- obufpos++;
- CHARCNT = CHARCNT + 1;
- CURRX = CURRX + length(' ');
- }
- else
- shadd = TRUE;
-
- j = 0;
- while (s[j] != '\0') {
- outbuf[obufpos] = s[j];
- j++;
- obufpos++;
- }
- if (LASTPERIOD) {
- outbuf[obufpos] = ' ';
- obufpos++;
- outbuf[obufpos] = SHIFTOUT;
- obufpos++;
- CHARCNT = CHARCNT + 1;
- CURRX = CURRX + length(' ');
- LASTPERIOD = FALSE;
- }
- /* WARNING --- outbuf does NOT have a NULL at its end */
- CHARCNT = CHARCNT + chcnt ;
-
-
- }
-
-
- /* we have to parse the word to find any
- embedded font changes, and to determine its printable
- length. The word is copied into tstring with any control characters
- expanded and embedded. This needs to be a FSM. */
-
- VOID parseword(tstring,word,wordlength,chcnt,ifile,f)
- char tstring[],word[];
- int *wordlength;
- int *chcnt;
- FILE *ifile, *f;
- {
- int nextstate;
- int i; /* for counter of subscript in word */
- int j; /* subscript in tstring */
- int k; /* subscript for copying */
- int m; /* general counter */
-
- char tstr[MAXSTR], tempstr[MAXSTR]; /* a temporary string */
- char ch,regname;
-
- *chcnt = 0;
- *wordlength = 0;
- i = 0;
- j = 0;
-
- nextstate = 0;
- if (InExpression)
- nextstate = 4;
-
- if (InMacro)
- nextstate = 17;
-
- while (nextstate != 999) {
- ch = word[i];
- switch(nextstate) {
- case 0: /* start state */
- if (ch == '\\')
- nextstate = 1;
- else if (ch == '\0' || ch == EOF)
- nextstate = 999;
- else /* copy state */
- nextstate = 1000;
- break;
-
- case 1 : /* it's a '\' */
- i++;
- ch = word[i];
- if (ch == '\\')
- nextstate = 2;
- else if (ch == '(')
- nextstate = 3;
- else if (ch == '{')
- nextstate = 17;
- else if (ch == '[')
- nextstate = 4;
- else if (ch == 'f')
- nextstate = 8;
- else
- /* not a state -- must be an escaped
- character, so just copy it */
- nextstate = 1000;
- break;
-
- case 2: /* it is an escaped '\' */
- tstring[j] = ch;
- j++;
- tstring[j] = SHIFTOUT;
- j++;
- *wordlength = *wordlength + length('\\');
- *chcnt = *chcnt + 1;
- i++;
- nextstate = 0; /* start it over */
- break;
-
- case 3: /* it is an in-line register */
- /* first get the name of the register -- it should
- be a single character */
- i++;
- regname = word[i];
- i++; /* advance to after the register name */
- if (word[i] == 'C') {
- /* interpolate as a character */
- sprintf(tempstr,"%c",REG(regname));
- i++;
- }
- else /* interpolate as a number */
- sprintf(tempstr,"%d",REG(regname));
- if (word[i]!= ')') {
- fprintf(stderr,"error in register name -- one letter only!\n");
- exit(1);
- }
- i++; /* to skip the ')' */
- /* now append tempstr to the output string */
- k = 0;
- while (tempstr[k] != '\0') {
- tstring[j] = tempstr[k];
- j++;
- tstring[j] = SHIFTOUT;
- *wordlength = *wordlength + length(tempstr[k]);
- *chcnt = *chcnt + 1;
- j++;
- k++;
- }
- nextstate = 0;
-
- break;
-
- case 4: /* it is an expression */
- /* don't forget to advance i to end of expression */
- /* the end of the expression is signified by ']' */
- InExpression = TRUE;
- tstr[0] = '\0';
- if (word[i] == '[') i++; /* skip the '[' */
- k = 0;
- while (word[i] != '\0' && word[i] != ']') {
- tstr[k] = word[i];
- i++;
- k++;
- }
- tstr[k] = ' ';
- tstr[k + 1] = '\0';
- strcat(expstr,tstr);
- if (word[i] == ']') {
- InExpression = FALSE;
- eval(expstr);
- expstr[0] = '\0';
- }
-
- if (word[i] == ']') i++; /* skip the whatever */
- nextstate = 0;
-
- break;
-
- case 8: /* it is a font change, I guess. find out which one */
- i++;
- ch = word[i];
- switch (ch) {
- case '0' : /* return to default font */
- pushf(cfont,&fstk);
- pushi(clen,&ipstk);
- clen = defl;
- strcpy(cfont,prinit);
- k = 0;
- if (!FONTCHANGE)
- cfont[0] = '\0';
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
- case 'M': /* mountable font */
- case '1' : /* Presentation 18 point */
- pushf(cfont,&fstk);
- pushi(clen,&ipstk);
- strcpy(cfont,Pres);
- clen = &P18bl[0];
- k = 0;
- if (!FONTCHANGE ) cfont[0] = '\0';
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
- case '2' : /* Helv. 6 point font */
- pushf(cfont,&fstk);
- pushi(clen,&ipstk);
-
- sprintf(cfont,"%c&10O%c(0U%c(s1p6vsb4T",ESC,ESC,ESC);
- clen = &H6nl[0];
- k = 0;
- if (!FONTCHANGE ) cfont[0] = '\0';
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
- case 'B' : /* Times Roman bold face */
- pushf(cfont,&fstk);
- pushi(clen,&ipstk);
- clen = &H12bl[0];
- sprintf(cfont,"%c&l0O%c(0U%c(s1p12vs3b5T",ESC,ESC,ESC);
- if (!FONTCHANGE ) cfont[0] = '\0';
- k = 0;
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
- case 'I' : /* Times Roman 12 point italics */
- pushf(cfont,&fstk);
- pushi(clen,&ipstk);
- sprintf(cfont,"%c&l0O%c(0U%c(s1p12v1sb5T",ESC,ESC,ESC);
- clen = &H12il[0];
- if (!FONTCHANGE ) cfont[0] = '\0';
- k = 0;
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
- case 'T' : /* Courier */
- pushf(cfont,&fstk);
- pushi(clen,&ipstk);
- sprintf(cfont,"%c&10O%c(0U%c(sp10h12vsb3T",ESC,ESC,ESC);
- clen = &C12nl[0];
- if (!FONTCHANGE ) cfont[0] = '\0';
- k = 0;
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
- case 'U' : /* underline toggle */
- if (ULSTATE == FALSE) {
- sprintf(tempstr,"%c&dD",ESC);
- ULSTATE = TRUE;
- }
- else {
- sprintf(tempstr,"%c&d@",ESC);
- ULSTATE = FALSE;
- }
- if (!FONTCHANGE ) tempstr[0] = '\0';
- k = 0;
- while (tempstr[k] != '\0') {
- tstring[j] = tempstr[k];
- k++;
- j++;
- }
- break;
- case 'P' : /* pop font stack */
- popf(cfont,&fstk);
- popi(&clen,&ipstk);
- k = 0;
- if (!FONTCHANGE ) cfont[0] = '\0';
- while (cfont[k] != '\0') {
- tstring[j] = cfont[k];
- k++;
- j++;
- }
- break;
-
- case '|' : /* it's an anchor */
- m = 0;
- while (m <= j) {
- if (tstring[m] == SHIFTOUT) {
- tstring[m] = ANCHOR;
- *chcnt = *chcnt - 1;
- }
- m++;
- }
- sprintf(tempstr,"%c*p%dX",ESC,TEMPINDENT + LMARGIN + i*length('w') );
- k = 0;
- if (!FONTCHANGE ) tempstr[0] = '\0';
- while (tempstr[k] != '\0') {
- tstring[j] = tempstr[k];
- k++;
- j++;
- }
- break;
-
- } /* of switch */
- i++;
- nextstate = 0; /* start over */
- break;
-
- case 17: /* expand in-line string macro */
- /* don't forget to advance i */
- InMacro = TRUE;
- if (word[i] == '{') i++; /* skip the '{' */
- k = 0;
- while (word[i] != '\0' && word[i] != '}') {
- tstr[k] = word[i];
- i++;
- k++;
- }
- tstr[k] = ' ';
- tstr[k + 1] = '\0';
- strcat(macline,tstr);
- if (word[i] == '}') {
- /* skip the '}' */
- i++;
- /* end the macline and process the
- macro */
- InMacro = FALSE;
- procmacro (macline,ifile,f);
- macline[0] = '\0';
- tstr[0] = '\0';
-
- }
-
- nextstate = 0;
-
- break;
-
-
- case 999 : /* at the end state */
- break;
-
- case 1000 : /* copy state */
- default:
- tstring[j] = ch;
- j++;
- tstring[j] = SHIFTOUT;
- nextstate = 0; /* start it over */
- *wordlength = *wordlength + length(ch);
- *chcnt = *chcnt + 1;
- j++;
- i++;
- break;
-
- } /* of switch */
- } /* of while nextstate */
- tstring[j] = '\0';
- k = j - 1;
- while (k > 0 && (isspace(tstring[k]) || tstring[k] == SHIFTOUT) ) k--;
- if (k > 0 && ispunct(tstring[k]) )
- LASTPERIOD = TRUE;
- else
- LASTPERIOD = FALSE;
-
- } /* of parseword */
-
-
-
- /* length returns the length of a character, measured in dots */
- int length(c)
- char c;
- {
- /* temporarily */
- return *(clen + (c & 0xff));
- }
-
- /* clean out the buffers, print anything collected, and reset counters */
- VOID brek(ifile,ofile)
- FILE *ifile,*ofile;
- {
- /* be sure to empty the buffer again */
- outbuf[obufpos] = '\0';
- if (outbuf[0] != '\0')
- output(ifile,ofile,0);
- outbuf[0] = '\0';
- obufpos = 0;
- CURRX = 0;
- CHARCNT = 0;
- }
-
-
- /* process a line, but do not justify it, and preserve the spaces */
- nonfill(s,ifile,f)
- char s[];
- FILE *ifile,*f;
- {
- /* The idea is to collect output into a buffer (outbuf)
- and when the buffer is complete, write it.
- The variable s contains the text of the last line
- read from the input file. The output buffer is
- in variable "outbuf". */
-
- int i;
-
- char word[MAXSTR],tstring[MAXSTR];
- int wordlength;
- int chcnt;
-
- /* first "doctor" the line if boldcount or italicscount > 0 */
- if (BOLDCNT > 0) {
- addstr(s,"\\fB","\\fP");
- BOLDCNT--;
- }
- if (ITALCNT > 0) {
- addstr(s,"\\fI","\\fP");
- ITALCNT--;
- }
- if (ULCOUNT > 0) {
- addstr(s,"\\fU","\\fU");
- ULCOUNT--;
- }
-
- /* now if the line should be centered, do it, otherwise just
- format it */
- if ( CNTRCNT > 0) {
- /* just parse the line to get the length */
- i = 0;
- while (s[i] != '\0') {
- getword(word,s,&i);
- parseword(tstring,word,&wordlength,&chcnt,ifile,f);
- append(tstring,chcnt);
- CURRX = CURRX + wordlength;
- }
- endln();
-
- TEMPINDENT = (RMARGIN - LMARGIN - CURRX)/2;
- CNTRCNT--;
-
- output (ifile,f,0);
- }
- else { /* don't center it */
-
- /* expand s to include any font changes */
- parseword(tstring,s,&wordlength,&chcnt,ifile,f);
- strcpy(outbuf,tstring);
- CURRX = CURRX + wordlength ;
- TEMPINDENT = 0;
- output(ifile,f,0);
-
- } /* of don't center it */
- }
-
-