[BACK]Return to paragraph.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/paragraph.c, Revision 1.2

1.1       deraadt     1: /*
                      2:  * Code for dealing with paragraphs and filling. Adapted from MicroEMACS 3.6
                      3:  * and GNU-ified by mwm@ucbvax.         Several bug fixes by blarson@usc-oberon.
                      4:  */
                      5: #include "def.h"
                      6:
1.2     ! millert     7: static int      fillcol = 70;
1.1       deraadt     8: #define MAXWORD 256
                      9:
                     10: /*
                     11:  * go back to the begining of the current paragraph
                     12:  * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
                     13:  * combination to delimit the begining of a paragraph
                     14:  */
1.2     ! millert    15: /* ARGSUSED */
1.1       deraadt    16: gotobop(f, n)
                     17: {
1.2     ! millert    18:        if (n < 0)              /* the other way... */
1.1       deraadt    19:                return gotoeop(f, -n);
                     20:
                     21:        while (n-- > 0) {       /* for each one asked for */
                     22:
                     23:                /* first scan back until we are in a word */
1.2     ! millert    24:
        !            25:                while (backchar(FFRAND, 1) && !inword()) {
        !            26:                }
1.1       deraadt    27:                curwp->w_doto = 0;      /* and go to the B-O-Line */
                     28:
1.2     ! millert    29:                /*
        !            30:                 * and scan back until we hit a <NL><SP> <NL><TAB> or
        !            31:                 * <NL><NL>
        !            32:                 */
1.1       deraadt    33:                while (lback(curwp->w_dotp) != curbp->b_linep)
                     34:                        if (llength(lback(curwp->w_dotp))
1.2     ! millert    35:                            && lgetc(curwp->w_dotp, 0) != ' '
        !            36:                            && lgetc(curwp->w_dotp, 0) != '.'
        !            37:                            && lgetc(curwp->w_dotp, 0) != '\t')
1.1       deraadt    38:                                curwp->w_dotp = lback(curwp->w_dotp);
                     39:                        else {
1.2     ! millert    40:                                if (llength(lback(curwp->w_dotp))
        !            41:                                    && lgetc(curwp->w_dotp, 0) == '.') {
        !            42:                                        curwp->w_dotp = lforw(curwp->w_dotp);
        !            43:                                        if (curwp->w_dotp == curbp->b_linep) {
        !            44:                                                /*
        !            45:                                                 * beond end of buffer,
        !            46:                                                 * cleanup time
        !            47:                                                 */
        !            48:                                                curwp->w_dotp = lback(curwp->w_dotp);
        !            49:                                                curwp->w_doto = llength(curwp->w_dotp);
        !            50:                                        }
        !            51:                                }
        !            52:                                break;
        !            53:                        }
1.1       deraadt    54:        }
1.2     ! millert    55:        curwp->w_flag |= WFMOVE;/* force screen update */
1.1       deraadt    56:        return TRUE;
                     57: }
                     58:
                     59: /*
                     60:  * go forword to the end of the current paragraph
                     61:  * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
                     62:  * combination to delimit the begining of a paragraph
                     63:  */
1.2     ! millert    64: /* ARGSUSED */
1.1       deraadt    65: gotoeop(f, n)
                     66: {
1.2     ! millert    67:        if (n < 0)              /* the other way... */
1.1       deraadt    68:                return gotobop(f, -n);
                     69:
                     70:        while (n-- > 0) {       /* for each one asked for */
                     71:
                     72:                /* Find the first word on/after the current line */
                     73:                curwp->w_doto = 0;
1.2     ! millert    74:                while (forwchar(FFRAND, 1) && !inword()) {
        !            75:                }
1.1       deraadt    76:                curwp->w_doto = 0;
                     77:                curwp->w_dotp = lforw(curwp->w_dotp);
                     78:                /* and scan forword until we hit a <NL><SP> or ... */
                     79:                while (curwp->w_dotp != curbp->b_linep) {
                     80:                        if (llength(curwp->w_dotp)
1.2     ! millert    81:                            && lgetc(curwp->w_dotp, 0) != ' '
        !            82:                            && lgetc(curwp->w_dotp, 0) != '.'
        !            83:                            && lgetc(curwp->w_dotp, 0) != '\t')
1.1       deraadt    84:                                curwp->w_dotp = lforw(curwp->w_dotp);
                     85:                        else
                     86:                                break;
                     87:                }
1.2     ! millert    88:                if (curwp->w_dotp == curbp->b_linep) {
1.1       deraadt    89:                        /* beond end of buffer, cleanup time */
                     90:                        curwp->w_dotp = lback(curwp->w_dotp);
                     91:                        curwp->w_doto = llength(curwp->w_dotp);
1.2     ! millert    92:                        break;
1.1       deraadt    93:                }
                     94:        }
1.2     ! millert    95:        curwp->w_flag |= WFMOVE;/* force screen update */
1.1       deraadt    96:        return TRUE;
                     97: }
                     98:
                     99: /*
                    100:  * Fill the current paragraph according to the current
                    101:  * fill column
                    102:  */
