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: }