[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.4

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