home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d197
/
nro.lha
/
Nro
/
nrotxt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-28
|
23KB
|
950 lines
/*
* 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;
}