page@swan.ulowell.edu (Bob Page) (03/09/89)
Submitted-by: U211344@HNYKUN11.BITNET (Olaf 'Rhialto' Seibert) Posting-number: Volume 89, Issue 37 Archive-name: applications/nrotxt.1 I have been told that a source file was missing in the distribution of NRO. Here it is. # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # nrotxt.c # This archive created: Wed Mar 8 14:58:09 1989 cat << \SHAR_EOF > nrotxt.c /* * 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; } SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.