[comp.sources.amiga] v89i037: nrotxt - missing source file from nro distribution

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.