1.2     ! millert   103: /* ARGSUSED */
1.1       deraadt   104: fillpara(f, n)
                    105: {
1.2     ! millert   106:        register int    c;      /* current char durring scan     */
        !           107:        register int    wordlen;/* length of current word        */
        !           108:        register int    clength;/* position on line during fill */
        !           109:        register int    i;      /* index during word copy        */
        !           110:        register int    eopflag;/* Are we at the End-Of-Paragraph? */
        !           111:        int             firstflag;      /* first word? (needs no space) */
        !           112:        int             newlength;      /* tentative new line length     */
        !           113:        int             eolflag;/* was at end of line            */
        !           114:        LINE           *eopline;/* pointer to line just past EOP */
        !           115:        char            wbuf[MAXWORD];  /* buffer for current word       */
1.1       deraadt   116:
                    117:        /* record the pointer to the line just past the EOP */
                    118:        (VOID) gotoeop(FFRAND, 1);
1.2     ! millert   119:        if (curwp->w_doto != 0) {
1.1       deraadt   120:                /* paragraph ends at end of buffer */
                    121:                (VOID) lnewline();
                    122:                eopline = lforw(curwp->w_dotp);
1.2     ! millert   123:        } else
        !           124:                eopline = curwp->w_dotp;
1.1       deraadt   125:
                    126:        /* and back top the begining of the paragraph */
                    127:        (VOID) gotobop(FFRAND, 1);
                    128:
                    129:        /* initialize various info */
1.2     ! millert   130:        while (!inword() && forwchar(FFRAND, 1)) {
        !           131:        }
1.1       deraadt   132:        clength = curwp->w_doto;
                    133:        wordlen = 0;
                    134:
                    135:        /* scan through lines, filling words */
                    136:        firstflag = TRUE;
                    137:        eopflag = FALSE;
                    138:        while (!eopflag) {
                    139:                /* get the next character in the paragraph */
1.2     ! millert   140:                if (eolflag = (curwp->w_doto == llength(curwp->w_dotp))) {
1.1       deraadt   141:                        c = ' ';
                    142:                        if (lforw(curwp->w_dotp) == eopline)
                    143:                                eopflag = TRUE;
                    144:                } else
                    145:                        c = lgetc(curwp->w_dotp, curwp->w_doto);
                    146:
                    147:                /* and then delete it */
                    148:                if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag)
                    149:                        return FALSE;
                    150:
                    151:                /* if not a separator, just add it in */
                    152:                if (c != ' ' && c != '\t') {
                    153:                        if (wordlen < MAXWORD - 1)
                    154:                                wbuf[wordlen++] = c;
                    155:                        else {
1.2     ! millert   156:                                /*
        !           157:                                 * You loose chars beyond MAXWORD if the word
1.1       deraadt   158:                                 * is to long. I'm to lazy to fix it now; it
1.2     ! millert   159:                                 * just silently truncated the word before,
        !           160:                                 * so I get to feel smug.
1.1       deraadt   161:                                 */
                    162:                                ewprintf("Word too long!");
                    163:                        }
                    164:                } else if (wordlen) {
                    165:                        /* calculate tenatitive new length with word added */
                    166:                        newlength = clength + 1 + wordlen;
1.2     ! millert   167:                        /*
        !           168:                         * if at end of line or at doublespace and previous
1.1       deraadt   169:                         * character was one of '.','?','!' doublespace here.
                    170:                         */
1.2     ! millert   171:                        if ((eolflag || curwp->w_doto == llength(curwp->w_dotp)
        !           172:                         || (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' '
        !           173:                             || c == '\t')
        !           174:                            && ISEOSP(wbuf[wordlen - 1])
        !           175:                            && wordlen < MAXWORD - 1)
1.1       deraadt   176:                                wbuf[wordlen++] = ' ';
                    177:                        /* at a word break with a word waiting */
                    178:                        if (newlength <= fillcol) {
                    179:                                /* add word to current line */
                    180:                                if (!firstflag) {
                    181:                                        (VOID) linsert(1, ' ');
                    182:                                        ++clength;
                    183:                                }
                    184:                                firstflag = FALSE;
                    185:                        } else {
1.2     ! millert   186:                                if (curwp->w_doto > 0 &&
        !           187:                                    lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') {
1.1       deraadt   188:                                        curwp->w_doto -= 1;
                    189:                                        (VOID) ldelete((RSIZE) 1, KNONE);
                    190:                                }
                    191:                                /* start a new line */
                    192:                                (VOID) lnewline();
                    193:                                clength = 0;
                    194:                        }
                    195:
                    196:                        /* and add the word in in either case */
1.2     ! millert   197:                        for (i = 0; i < wordlen; i++) {
1.1       deraadt   198:                                (VOID) linsert(1, wbuf[i]);
                    199:                                ++clength;
                    200:                        }
                    201:                        wordlen = 0;
                    202:                }
                    203:        }
                    204:        /* and add a last newline for the end of our new paragraph */
                    205:        (VOID) lnewline();
1.2     ! millert   206:        /*
        !           207:         * we realy should wind up where we started, (which is hard to keep
1.1       deraadt   208:         * track of) but I think the end of the last line is better than the
1.2     ! millert   209:         * begining of the blank line.
        !           210:         */
1.1       deraadt   211:        (VOID) backchar(FFRAND, 1);
                    212:        return TRUE;
                    213: }
                    214:
                    215: /* delete n paragraphs starting with the current one */
