home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d352
/
mg.lha
/
MG
/
src.LZH
/
mg
/
paragraph.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
8KB
|
296 lines
/*
* Code for dealing with paragraphs and filling. Adapted from MicroEMACS 3.6
* and GNU-ified by mwm@ucbvax. Several bug fixes by blarson@usc-oberon.
*/
#include "def.h"
#include "line.h"
#include "buffer.h"
#include "window.h"
static int fillcol = 70;
#define MAXWORD 256
/*
* go back to the begining of the current paragraph here we look for a
* <NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the begining
* of a paragraph
*/
/* ARGSUSED */
gotobop(f, n)
{
if (n < 0) /* the other way... */
return gotoeop(f, -n);
while (n-- > 0) { /* for each one asked for */
/* first scan back until we are in a word */
while (backchar(FFRAND, 1) && !inword()) {
}
curwp->w_doto = 0; /* and go to the B-O-Line */
/*
* and scan back until we hit a <NL><SP> <NL><TAB> or
* <NL><NL>
*/
while (lback(curwp->w_dotp) != curbp->b_linep)
if (llength(lback(curwp->w_dotp))
&& lgetc(curwp->w_dotp, 0) != ' '
&& lgetc(curwp->w_dotp, 0) != '\t')
curwp->w_dotp = lback(curwp->w_dotp);
else
break;
}
curwp->w_flag |= WFMOVE;/* force screen update */
return TRUE;
}
/*
* go forword to the end of the current paragraph here we look for a <NL><NL>
* or <NL><TAB> or <NL><SPACE> combination to delimit the begining of a
* paragraph
*/
/* ARGSUSED */
gotoeop(f, n)
{
if (n < 0) /* the other way... */
return gotobop(f, -n);
while (n-- > 0) { /* for each one asked for */
/* Find the first word on/after the current line */
curwp->w_doto = 0;
while (forwchar(FFRAND, 1) && !inword()) {
}
curwp->w_doto = 0;
curwp->w_dotp = lforw(curwp->w_dotp);
/* and scan forword until we hit a <NL><SP> or ... */
while (curwp->w_dotp != curbp->b_linep) {
if (llength(curwp->w_dotp)
&& lgetc(curwp->w_dotp, 0) != ' '
&& lgetc(curwp->w_dotp, 0) != '\t')
curwp->w_dotp = lforw(curwp->w_dotp);
else
break;
}
if (curwp->w_dotp == curbp->b_linep) {
/* beond end of buffer, cleanup time */
curwp->w_dotp = lback(curwp->w_dotp);
curwp->w_doto = llength(curwp->w_dotp);
break;
}
}
curwp->w_flag |= WFMOVE;/* force screen update */
return TRUE;
}
/*
* Fill the current paragraph according to the current fill column
*/
/* ARGSUSED */
fillpara(f, n)
{
register int c; /* current char durring scan */
register int wordlen;/* length of current word */
register int clength;/* position on line during fill */
register int i; /* index during word copy */
register int eopflag;/* Are we at the End-Of-Paragraph? */
int firstflag; /* first word? (needs no space) */
int newlength; /* tentative new line length */
int eolflag;/* was at end of line */
struct line *eopline;/* pointer to line just past EOP */
char wbuf[MAXWORD]; /* buffer for current word */
/* record the pointer to the line just past the EOP */
(VOID) gotoeop(FFRAND, 1);
if (curwp->w_doto != 0) {
/* paragraph ends at end of buffer */
(VOID) lnewline();
eopline = lforw(curwp->w_dotp);
} else
eopline = curwp->w_dotp;
/* and back top the begining of the paragraph */
(VOID) gotobop(FFRAND, 1);
/* initialize various info */
while (!inword() && forwchar(FFRAND, 1)) {
}
for (clength = i = 0; i < curwp->w_doto; i += 1)
if (ltext(curwp->w_dotp)[i] == '\t')
clength |= 0x07;
else
clength += 1;
wordlen = 0;
/* scan through lines, filling words */
firstflag = TRUE;
eopflag = FALSE;
while (!eopflag) {
/* get the next character in the paragraph */
if (eolflag = (curwp->w_doto == llength(curwp->w_dotp))) {
c = ' ';
if (lforw(curwp->w_dotp) == eopline)
eopflag = TRUE;
} else
c = lgetc(curwp->w_dotp, curwp->w_doto);
/* and then delete it */
if (fdelete((RSIZE) 1, FALSE) == FALSE && !eopflag)
return FALSE;
/* if not a separator, just add it in */
if (c != ' ' && c != '\t') {
if (wordlen < MAXWORD - 1)
wbuf[wordlen++] = c;
else {
/*
* You loose chars beyond MAXWORD if the word
* is to long. I'm to lazy to fix it now; it
* just silently truncated the word before,
* so I get to feel smug.
*/
ewprintf("Word too long!");
}
} else if (wordlen) {
/* calculate tenatitive new length with word added */
newlength = clength + 1 + wordlen;
/*
* if at end of line or at doublespace and previous
* character was one of '.','?','!' doublespace here.
*/
if ((eolflag || curwp->w_doto == llength(curwp->w_dotp)
|| (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' '
|| c == '\t')
&& ISEOSP(wbuf[wordlen - 1])
&& wordlen < MAXWORD - 1)
wbuf[wordlen++] = ' ';
/* at a word break with a word waiting */
if (newlength <= fillcol) {
/* add word to current line */
if (!firstflag) {
(VOID) linsert(1, ' ');
++clength;
}
firstflag = FALSE;
} else {
if (curwp->w_doto > 0 &&
lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') {
curwp->w_doto -= 1;
(VOID) fdelete((RSIZE) 1, FALSE);
}
/* start a new line */
(VOID) lnewline();
clength = 0;
}
/* and add the word in in either case */
for (i = 0; i < wordlen; i++) {
(VOID) linsert(1, wbuf[i]);
++clength;
}
wordlen = 0;
}
}
/* and add a last newline for the end of our new paragraph */
(VOID) lnewline();
/*
* we realy should wind up where we started, (which is hard to keep
* track of) but I think the end of the last line is better than the
* begining of the blank line.
*/
(VOID) backchar(FFRAND, 1);
return TRUE;
}
/* delete n paragraphs starting with the current one */
/* ARGSUSED */
killpara(f, n)
{
register int status; /* returned status of functions */
while (n--) { /* for each paragraph to delete */
/* mark out the end and begining of the para to delete */
(VOID) gotoeop(FFRAND, 1);
/* set the mark here */
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
/* go to the begining of the paragraph */
(VOID) gotobop(FFRAND, 1);
curwp->w_doto = 0; /* force us to the begining of line */
/* and delete it */
if ((status = killregion(FFRAND, 1)) != TRUE)
return status;
/* and clean up the 2 extra lines */
(VOID) fdelete((RSIZE) 1, TRUE);
}
return TRUE;
}
/*
* check to see if we're past fillcol, and if so, justify this line. As a
* last step, justify the line.
*/
/* ARGSUSED */
fillword(f, n)
{
register char c;
register int col, i, nce;
for (i = col = 0; col <= fillcol; ++i, ++col) {
if (i == curwp->w_doto)
return selfinsert(f, n);
c = lgetc(curwp->w_dotp, i);
if (c == '\t'
#ifdef NOTAB
&& !(curbp->b_flag & BFNOTAB)
#endif
)
col |= 0x07;
else if (ISCTRL(c) != FALSE)
++col;
}
if (curwp->w_doto != llength(curwp->w_dotp)) {
(VOID) selfinsert(f, n);
nce = llength(curwp->w_dotp) - curwp->w_doto;
} else
nce = 0;
curwp->w_doto = i;
if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
do {
(VOID) backchar(FFRAND, 1);
} while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
&& c != '\t' && curwp->w_doto > 0);
if (curwp->w_doto == 0)
do {
(VOID) forwchar(FFRAND, 1);
} while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
&& c != '\t' && curwp->w_doto < llength(curwp->w_dotp));
(VOID) delwhite(FFRAND, 1);
(VOID) lnewline();
i = llength(curwp->w_dotp) - nce;
curwp->w_doto = i > 0 ? i : 0;
curwp->w_flag |= WFMOVE;
if (nce == 0 && curwp->w_doto != 0)
return fillword(f, n);
return TRUE;
}
/* Set fill column to n. */
setfillcol(f, n)
{
extern int getcolpos();
fillcol = ((f & FFARG) ? n : getcolpos());
ewprintf("Fill column set to %d", fillcol);
return TRUE;
}