1 /*
2  *	User text formatting functions
3  *	Copyright
4  *		(C) 1992 Joseph H. Allen
5  *
6  *	This file is part of JOE (Joe's Own Editor)
7  */
8 #include "types.h"
9 
10 /* Center line cursor is on and move cursor to beginning of next line */
11 
ucenter(W * w,int k)12 int ucenter(W *w, int k)
13 {
14 	BW *bw;
15 	P *p, *q;
16 	off_t endcol, begcol, x;
17 	int c;
18 
19 	WIND_BW(bw, w);
20 	p = bw->cursor;
21 
22 	p_goto_eol(p);
23 	while (joe_isblank(bw->b->o.charmap, (c = prgetc(p))))
24 		/* do nothing */;
25 	if (c == '\n') {
26 		pgetc(p);
27 		goto done;
28 	}
29 	if (c == NO_MORE_DATA)
30 		goto done;
31 	pgetc(p);
32 	endcol = piscol(p);
33 
34 	p_goto_bol(p);
35 	while (joe_isblank(bw->b->o.charmap, (c = pgetc(p))))
36 		/* do nothing */;
37 	if (c == '\n') {
38 		prgetc(p);
39 		goto done;
40 	}
41 	if (c == NO_MORE_DATA)
42 		goto done;
43 	prgetc(p);
44 	begcol = piscol(p);
45 
46 	if (endcol - begcol > bw->o.rmargin + bw->o.lmargin)
47 		goto done;
48 
49 	q = pdup(p, "ucenter");
50 	p_goto_bol(q);
51 	bdel(q, p);
52 	prm(q);
53 
54 	for (x = 0; x != (bw->o.lmargin + bw->o.rmargin) / 2 - (endcol - begcol) / 2; ++x)
55 		binsc(p, ' ');
56 
57       done:
58 	if (!pnextl(p)) {
59 		binsc(p, '\n');
60 		pgetc(p);
61 		return -1;
62 	} else
63 		return 0;
64 }
65 
66 /* Return true if c is a character which can indent a paragraph */
67 
68 /*   > is for mail/news
69  *   * is for C comments
70  *   / is for C++ comments
71  *   # is for shell script comments
72  *   % is for TeX comments
73  */
74 
cpara(BW * bw,int c)75 static int cpara(BW *bw, int c)
76 {
77 	if (c == ' ' || c == '\t')
78 		return 1;
79 	if (bw->o.cpara) {
80 		const char *s = bw->o.cpara;
81 		while (*s) {
82 			if (utf8_decode_fwrd(&s, NULL) == c)
83 				return 1;
84 		}
85 	}
86 	return 0;
87 #ifdef junk
88 	if (c == ' ' || c == '\t' || c == '\\' ||
89 	    c == '>' || c == '|' || c == ':' || c == '*' || c == '/' ||
90 	    c == ',' || c == '.' || c == '?' || c == ';' || c == ']' ||
91 	    c == '}' || c == '=' || c == '+' || c == '-' || c == '_' ||
92 	    c == ')' || c == '&' || c == '^' || c == '%' || c == '$' ||
93 	    c == '#' || c == '@' || c == '!' || c == '~')
94 		return 1;
95 	else
96 		return 0;
97 #endif
98 }
99 
100 /* Return true if this first non-whitespace character means
101    we are not a paragraph for sure (for example, '.' in nroff) */
102 
cnotpara(BW * bw,int c)103 static int cnotpara(BW *bw, int c)
104 {
105 	const char *s;
106 	if (bw->o.cnotpara) {
107 		s = bw->o.cnotpara;
108 		while (*s) {
109 			if (c == utf8_decode_fwrd(&s, NULL))
110 				return 1;
111 		}
112 	}
113 	return 0;
114 }
115 
116 /* Return true if line is definitely not a paragraph line.
117  * Lines which aren't paragraph lines:
118  *  1) Blank lines
119  *  2) Lines which begin with '.'
120  */
121 
pisnpara(BW * bw,P * p)122 static int pisnpara(BW *bw, P *p)
123 {
124 	P *q;
125 	int c;
126 
127 	q = pdup(p, "pisnpara");
128 	p_goto_bol(q);
129 	while (cpara(bw, c = pgetc(q)))
130 		/* do nothing */;
131 	prm(q);
132 	if (cnotpara(bw, c) || c == '\r' || c == '\n')
133 		return 1;
134 	else
135 		return 0;
136 }
137 
138 /* Determine amount of indentation on current line.  Set first
139    to include '-' and '*' bullets. */
140 
nindent(BW * bw,P * p,int first)141 static off_t nindent(BW *bw, P *p, int first)
142 {
143 	P *q = pdup(p, "nindent");
144 	off_t col;
145 	int c;
146 
147 	p_goto_bol(q);
148 	do {
149 		col = q->col;
150 	} while (cpara(bw, (c = pgetc(q))));
151 	if (first && (c == '-' || c == '*')) {
152 		c = pgetc(q);
153 		if (c == ' ') {
154 			col = q->col;
155 		}
156 	}
157 	prm(q);
158 	return col;
159 }
160 
161 /* Get indentation prefix column */
162 
prefix(BW * bw,P * p,int up)163 static off_t prefix(BW *bw, P *p,int up)
164 {
165 	off_t len;
166 	P *q = pdup(p, "prefix");
167 
168 	p_goto_bol(q);
169 	while (cpara(bw, brch(q)))
170 		pgetc(q);
171 	while (!pisbol(q)) {
172 		/* int c; */
173 		if (!joe_isblank(p->b->o.charmap, ( /* c = */ prgetc(q)))) {
174 		/*
175 			if (up && (c == '*' || c == '-')) {
176 				if (!pisbol(q)) {
177 					c = prgetc(q);
178 					pgetc(q);
179 					if (c == ' ' || c == '\t')
180 						goto skip;
181 				} else
182 					goto skip;
183 			}
184 			pgetc(q);
185 		*/
186 			break;
187 		/* 	skip:; */
188 		}
189 	}
190 	len = piscol(q);
191 	prm(q);
192 	return len;
193 }
194 
195 /* Move pointer to beginning of paragraph
196  *
197  * This function simply moves backwards until it sees:
198  *  0) The beginning of the file
199  *  1) A blank line
200  *  2) A line with a different indentation prefix
201  *  3) A line with indentation greater than that of the line we started with
202  *  4) A line with indentation less than that of the starting line, but with
203  *     a blank line (or beginning of file) preceding it.
204  */
205 
206 int within = 0;
207 
pbop(BW * bw,P * p)208 P *pbop(BW *bw, P *p)
209 {
210 	off_t indent;
211 	off_t prelen;
212 	P *last;
213 
214 	p_goto_bol(p);
215 	indent = nindent(bw, p, 0);
216 	prelen = prefix(bw, p, 0);
217 	last = pdup(p, "pbop");
218 	while (!pisbof(p) && (!within || !markb || p->byte > markb->byte)) {
219 		off_t ind;
220 		off_t len;
221 
222 		pprevl(p);
223 		p_goto_bol(p);
224 		ind = nindent(bw, p, 0);
225 		len = prefix(bw, p, 0);
226 		if (pisnpara(bw, p) || len != prelen) {
227 			pset(p, last);
228 			break;
229 		}
230 		if (ind > indent) {
231 /*
232 			int ok = 1;
233 			P *q = pdup(p, "pbop");
234 			if (pprevl(q)) {
235 				p_goto_bol(q);
236 				if (nindent(bw, q, 0) == ind)
237 					ok = 0;
238 			}
239 			prm(q);
240 			if (!ok)
241 				pnextl(p);
242 */
243 			break;
244 		}
245 		if (ind < indent) {
246 			pset(p, last);
247 			break;
248 			/* if (pisbof(p)) {
249 				break;
250 			}
251 			pprevl(p);
252 			p_goto_bol(p);
253 			if (pisnpara(bw, p)) {
254 				pnextl(p);
255 				break;
256 			} else {
257 				pnextl(p);
258 				pnextl(p);
259 				break;
260 			} */
261 		}
262 		pset(last, p);
263 	}
264 	prm(last);
265 	return p;
266 }
267 
268 /* Move pointer to end of paragraph.  Pointer must already be on first
269  * line of paragraph for this to work correctly.
270  *
271  * This function moves forwards until it sees:
272  *  0) The end of the file.
273  *  1) A blank line
274  *  2) A line with indentation different from the second line of the paragraph
275  *  3) A line with prefix column different from first line
276  */
277 
peop(BW * bw,P * p)278 P *peop(BW *bw, P *p)
279 {
280 	off_t indent;
281 	off_t prelen;
282 
283 	if (!pnextl(p) || pisnpara(bw, p) || (within && markk && p->byte >= markk->byte))
284 		return p;
285 	indent = nindent(bw, p, 0);
286 	prelen = prefix(bw, p, 0);
287 	while (pnextl(p) && (!within || !markk || p->byte < markk->byte)) {
288 		off_t ind = nindent(bw, p, 0);
289 		off_t len = prefix(bw, p, 0);
290 
291 		if (ind != indent || len != prelen || pisnpara(bw, p))
292 			break;
293 	}
294 	return p;
295 }
296 
297 /* Motion commands */
298 
ubop(W * w,int k)299 int ubop(W *w, int k)
300 {
301 	BW *bw;
302 	P *q;
303 	WIND_BW(bw, w);
304 	q = pdup(bw->cursor, "ubop");
305 
306       up:
307 	while (pisnpara(bw, q) && !pisbof(q) && (!within || !markb || q->byte > markb->byte))
308 		pprevl(q);
309 	pbop(bw, q);
310 	if (q->byte != bw->cursor->byte) {
311 		pset(bw->cursor, q);
312 		prm(q);
313 		return 0;
314 	} else if (!pisbof(q)) {
315 		prgetc(q);
316 		goto up;
317 	} else {
318 		prm(q);
319 		return -1;
320 	}
321 }
322 
ueop(W * w,int k)323 int ueop(W *w, int k)
324 {
325 	P *q;
326 	BW *bw;
327 	WIND_BW(bw, w);
328 	q = pdup(bw->cursor, "ueop");
329 
330       up:
331 	while (pisnpara(bw, q) && !piseof(q))
332 		pnextl(q);
333 	pbop(bw, q);
334 	peop(bw, q);
335 	if (q->byte != bw->cursor->byte) {
336 		pset(bw->cursor, q);
337 		prm(q);
338 		return 0;
339 	} else if (!piseof(q)) {
340 		pnextl(q);
341 		goto up;
342 	} else {
343 		prm(q);
344 		return -1;
345 	}
346 }
347 
348 /* Wrap word.  If 'french' is set, only one space will be placed
349  * after . ? or !
350  */
351 
wrapword(BW * bw,P * p,off_t indent,int french,int no_over,char * indents)352 void wrapword(BW *bw, P *p, off_t indent, int french, int no_over, char *indents)
353 {
354 	P *q;
355 	P *r;
356 	P *s;
357 	int rmf = 0;
358 	int c;
359 	off_t to = p->byte;
360 	int my_indents = 0;
361 
362 	/* autoindent when called by utype */
363 	if (!indents) {
364 		/* Get indentation prefix from beginning of line */
365 		s = pdup(p, "wrapword");
366 		p_goto_bol(s);
367 		pbop(bw, s);
368 		/* Record indentation of second line of paragraph, of first
369 		 * line if there is only one line */
370 		q = pdup(s, "wrapword");
371 		pnextl(q);
372 		if (q->line < p->line) {
373 			/* Second line */
374 			P *tr = pdup(q, "wrapword");
375 
376 			indent = nindent(bw, q, 0);
377 			pcol(tr, indent);
378 			indents = brs(q, tr->byte - q->byte); /* Risky */
379 			prm(tr);
380 		} else {
381 			/* First line */
382 			P *tr = pdup(s, "uformat");
383 			ptrdiff_t x, y;
384 
385 			indent = nindent(bw, s, 1);
386 			pcol(tr, indent);
387 			indents = brs(s, tr->byte - s->byte); /* Risky */
388 			prm(tr);
389 			if (!bw->o.autoindent) {
390 				/* Don't indent second line of single-line paragraphs if autoindent is off */
391 				ptrdiff_t tx = zlen(indents);
392 				ptrdiff_t orgx = tx;
393 				while (tx && (indents[tx - 1] == ' ' || indents[tx - 1] == '\t'))
394 					indents[--tx] = 0;
395 				if (tx && orgx != tx) {
396 					indents[tx++] = ' ';
397 					indents[tx] = 0;
398 				}
399 				indent = txtwidth1(bw->o.charmap, bw->o.tab, indents, tx);
400 			}
401 			for (x = 0; indents[x] && (indents[x] == ' ' || indents[x] == '\t'); ++x);
402 			y = zlen(indents);
403 			while (y && (indents[y - 1] == ' ' || indents[y - 1] == '\t'))
404 				--y;
405 			/* Don't duplicate bullet */
406 			if (y && ((indents[y - 1] == '*' && !cpara(bw, '*')) || (indents[y - 1] == '-' && !cpara(bw, '-'))) &&
407 			    (y == 1 || indents[y - 2] == ' ' || indents[y - 2] == '\t'))
408 			    	indents[y - 1] = ' ';
409 			/* Fix C comment */
410 			if (indents[x] == '/' && indents[x + 1] == '*')
411 				indents[x] = ' ';
412 		}
413 		if (bw->o.lmargin > indent) {
414 			int x;
415 			for (x = 0; indents[x] == ' ' || indents[x] == '\t'; ++x);
416 			if (!indents[x]) {
417 				joe_free(indents);
418 				indent = bw->o.lmargin;
419 				indents = (char *)joe_malloc(indent+1); /* Risky */
420 				for (x = 0; x != indent; ++x)
421 					indents[x] = ' ';
422 				indents[x] = 0;
423 			}
424 		}
425 		my_indents = 1;
426 		prm(q);
427 		prm(s);
428 	}
429 
430 
431 /*
432 	if(!indents) {
433 		int f = 0;
434 		P *r = pdup(p);
435 
436 		p_goto_bol(r);
437 		q = pdup(r);
438 		while(cpara(c = brc(q))) {
439 			if(!joe_isblank(c))
440 				f = 1;
441 			pgetc(q);
442 		}
443 		if(f) {
444 			indents = brs(r, q->byte-r->byte);
445 			rmf = 1;
446 			if(indents[0] == '/' && indents[1] == '*')
447 				indents[0] = ' ';
448 		}
449 		prm(r);
450 		prm(q);
451 	}
452 */
453 
454 	/* Get to beginning of word */
455 	while (!pisbol(p) && piscol(p) > indent && !joe_isblank(p->b->o.charmap, prgetc(p)))
456 		/* do nothing */;
457 
458 	/* If we found the beginning of a word... */
459 	if (!pisbol(p) && piscol(p) > indent) {
460 		/* Move q to two (or one if 'french' is set) spaces after end of previous
461 		   word */
462 		q = pdup(p, "wrapword");
463 		while (!pisbol(q))
464 			if (!joe_isblank(p->b->o.charmap, (c = prgetc(q)))) {
465 				pgetc(q);
466 				if ((c == '.' || c == '?' || c == '!')
467 				    && q->byte != p->byte && !french)
468 					pgetc(q);
469 				break;
470 			}
471 		pgetc(p);
472 
473 		/* Delete space between start of word and end of previous word */
474 		to -= p->byte - q->byte;
475 		bdel(q, p);
476 		prm(q);
477 
478 		if (bw->o.flowed) {
479 			binsc(p, ' ');
480 			pgetc(p);
481 			++to;
482 		}
483 
484 		/* Move word to beginning of next line */
485 		binsc(p, '\n');
486 
487 		/* When overtype is on, do not insert lines */
488 		if (!no_over && p->b->o.overtype){
489 			/* delete the next line break which is unnecessary */
490 			r = pdup(p, "wrapword");
491 			/* p_goto_eol(r); */
492 			pgetc(r);
493 			p_goto_eol(r);
494 			s = pdup(r, "wrapword");
495 			pgetc(r);
496 			bdel(s,r);
497 			binsc(r, ' ');
498 
499 			/* Now we got to take care that all subsequent lines are not longer than the right margin */
500 			/* Move cursor to right margin */
501 			pfwrd(r, r->b->o.rmargin - r->col);
502 
503 			/* Make a copy of the cursor and move the copied cursor to the end of the line */
504 			prm(s);
505 			s = pdup(r, "wrapword");
506 			p_goto_eol(s);
507 
508 			/* If s is located behind r then the line goes beyond the right margin and we need to call wordwrap() for that line. */
509 /*
510 			if (r->byte < s->byte){
511 				wrapword(bw, r, indent, french, 1, indents);
512 			}
513 */
514 			prm(r);
515 			prm(s);
516 		}
517 
518 		++to;
519 		if (p->b->o.crlf)
520 			++to;
521 		pgetc(p);
522 
523 		/* Indent to left margin */
524 		if (indents) {
525 			binss(p, indents);
526 			to += zlen(indents);
527 		} else
528 			while (indent--) {
529 				binsc(p, ' ');
530 				++to;
531 			}
532 
533 		if (rmf)
534 			joe_free(indents);
535 	}
536 
537 	/* Move cursor back to original position */
538 	pfwrd(p, to - p->byte);
539 	if (my_indents)
540 		joe_free(indents);
541 }
542 
543 /* Reformat paragraph */
544 
uformat(W * w,int k)545 int uformat(W *w, int k)
546 {
547 	off_t indent;
548 	char *indents;
549 	B *buf;
550 	P *b;
551 	off_t curoff;
552 	int c;
553 	P *p, *q;
554 	BW *bw;
555 	int flag;
556 	WIND_BW(bw, w);
557 
558 	p = pdup(bw->cursor, "uformat");
559 	p_goto_bol(p);
560 
561 	/* Do nothing if we're not on a paragraph line */
562 	if (pisnpara(bw, p)) {
563 		prm(p);
564 		return 0;
565 	}
566 
567 	/* Move p to beginning of paragraph, bw->cursor to end of paragraph and
568 	 * set curoff to original cursor offset within the paragraph */
569 	pbop(bw, p);
570 	curoff = bw->cursor->byte - p->byte;
571 	pset(bw->cursor, p);
572 	peop(bw, bw->cursor);
573 
574 	/* Ensure that paragraph ends on a beginning of a line */
575 	if (!pisbol(bw->cursor))
576 		binsc(bw->cursor, '\n'), pgetc(bw->cursor);
577 
578 	/* Record indentation of second line of paragraph, of first line if there
579 	 * is only one line */
580 	q = pdup(p, "uformat");
581 	pnextl(q);
582 	if (q->line != bw->cursor->line) {
583 		P *r = pdup(q, "uformat");
584 
585 		indent = nindent(bw, q, 0);
586 		pcol(r, indent);
587 		indents = brs(q, r->byte - q->byte); /* Risky */
588 		prm(r);
589 	} else {
590 		P *r = pdup(p, "uformat");
591 		ptrdiff_t x, y;
592 		indent = nindent(bw, p, 1); /* allowing * and - here */
593 		pcol(r, indent);
594 		indents = brs(p, r->byte - p->byte); /* Risky */
595 		prm(r);
596 		if (!bw->o.autoindent) {
597 			/* Don't indent second line of single-line paragraphs if autoindent is off */
598 			ptrdiff_t tx = zlen(indents);
599 			while (tx && (indents[tx - 1] == ' ' || indents[tx - 1] == '\t'))
600 				indents[--tx] = 0;
601 			if (tx) {
602 				indents[tx++] = ' ';
603 				indents[tx] = 0;
604 			}
605 			indent = txtwidth1(bw->o.charmap, bw->o.tab, indents, tx);
606 		}
607 		for (x = 0; indents[x] && (indents[x] == ' ' || indents[x] == '\t'); ++x);
608 		y = zlen(indents);
609 		while (y && (indents[y - 1] == ' ' || indents[y - 1] == '\t'))
610 			--y;
611 		/* Don't duplicate if it looks like a bullet */
612 		if (y && ((indents[y - 1] == '*' && !cpara(bw, '*')) || (indents[y - 1] == '-' && !cpara(bw, '-'))) &&
613 		    (y == 1 || indents[y - 2] == ' ' || indents[y - 2] == '\t'))
614 			indents[y - 1] = ' ';
615 		/* Fix C comment */
616 		if (indents[x] == '/' && indents[x + 1] == '*')
617 			indents[x] = ' ';
618 	}
619 	prm(q);
620 
621 	/* But if the left margin is greater, we use that instead */
622 	if (bw->o.lmargin > indent) {
623 		int x;
624 		for (x = 0; indents[x] == ' ' || indents[x] == '\t'; ++x);
625 		if (!indents[x]) {
626 			joe_free(indents);
627 			indent = bw->o.lmargin;
628 			indents = (char *)joe_malloc(indent+1); /* Risky, indent could be very large in theory */
629 			for (x = 0; x != indent; ++x)
630 				indents[x] = ' ';
631 			indents[x] = 0;
632 		}
633 	}
634 
635 	/* Cut paragraph into new buffer */
636 
637 	/* New buffer needs to inherit UTF-8 and CR-LF options */
638 	buf = bcpy(p, bw->cursor);
639 	buf->o.crlf = p->b->o.crlf;
640 	buf->o.charmap = p->b->o.charmap;
641 	bdel(p, bw->cursor);
642 
643 	/* text is in buffer.  insert it at cursor */
644 
645 	b = pdup(buf->bof, "uformat");
646 
647 	/* First line: preserve whitespace within this line
648 	   (but still apply french spacing after periods) */
649 	flag = 0;
650 	while (!piseof(b)) {
651 		c = brch(b);
652 		if (joe_isblank(b->b->o.charmap,c) || c == '\n') {
653 			int f = 0;
654 
655 			/* First space after end of word */
656 			if (flag && piscol(p) > bw->o.rmargin)
657 				wrapword(bw, p, indent, bw->o.french, 1, indents);
658 
659 			flag = 0;
660 
661 			/* Stop if we're at end of line */
662 			if (c == '\n' || piseolblank(b))
663 				break;
664 
665 			/* Set f if previous character was '.', '?' or '!' */
666 			if (!pisbof(b)) {
667 				P *d = pdup(b, "uformat");
668 				int g = prgetc(d);
669 				if (g=='.' || g=='?' || g=='!') {
670 					f = 1;
671 				}
672 				prm(d);
673 			}
674 
675 			if (f) {
676 				/* Skip past the whitespace. */
677 				while (joe_isblank(b->b->o.charmap, brc(b))) {
678 					if(b->byte == curoff)
679 						pset(bw->cursor, p);
680 					pgetc(b);
681 				}
682 
683 				/* Insert proper amount of whitespace */
684 				if (!piseof(b)) {
685 					if (!bw->o.french)
686 						binsc(p, ' '), pgetc(p);
687 					binsc(p, ' ');
688 					pgetc(p);
689 				}
690 			} else {
691 				/* Insert whitespace character, advance pointer */
692 				binsc(p, pgetc(b));
693 				pgetc(p);
694 			}
695 		} else {
696 			/* Insert characters of word and wrap if necessary */
697 			if (b->byte == curoff)
698 				pset(bw->cursor, p);
699 
700 			binsc(p, pgetc(b));
701 			pgetc(p);
702 			flag = 1;
703 		}
704 	}
705 
706 	/* Remaining lines: collapse whitespace */
707 
708 	flag = 0;
709 	while (!piseof(b)) {
710 		c = brc(b);
711 		if (joe_isblank(b->b->o.charmap,c) || c == '\n') {
712 			int f = 0;
713 			P *d;
714 			int g;
715 
716 			/* First space at end of word, wrap it */
717 			if (flag && piscol(p) > bw->o.rmargin)
718 				wrapword(bw, p, indent, bw->o.french, 1, indents);
719 
720 			flag = 0;
721 
722 			/* Detect end of sentence */
723 			d=pdup(b, "uformat");
724 			g=prgetc(d);
725 			if (g=='.' || g=='?' || g=='!') {
726 				f = 1;
727 			}
728 			prm(d);
729 
730 			/* Skip past the whitespace.  Skip over indentations */
731 		      loop:
732 
733 			c = brc(b);
734 			if (c == '\n') {
735 				if (b->byte == curoff)
736 					pset(bw->cursor, p);
737 
738 				pgetc(b);
739 				while (cpara(bw, (c=brch(b)))) {
740 					if (b->byte == curoff)
741 						pset(bw->cursor, p);
742 					pgetc(b);
743 				}
744 			}
745 
746 			if (joe_isblank(b->b->o.charmap,c)) {
747 				if(b->byte == curoff)
748 					pset(bw->cursor, p);
749 				pgetc(b);
750 				goto loop;
751 			}
752 
753 			/* Insert proper amount of whitespace */
754 			if (!piseof(b)) {
755 				if (f && !bw->o.french)
756 					binsc(p, ' '), pgetc(p);
757 				binsc(p, ' ');
758 				pgetc(p);
759 			}
760 		} else {
761 			/* Insert characters of word and wrap if necessary */
762 			if (b->byte == curoff)
763 				pset(bw->cursor, p);
764 
765 			binsc(p, pgetc(b));
766 			pgetc(p);
767 			flag = 1;
768 		}
769 	}
770 
771 	if (flag && piscol(p) > bw->o.rmargin)
772 		wrapword(bw, p, indent, bw->o.french, 1, indents);
773 
774 	binsc(p, '\n');
775 	prm(p);
776 	brm(buf);
777 	joe_free(indents);
778 	return 0;
779 }
780 
781 /* Format entire block */
782 
ufmtblk(W * w,int k)783 int ufmtblk(W *w, int k)
784 {
785 	BW *bw;
786 	WIND_BW(bw, w);
787 	if (markv(1) && bw->cursor->byte >= markb->byte && bw->cursor->byte <= markk->byte) {
788 		markk->end = 1;
789 		utomarkk(w, 0);
790 		within = 1;
791 		do {
792 			ubop(w, 0), uformat(w, 0);
793 		} while (bw->cursor->byte > markb->byte);
794 		within = 0;
795 		markk->end = 0;
796 		if (lightoff)
797 			unmark(w, 0);
798 		return 0;
799 	} else
800 		return uformat(w, 0);
801 }
802