1.2     ! millert   216: /* ARGSUSED */
1.1       deraadt   217: killpara(f, n)
                    218: {
1.2     ! millert   219:        register int    status; /* returned status of functions */
1.1       deraadt   220:
                    221:        while (n--) {           /* for each paragraph to delete */
                    222:
                    223:                /* mark out the end and begining of the para to delete */
                    224:                (VOID) gotoeop(FFRAND, 1);
                    225:
                    226:                /* set the mark here */
                    227:                curwp->w_markp = curwp->w_dotp;
                    228:                curwp->w_marko = curwp->w_doto;
                    229:
                    230:                /* go to the begining of the paragraph */
                    231:                (VOID) gotobop(FFRAND, 1);
                    232:                curwp->w_doto = 0;      /* force us to the begining of line */
                    233:
                    234:                /* and delete it */
                    235:                if ((status = killregion(FFRAND, 1)) != TRUE)
                    236:                        return status;
                    237:
                    238:                /* and clean up the 2 extra lines */
                    239:                (VOID) ldelete((RSIZE) 1, KFORW);
                    240:        }
                    241:        return TRUE;
                    242: }
                    243:
                    244: /*
                    245:  * check to see if we're past fillcol, and if so,
                    246:  * justify this line. As a last step, justify the line.
                    247:  */
1.2     ! millert   248: /* ARGSUSED */
1.1       deraadt   249: fillword(f, n)
                    250: {
1.2     ! millert   251:        register char   c;
        !           252:        register int    col, i, nce;
1.1       deraadt   253:
                    254:        for (i = col = 0; col <= fillcol; ++i, ++col) {
1.2     ! millert   255:                if (i == curwp->w_doto)
        !           256:                        return selfinsert(f, n);
1.1       deraadt   257:                c = lgetc(curwp->w_dotp, i);
                    258:                if (c == '\t'
                    259: #ifdef NOTAB
1.2     ! millert   260:                    && !(curbp->b_flag & BFNOTAB)
1.1       deraadt   261: #endif
1.2     ! millert   262:                        )
        !           263:                        col |= 0x07;
        !           264:                else if (ISCTRL(c) != FALSE)
        !           265:                        ++col;
1.1       deraadt   266:        }
                    267:        if (curwp->w_doto != llength(curwp->w_dotp)) {
                    268:                (VOID) selfinsert(f, n);
                    269:                nce = llength(curwp->w_dotp) - curwp->w_doto;
1.2     ! millert   270:        } else
        !           271:                nce = 0;
1.1       deraadt   272:        curwp->w_doto = i;
                    273:
                    274:        if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
                    275:                do {
                    276:                        (VOID) backchar(FFRAND, 1);
                    277:                } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
1.2     ! millert   278:                         && c != '\t' && curwp->w_doto > 0);
1.1       deraadt   279:
                    280:        if (curwp->w_doto == 0)
                    281:                do {
                    282:                        (VOID) forwchar(FFRAND, 1);
                    283:                } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
1.2     ! millert   284:                    && c != '\t' && curwp->w_doto < llength(curwp->w_dotp));
1.1       deraadt   285:
                    286:        (VOID) delwhite(FFRAND, 1);
                    287:        (VOID) lnewline();
                    288:        i = llength(curwp->w_dotp) - nce;
1.2     ! millert   289:        curwp->w_doto = i > 0 ? i : 0;
1.1       deraadt   290:        curwp->w_flag |= WFMOVE;
1.2     ! millert   291:        if (nce == 0 && curwp->w_doto != 0)
        !           292:                return fillword(f, n);
1.1       deraadt   293:        return TRUE;
                    294: }
                    295:
                    296: /* Set fill column to n. */
1.2     ! millert   297: setfillcol(f, n)
        !           298: {
        !           299:        extern int      getcolpos();
1.1       deraadt   300:
                    301:        fillcol = ((f & FFARG) ? n : getcolpos());
                    302:        ewprintf("Fill column set to %d", fillcol);
                    303:        return TRUE;
                    304: }