home *** CD-ROM | disk | FTP | other *** search
- /*
- * Text processing portion of NRO word processor
- *
- * Originally by Stephen L. Browning, 5723 North Parker Avenue
- * Indianapolis, Indiana 46220
- *
- * Transformed beyond immediate recognition, and
- * adapted for Amiga by Olaf Seibert, KosmoSoft
- *
- * Vossendijk 149-1 (study) Beek 5 (home)
- * 5634 TN Nijmegen 5815 CS Merselo
- * The Netherlands The Netherlands
- * Phone:
- * (...-31)80561045 (...-31)4786205
- * or 080-561045 04786-205
- *
- * This program is NOT in the public domain. It may, however
- * be distributed only at no charge, and this notice must be
- * included unaltered.
- */
-
- #include <stdio.h>
- #include "nro.h"
- #include "nroxtrn.h"
-
- text(from, infile)
- register uchar *from;
- register FILE *infile;
- {
- register short more;
-
- /*
- * text() Is being called with the first letter of an input line
- * already in the buffer.
- */
-
- if (*from == ' ' || iseol(*from))
- leadbl(from, infile);
- else
- putbak(*from);
-
- if (iseol(*from)) put(from); /* All blank line */
- else if (env.fill == NO) unfilled(infile);
- else {
- more = getwrd(from, infile);
- while (more > 0) {
- putwrd(from);
- more = getwrd(from, infile);
- }
- if (more != EOF) putwrd(from);
- }
-
- /* Reached end of input line */
-
- if (env.ceval > 0) --env.ceval;
- if (env.ulval > 0) if (--env.ulval == 0) env.reqmode &= ~FXUL;
- if (env.cuval > 0) if (--env.cuval == 0) env.reqmode &= ~FXUL;
- if (env.boval > 0) if (--env.boval == 0) env.reqmode &= ~FXBO;
- if (env.itval > 0) if (--env.itval == 0) env.reqmode &= ~FXIT;
- }
-
-
-
- /*
- * delete leading blanks, set tival
- */
-
- leadbl(p, infile)
- uchar *p;
- FILE *infile;
- {
- int i = 0;
- register uchar chr = *p;
-
- dobrk();
-
- while (chr == ' ') {
- chr = ngetc(infile);
- i++;
- }
- *p = chr;
-
- if (isnteol(chr)) {
- env.tival += i;
- putbak(chr);
- } else p[1] = EOS;
- }
-
-
- /*
- * Get non-blank word from the input file.
- * Returns 1 if there is propably more text on the line,
- * EOF on end of file, and 0 otherwise.
- */
-
- getwrd(to, infile)
- register uchar *to;
- register FILE *infile;
- {
- register int length;
- register short chr;
- uchar firstchr;
- int more;
-
- chr = ngetc(infile);
- if (chr == EOF) {
- *to = EOS;
- return EOF;
- }
- length = 0;
-
- /* Skip spaces, include tabs, but only at begin of word */
-
- while (chr == ' ') chr = ngetc(infile);
- firstchr = chr;
-
- more = TRUE; /* May I still accept more TABs ? */
- while (chr != ' ' && isnteol(chr) && chr != EOF && length < MAXWORD-3) {
- if (chr != '\t') more = FALSE;
- else if (!more) break;
- *to++ = chr;
- length++;
- chr = ngetc(infile);
- }
-
- if (iseol(chr)) more = FALSE;
- else {
- more = TRUE;
- if (chr == '\t') putbak(chr);
- }
-
- if (length > 0) {
- chr = *(to-1);
- if (chr == '"') chr = *(to-2);
- if (chr == '?' || chr == '!') {
- *to++ = ' ';
- ++length;
- }
- if (chr == '.' && (!more || islower(firstchr))) {
- *to++ = ' ';
- ++length;
- }
- }
- *to = EOS;
- if (length >= MAXWORD-1) error("nro: word buffer overflow\n");
-
- return more;
- }
-
-
-
- /*
- * Put word in output buffer
- */
-
- putwrd(wrdbuf)
- uchar *wrdbuf;
- {
- uchar *from, *to;
- int w, last, llval, nextra;
- uchar temp[MAXWORD];
-
-
- if ((w = strlen(wrdbuf)) == 0) return;
- last = w + env.outp;
- w = width(wrdbuf);
-
- llval = env.tmval - env.tival;
- if ((env.outp > 0 && env.outw + w > llval) || last > MAXLINE-20) {
-
- if (env.ceval != 0) /* Centering overrides justification */
- /* Can't be done here since buffer not terminated */
- /* center(env.outbuf) */ ;
- else if (env.juval == YES) {
- nextra = llval - env.outw + 1;
- /*
- * Delete trailing spaces and
- * modify counts so that it is right justified.
- */
- if (env.outbuf[env.outp-2] == ' ') {
- --env.outp;
- ++nextra;
- }
- spread(env.outbuf, env.outp-1, nextra, env.outwds);
- if (env.outwds > 1)
- env.outp += (nextra - 1);
- }
- env.dontbrk = FALSE;
- dobrk(); /* This also does a put() and may change modes */
- }
-
- /* Do bold underline italics here */
- env.curmode = doboitul(wrdbuf, temp, MAXWORD, env.curmode);
- from = wrdbuf;
- to = env.outbuf + env.outp;
-
- /* Append given word to the output buffer */
- nextra = FALSE;
- while (*from != EOS) {
- if (*from == '\t') {
- llval = 0; /* Ouch, but we need pointer to INT */
- to = tabexp(env.outw, &llval, to);
- env.outw += llval;
- w--;
- from++;
- nextra = TRUE; /* We have just expanded a tab */
- } else {
- *to++ = *from++;
- }
- }
- *to++ = ' ';
- env.outw += w + 1;
- env.outp = to - env.outbuf;
- env.outwds++;
-
- if (nextra) { /* Eliminate all preceding spaces */
- to--; /* Don't touch the last appended space */
- while (to > env.outbuf) {
- if (*--to == ' ') *to = NBSP;
- }
- env.outwds = 1;
- }
- }
-
- /*
- * doboitul - Do bold, italics and underline
- */
-
- doboitul(from, via, size, curmode)
- uchar *from, *via;
- int size;
- short curmode;
- {
- if (dc.bsflg == BSAMIGA) {
- return processfx(from, via, size, curmode);
- } else {
- if (env.reqmode & FXBO) bold(from, via, size);
- else if (env.reqmode & FXUL) underl(from, via, size);
-
- return curmode;
- }
- }
-
-
- /*
- * Insert bold face text in from using via
- */
-
- bold(from, via, size)
- register uchar *from, *via;
- register int size;
- {
- register int i, j;
- register uchar c;
-
- j = 0;
- for (i=0; (c=from[i]) && c != '\n' && (j < size-1); i++) {
- if (isalnum(c)) {
- via[j++] = c;
- via[j++] = '\b';
- }
- via[j++] = c;
- }
- via[j++] = c;
- via[j] = EOS;
- while (*via != EOS) *from++ = *via++;
- *from = EOS;
- }
-
-
-
- /*
- * Underline a line from using buffer via
- */
-
- underl(from, via, size)
- register uchar *from, *via;
- register int size;
- {
- register int i, j;
- register uchar c;
-
- j = 0;
- for (i=0; (c=from[i]) && c != '\n' && (j < size-1); i++) {
- /* if (c >= ' ' && c <= '~') */ /* Test superfluous */
- if (isalnum(c) || env.cuval > 0 && c!= ' ') {
- via[j++] = '_';
- via[j++] = '\b';
- }
- via[j++] = c;
- }
- via[j++] = c;
- via[j] = EOS;
- while (*via != EOS) *from++ = *via++;
- *from = EOS;
- }
-
-
-
- #define movecodes(index)\
- for (cp=commseq[index]; commbyte = *cp++; ) from[j++] = commbyte;
-
- /*
- * Do bold, underline and italics the Amiga way
- */
-
- short processfx(from, via, size, curmode)
- uchar *from, *via;
- int size;
- register short curmode;
- {
- register short reqmode = env.reqmode;
- register short tmpmode;
- register int j;
- register uchar c;
- short cu = TRUE;
- uchar *cp, commbyte;
-
- if (reqmode == FXPLAIN && curmode == FXPLAIN)
- return FXPLAIN;
-
- if (env.ulval > 0) { /* Need we underline non-continuously? */
- cu = FALSE;
- }
-
- strcpy(via, from); /* Minimize amount to move */
- j = 0;
-
- if (curmode & ~reqmode) { /* Something too much active? */
- movecodes(FXPLAIN); /* Cancel it! */
- curmode = FXPLAIN;
- }
-
- while ( (c = *via++) && c != '\n' && (j < size-6) ) {
- if (isspace(c)) { /* Spaces cancel underline */
- if (curmode & FXUL) {
- movecodes(FXPLAIN);
- curmode = FXPLAIN;
- }
- } else if (isalnum(c)) {/* Letgits set everything */
- if (curmode != reqmode) {
- movecodes(reqmode & ~curmode);
- curmode = reqmode;
- }
- } else { /* Rest of characters are mixed */
- tmpmode = reqmode & ~FXBO;
- if (! cu) tmpmode = tmpmode & ~FXUL;
-
- if (curmode & ~tmpmode) {
- movecodes(FXPLAIN);
- curmode = FXPLAIN;
- }
- if (curmode != tmpmode) {
- movecodes(tmpmode & ~curmode);
- curmode = tmpmode;
- }
- }
- from[j++] = c;
- }
- if (curmode & FXUL) { /* Leave bold and italics on */
- movecodes(FXPLAIN);
- curmode = FXPLAIN;
- }
-
- from[j++] = c; /* Append terminator */
- from[j++] = EOS; /* This may sometimes not be necessary */
-
- return curmode;
- }
-
-
- /*
- * tabexp - Expand a tab
- *
- * Returns the pointer to the next free byte
- */
-
- uchar *tabexp(inwidth, outwidth, buffer)
- int inwidth;
- register int *outwidth;
- register uchar *buffer;
- {
- int i, extra;
-
- /* Find the tab we need to go to */
- inwidth += env.tival;
- for (i=0; i<MAXTAB && env.tabstop[i] <= inwidth; i++) ;
-
- extra = env.tabstop[i];
- if (extra >= env.tmval || i >= MAXTAB)
- extra = 0;
- else
- extra -= inwidth;
-
- while (extra-- > 0) {
- *(buffer++) = NBSP;
- ++*outwidth;
- }
-
- return buffer;
- }
-
- /*
- * swmodes - switch printer modes
- */
-
- swmodes(modefrom, modeto)
- int modefrom, modeto;
- {
- uchar commbyte;
- uchar from[16];
- uchar *cp;
- int j = 0;
-
- if (modefrom & ~modeto) {
- movecodes(FXPLAIN);
- modefrom = FXPLAIN;
- }
- if (modefrom != modeto) {
- movecodes(modeto & ~modefrom);
- }
- from[j] = EOS;
-
- putlin(from, pout);
- }
-
- #undef movecodes
-
-
- /*
- * unfilled - Copy input line without fill
- */
-
- unfilled(infile)
- register FILE *infile;
- {
- uchar line[MAXLINE];
- uchar temp[MAXLINE];
- register uchar *linep = line;
- register int chr;
- int width = 0;
-
- while (width < MAXLINE-2 && (chr = ngetc(infile), isnteol(chr))) {
- if (chr == '\t') {
- linep = tabexp(width, &width, linep);
- } else if (chr == EOF) {
- break;
- } else {
- *linep++ = chr;
- width++;
- }
- }
- #ifdef CPM
- *linep++ = '\r';
- #endif
- *linep++ = '\n';
- *linep = EOS;
-
- if (env.ceval != 0) /* Centering */
- center(line);
- env.curmode = doboitul(line, temp, MAXLINE, env.expmode = dc.curmode);
- put(line);
- }
-
-
-
- /*
- * Center a line by incrementing tival
- */
-
- center(p)
- uchar *p;
- {
- env.tival += max((env.tmval - env.tival - width(p) + 1) >> 1, 0);
- }
-
-
-
- /*
- * Expand title buffer to include character string
- */
-
- expand(buffer, pgchr, string)
- uchar *buffer;
- uchar pgchr;
- uchar *string;
- {
- uchar tmp[MAXLINE];
- register uchar *from, *to, *tmpstr;
-
- from = buffer;
- to = tmp;
- while (*from != EOS) {
- if (*from == pgchr) {
- tmpstr = string;
- while (*tmpstr != EOS) *to++ = *tmpstr++;
- } else *to++ = *from;
- from++;
- }
- *to = EOS;
- strcpy(buffer, tmp); /* Copy it back */
- }
-
-
- /*
- * Get field from title
- */
-
- uchar *getfield(p, q, delim)
- uchar *p, *q;
- uchar delim;
- {
- while (*p != delim && isnteol(*p) && *p != EOS) {
- *q++ = *p++;
- }
- *q = EOS;
- if (*p == delim) p++;
- return p;
- }
-
-
- /*
- * Convert integer to decimal ascii string
- */
-
- itoda(value, buffer)
- int value;
- uchar *buffer;
- {
- if (env.pnflg == PNARABIC)
- sprintf(buffer, "%d", value);
- else {
- buffer[0] = EOS;
- while (value >= 1000) { strcat(buffer, "m" ); value -= 1000; }
- if (value >= 400 ) { strcat(buffer, "cd"); value -= 400; }
- while (value >= 100 ) { strcat(buffer, "c" ); value -= 100; }
- if (value >= 90 ) { strcat(buffer, "xc"); value -= 90; }
- if (value >= 50 ) { strcat(buffer, "l" ); value -= 50; }
- if (value >= 40 ) { strcat(buffer, "xl"); value -= 40; }
- while (value >= 10 ) { strcat(buffer, "x" ); value -= 10; }
- if (value >= 9 ) { strcat(buffer, "ix"); value -= 9; }
- if (value >= 5 ) { strcat(buffer, "v" ); value -= 5; }
- if (value >= 4 ) { strcat(buffer, "iv"); value -= 4; }
- while (value--) strcat(buffer, "i");
-
- if (env.pnflg == PNUROMAN) strupper (buffer);
- }
- }
-
- /*
- * strupper - Convert string to upper case
- */
-
- strupper(string)
- register uchar *string;
- {
- for ( ; *string != EOS; string++) {
- if (islower(*string))
- *string = toupper(*string);
- }
- }
-
-
- /*
- * Center title text into print buffer
- */
-
- justcntr(p, q, limit)
- uchar *p, *q;
- int limit[];
- {
- int len;
-
- len = width(p);
- q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
- while (*p != EOS) *q++ = *p++;
- }
-
-
-
- /*
- * Left justify title text into print buffer
- */
-
- justleft(from, to, limit)
- uchar *from, *to;
- int limit;
- {
- to = &to[limit];
- while (*from != EOS) *to++ = *from++;
- }
-
-
- /*
- * Right justify title text into print buffer
- */
-
- justrite(from, to, limit)
- uchar *from, *to;
- int limit;
- {
- int len;
-
- len = width(from);
- to = &to[limit - len];
- while (*from != EOS) *to++ = *from++;
- }
-
-
-
-
- /*
- * Find minimum of two integers
- */
-
- int min(v1, v2)
- int v1, v2;
- {
- return (v1 < v2) ? v1 : v2;
- }
-
-
-
- /*
- * Find maximum of two integers
- */
-
- int max(v1, v2)
- int v1, v2;
- {
- return (v1 > v2) ? v1 : v2;
- }
-
-
-
- /*
- * Find absolute of a value
- */
-
- abs(foo)
- int foo;
- {
- return (foo >= 0) ? foo : -foo;
- }
-
-
-
- /*
- * Put out page footer
- */
-
- pfoot()
- {
- if (pg.prflg) {
- skip(pg.m3val);
- if (pg.m4val > 0) {
- if ((pg.curpag % 2) == 0) {
- puttl(pg.efoot, pg.eflim, pg.curpag);
- } else {
- puttl(pg.ofoot, pg.oflim, pg.curpag);
- }
- skip(pg.m4val - 1);
- }
- }
- }
-
-
-
- /*
- * Put out page header
- */
-
- phead()
- {
- pg.curpag = pg.newpag;
- if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg) {
- pg.prflg = TRUE;
- } else {
- pg.prflg = FALSE;
- }
- ++pg.newpag;
- if (pg.prflg) {
- if (pg.m1val > 0) {
- skip(pg.m1val - 1);
- if ((pg.curpag % 2) == 0) {
- puttl(pg.ehead, pg.ehlim, pg.curpag);
- } else {
- puttl(pg.ohead, pg.ohlim, pg.curpag);
- }
- }
- skip(pg.m2val);
- }
- /*
- * Initialize lineno for the next page
- */
- pg.lineno = pg.m1val + pg.m2val + 1;
- }
-
-
- /*
- * Print character with test for printer
- */
-
- #ifdef CPM
- prchar(c, fp)
- uchar c;
- FILE *fp;
- {
- if (dc.lpr) {
- bdos(5, c);
- } else {
- putc(c, fp);
- }
- }
- #endif
-
-
-
-
- /*
- * Put out line with proper spacing and indenting
- */
-
- put(p)
- uchar *p;
- {
- int j;
- uchar os[MAXLINE];
-
- if (pg.lineno == 0 || pg.lineno > pg.bottom) {
- phead();
- }
- if (pg.prflg) {
- if (dc.bsflg == BSNO && strkovr(p, os)) {
- if (isnteol(os[0]))
- for (j = pg.offset + env.tival; j; j--)
- prchar(' ', pout);
- putlin(os, pout);
- }
- if (isnteol(*p))
- for (j = pg.offset + env.tival; j; j--)
- prchar(' ', pout);
-
- /* Is the expected mode at the beginning of the line */
- /* also the real current printer mode ? */
-
- if (env.expmode != dc.curmode)
- swmodes(dc.curmode, env.expmode);
- putlin(p, pout);
-
- /* Update the mode at the end of the line */
- env.expmode = dc.curmode = env.curmode;
- }
-
- env.tival = env.inval;
- env.tmval = env.rmval;
- skip(min(env.lsval-1, pg.bottom-pg.lineno));
- pg.lineno = pg.lineno + env.lsval;
-
- if (pg.lineno > pg.bottom) pfoot();
- }
-
-
- /*
- * Output a null terminated string to the file
- * specified by pbuf.
- */
-
- #ifndef putlin
-
- putlin(p, prfile)
- register uchar *p;
- register FILE *prfile;
- {
- register uchar chr;
-
- while ((chr = *p++) != EOS) prchar(chr, prfile);
- }
-
- #endif
-
-
- /*
- * Put out title or footer
- */
-
- puttl(p, lim, pgno)
- uchar *p;
- int lim[];
- int pgno;
- {
- int i;
- uchar pn[8];
- uchar delim;
- uchar t[MAXLINE];
- uchar h[MAXLINE];
-
- itoda(pgno, pn);
-
- for (i=0; i<MAXLINE; i++) h[i] = ' ';
-
- delim = *p++;
- p = getfield(p, t, delim);
- expand(t, env.pgchr, pn);
- justleft(t, h, lim[LEFT]);
-
- p = getfield(p, t, delim);
- expand(t, env.pgchr, pn);
- justcntr(t, h, lim);
-
- p = getfield(p, t, delim);
- expand(t, env.pgchr, pn);
- justrite(t, h, lim[RIGHT]);
-
- for (i=MAXLINE-4; h[i] == ' '; --i) h[i] = EOS;
- h[++i] = '\n';
- #ifdef CPM
- h[++i] = '\r';
- #endif
- h[++i] = EOS;
- if (i > 1) { /* strlen(h) */
- for (i=0; i<pg.offset; i++) prchar(' ', pout);
- }
- if (dc.curmode != FXPLAIN) { /* Cancel special effx */
- putlin(commseq[FXPLAIN], pout);
- dc.curmode = /* env.curmode = */ FXPLAIN;
- }
- putlin(h, pout);
- }
-
-
- /*
- * Skips the number of lines specified by n.
- */
-
- skip(n)
- register int n;
- {
- register int i;
-
- if (n > 0 && pg.prflg) {
- for (i=0; i<n; i++) {
- prchar('\n', pout);
- }
- }
- }
-
-
-
- /*
- * Spread words to justify right margin
- */
-
- spread(p, outp, nextra, outwds)
- uchar p[];
- int outp, nextra, outwds;
- {
- register int from, to;
- register int nblanks, needed, nholes;
-
- if ((nextra <= 0) || (outwds <= 1)) return;
- env.sprdir = !env.sprdir;
- needed = nextra;
- nholes = outwds - 1; /* Holes between words */
- from = outp - 1; /* Last non-blank character */
- to = min(MAXLINE-2, from+needed); /* Leave room for LF, EOS */
-
- /* Walk over the line from right to left */
- while (from < to) { /* as long as we need insert more spaces */
- p[to] = p[from];
- if (p[from] == ' ') { /* Aha. Need to insert spaces here */
- if (env.sprdir == 0) nblanks = (needed - 1)/ nholes + 1;
- else nblanks = needed / nholes;
- needed -= nblanks;
- --nholes;
- for (; nblanks>0; --nblanks) {
- /* --to; */
- p[--to] = ' ';
- }
- }
- --from;
- --to;
- }
- }
-
-
-
- /*
- * Split overstrikes (backspaces) into seperate buffer
- */
-
- strkovr(from, aux)
- register uchar *from, *aux;
- {
- register uchar *to; /* Pointer back in original buffer */
- uchar *beginaux = aux;
- int bsflg;
-
- bsflg = FALSE;
- to = from;
-
- while (*from != EOS) {
- *aux = ' '; /* First, assume no action necessary */
- *to = *from; /* Copy current character */
- from++;
- if (*from == '\b') { /* Oh, we need to do some work */
- if (*to >= ' ' && *to <= '~') {
- bsflg = TRUE;
- *aux = *to; /* Put overstruck 1st character in aux */
- from++;
- *to = *from;/* Put second character in orig. buffer */
- from++;
- }
- }
- aux++;
- to++;
- }
-
- if (bsflg) { /* Eliminate trailing spaces */
- while (aux[-1] == ' ' && aux > beginaux) aux--;
- *aux++ = '\r';
- if (aux <= beginaux+1)
- bsflg = FALSE; /* Maybe nothing is left in the buffer! */
- }
- *aux = *to = EOS;
-
- return bsflg;
- }
-
-
- /*
- * Compute width of character string
- */
-
- width(s)
- register uchar *s;
- {
- int w;
-
- w = 0;
- while (*s != EOS) {
- if (*s == '\b') --w;
- else if ((*s & 0x7F) == ESC) { /* Eat escape sequences */
- while (*++s <= '@');
- } else if (isnteol(*s)) w++;
- ++s;
- }
- return w;
- }
-