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

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