1 /* $MirOS: contrib/code/jupp/uformat.c,v 1.3 2010/04/08 15:31:05 tg Exp $ */
3 * User text formatting functions
5 * (C) 1992 Joseph H. Allen
7 * This file is part of JOE (Joe's Own Editor)
24 /* Center line cursor is on and move cursor to beginning of next line */
28 P *p = bw->cursor, *q;
29 long endcol, begcol, x;
33 while (joe_isblank(bw->b->o.charmap, (c = prgetc(p))))
39 if (c == NO_MORE_DATA)
45 while (joe_isblank(bw->b->o.charmap, (c = pgetc(p))))
51 if (c == NO_MORE_DATA)
56 if (endcol - begcol > bw->o.rmargin + bw->o.lmargin)
64 for (x = 0; x != (bw->o.lmargin + bw->o.rmargin) / 2 - (endcol - begcol) / 2; ++x)
76 /* Return true if c is a character which can indent a paragraph */
78 static int cpara(int c)
80 if (c == ' ' || c == '\t' || c == '\\' ||
81 c == '>' || c == '|' || c == ':' || c == '*' || c == '/' ||
82 c == ',' || c == '.' || c == '?' || c == ';' || c == ']' ||
83 c == '}' || c == '=' || c == '+' || c == '-' || c == '_' ||
84 c == ')' || c == '&' || c == '^' || c == '%' || c == '$' ||
85 c == '#' || c == '@' || c == '!' || c == '~')
91 /* Return true if line is definitly not a paragraph line.
92 * Lines which arn't paragraph lines:
94 * 2) Lines which begin with '.'
97 static int pisnpara(P *p)
104 while (cpara(c = pgetc(q)))
107 if (c == '.' || c == '\r' || c == '\n')
113 /* Determine amount of indentation on current line */
115 static long nindent(P *p)
123 } while (cpara(pgetc(q)));
128 /* Get indentation prefix column */
130 static long prefix(P *p)
136 while (cpara(brch(q)))
139 if (!joe_isblank(p->b->o.charmap, prgetc(q))) {
148 /* Move pointer to beginning of paragraph
150 * This function simply moves backwards until it sees:
151 * 0) The beginning of the file
153 * 2) A line with a different indentation prefix
154 * 3) A line with indentation greater than that of the line we started with
155 * 4) A line with indentation less than that of the starting line, but with
156 * a blank line (or beginning of file) preceeding it.
169 while (!pisbof(p) && (!within || !markb || p->byte > markb->byte)) {
177 if (pisnpara(p) || len != prelen) {
201 /* Move pointer to end of paragraph. Pointer must already be on first
202 * line of paragraph for this to work correctly.
204 * This function moves forwards until it sees:
205 * 0) The end of the file.
207 * 2) A line with indentation different from the second line of the paragraph
208 * 3) A line with prefix column different from first line
216 if (!pnextl(p) || pisnpara(p) || (within && markk && p->byte >= markk->byte))
220 while (pnextl(p) && (!within || !markk || p->byte < markk->byte)) {
221 long ind = nindent(p);
222 long len = prefix(p);
224 if (ind != indent || len != prelen || pisnpara(p))
230 /* Motion commands */
234 P *q = pdup(bw->cursor);
237 while (pisnpara(q) && !pisbof(q) && (!within || !markb || q->byte > markb->byte))
240 if (q->byte != bw->cursor->byte) {
244 } else if (!pisbof(q)) {
255 P *q = pdup(bw->cursor);
258 while (pisnpara(q) && !piseof(q))
262 if (q->byte != bw->cursor->byte) {
266 } else if (!piseof(q)) {
275 /* Wrap word. If 'french' is set, only one space will be placed
279 void wrapword(P *p, long int indent, int french, unsigned char *indents)
286 /* Get indentation prefix from beginning of line */
294 while(cpara(c = brc(q))) {
300 indents = brs(r, q->byte-r->byte);
302 if(indents[0] == '/' && indents[1] == '*')
310 /* Get to beginning of word */
311 while (!pisbol(p) && piscol(p) > indent && !joe_isblank(p->b->o.charmap, prgetc(p)))
314 /* If we found the beginning of a word... */
315 if (!pisbol(p) && piscol(p) > indent) {
316 /* Move q to two (or one if 'french' is set) spaces after end of previous
320 if (!joe_isblank(p->b->o.charmap, (c = prgetc(q)))) {
322 if ((c == '.' || c == '?' || c == '!')
323 && q->byte != p->byte && !french)
329 /* Delete space between start of word and end of previous word */
330 to -= p->byte - q->byte;
334 /* Move word to beginning of next line */
341 /* Indent to left margin */
344 to += strlen((char *)indents);
355 /* Move cursor back to original position */
356 pfwrd(p, to - p->byte);
359 /* Reformat paragraph */
364 unsigned char *indents;
371 p = pdup(bw->cursor);
374 /* Do nothing if we're not on a paragraph line */
380 /* Move p to beginning of paragraph, bw->cursor to end of paragraph and
381 * set curoff to original cursor offset within the paragraph */
383 curoff = bw->cursor->byte - p->byte;
387 /* Ensure that paragraph ends on a beginning of a line */
388 if (!pisbol(bw->cursor))
389 binsc(bw->cursor, '\n'), pgetc(bw->cursor);
391 /* Record indentation of second line of paragraph, of first line if there
392 * is only one line */
395 if (q->line != bw->cursor->line) {
400 indents = brs(q, r->byte - q->byte);
407 indents = brs(p, r->byte - p->byte);
412 /* But if the left margin is greater, we use that instead */
413 if (bw->o.lmargin > indent)
414 indent = bw->o.lmargin;
416 /* Cut paragraph into new buffer */
418 /* New buffer needs to inherit UTF-8 and CR-LF options */
419 buf = bcpy(p, bw->cursor);
420 buf->o.crlf = p->b->o.crlf;
421 buf->o.charmap = p->b->o.charmap;
424 /* text is in buffer. insert it at cursor */
430 /* Set cursor position if we're at original offset */
431 if (b->byte == curoff)
434 /* Get character from buffer */
437 /* Stop if we found end of line */
443 /* Stop if we found white-space followed by end of line */
444 if (joe_isblank(b->b->o.charmap, c) && piseolblank(b))
447 /* Insert character, advance pointer */
451 /* Do word wrap if we reach right margin */
452 if (piscol(p) > bw->o.rmargin && !joe_isblank(p->b->o.charmap,c)) {
453 wrapword(p, indent, bw->o.french, indents);
462 if (joe_isblank(b->b->o.charmap,c) || c == '\n') {
467 /* Set f if there are two spaces after . ? or ! instead of one */
468 /* (What is c was '\n'?) */
471 if (g=='.' || g=='?' || g=='!') {
474 if (joe_isspace(bw->b->o.charmap,brch(d)))
479 /* Skip past the whitespace. Skip over indentations */
484 if (b->byte == curoff)
488 while (cpara(c=brch(b))) {
489 if (b->byte == curoff)
495 if (joe_isblank(b->b->o.charmap,c)) {
496 if(b->byte == curoff)
502 /* Insert proper amount of whitespace */
504 if (f && !bw->o.french)
505 binsc(p, ' '), pgetc(p);
510 /* Insert characters of word and wrap if necessary */
511 if (b->byte == curoff)
516 if (piscol(p) > bw->o.rmargin)
517 wrapword(p, indent, bw->o.french, indents);
528 /* Format entire block */
532 if (markv(1) && bw->cursor->byte >= markb->byte && bw->cursor->byte <= markk->byte) {
537 ubop(bw), uformat(bw);
538 } while (bw->cursor->byte > markb->byte);