Article View: comp.editors
Article #3080Re: Reformatting in vi (format program)
From: reeder
Date: Fri, 29 Jan 1988 17:36
Date: Fri, 29 Jan 1988 17:36
273 lines
7277 bytes
7277 bytes
Everyone has been talking about a paragraph formatting utility. Well
here one is. The comments should explain it all. I have run this on
XENIX and BSC systems. Enjoy!
/*
* Paragraph reformating utility from UNIX/Word Magazine Nov. '85
* Modified by Ed Reeder to allow for indentation, variable tabsize,
* line width, and BSD operation.
*
* This is best used within the vi editor, e.g.,
* !}rfm
*
* To allow for 1-key reformatting within vi, put the following
* in your /.exrc:
* map #1 !}rfm^V^M
* map #2 !}rfm^V^M}j
*
* This allows:
* Function Key 1 to reformat a paragraph, with the cursor placed
* at the beginning of the paragraph.
* Function Key 2 to reformat a paragraph, with the cursor placed
* at the beginning of the next paragraph.
*
* NOTE: for this to work you must have your function keys defined
* in your TERMCAP entry.
*
* By default rfm will assume that Tabs represent 8 characters and
* that the maximum line width will be 72 characters. These can be
* changed by specifying new values to rfm:
* rfm [-t tabsize] [-w width]
*/
#include "stdio.h"
#include <ctype.h>
#define YES 1
#define NO 0
#define LINELENGTH 72
#define TABSIZE 8 /* Number of characters a tab represents */
#ifdef bsd
#define STRCHR index /* Library routine to find 1st occurrence of a char */
#else
#define STRCHR strchr /* Library routine to find 1st occurrence of a char */
#endif
int c;
main( argc, argv )
int argc;
char *argv[];
{
int endchar; /* Does this word end a sentence? */
int getword(); /* Get next word on stdin */
int length; /* Length of word read by getword */
int count; /* number of characters on line so far */
int iindex = 0; /* number of chars in 'indentation' */
int icount = 0; /* number of apparent chars in 'indentation' */
int i;
int endwhile = 0;
int errflag = 0;
int tabsize = TABSIZE;
int linelength = LINELENGTH;
int strlen();
int printf();
int getopt();
char *strcat();
char *strcpy();
char word[255]; /* word read from stdin */
char istring[255]; /* indentation string */
char line[255]; /* output line */
extern int optind;
extern char *optarg;
/*
* Get any options
*/
while(( c = getopt( argc, argv, "t:w:" )) != EOF )
switch( c ) {
case 't':
for( i=0; optarg[i] != '\0'; i++ )
if( isdigit( optarg[i] ) == 0 )
errflag++;
if( errflag )
break;
tabsize = atoi( optarg );
break;
case 'w':
for( i=0; optarg[i] != '\0'; i++ )
if( isdigit( optarg[i] ) == 0 )
errflag++;
if( errflag )
break;
linelength = atoi( optarg );
break;
case '?':
errflag++;
}
if( errflag ) {
fprintf( stderr, "usage: %s [-t tabsize] [-w width]\n", argv[0] );
fprintf( stderr, "Defaults: tabsize=8, width=72\n" );
exit( 1 );
}
/*
* Let first line of non-white input define the level of indentation
*/
while(( c = getchar( )) != EOF ) {
switch( c ) {
/* Capture leading white space */
case '\t':
istring[iindex++] = c;
/* for tab allow for mixed tabs and spaces */
icount = ((icount / tabsize) * tabsize) + tabsize;
break;
case ' ':
istring[iindex++] = c;
icount++;
break;
/* Line was all white, reset indent info. */
case '\n':
putchar( '\n' );
iindex = icount = 0;
break;
/* Found 1st non-white character, sets indendentation */
default:
istring[iindex] = '\0';
count = icount;
ungetc( c, stdin ); /* push this char back */
strcpy( line, istring ); /* copy indent */
endwhile++;
}
if( endwhile != 0 )
break;
}
/*
* Main reformatting logic
*/
while(( endchar = getword( word )) != EOF ) {
count += length = strlen( word );
if( count > linelength ) { /* split the line here */
count = strlen( line ); /* remove trailing blanks */
while( line[--count] == ' ' )
line[count] = '\0';
printf( "%s\n", line );
count = length + icount; /* begin count for next line */
strcpy( line, istring );
strcat( line, word );
strcat( line, " " );
if( endchar == YES )
strcat( line, " " ); /* end of sentence space */
}
else if( endchar == YES ) {
strcat( line, word ); /* print an extra space */
strcat( line, " " );
count++; /* to account for the extra space */
}
else {
strcat( line, word );
strcat( line, " " );
}
count++; /* for the space separating words */
}
if( strlen( word ) > 0 )
strcat( line, word ); /* print the last word if applicable */
count = strlen( line ); /* remove trailing blanks */
while( line[--count] == ' ' )
line[count] = '\0';
printf( "%s\n", line );
exit( 0 );
}
int getword( word )
char *word; /* storage for word read */
{
int endflag = NO; /* Does this word end a sentence? */
int beginflag = YES; /* Is this the begining of a new word? */
while(( c = getchar( )) != EOF ) {
switch( c ) {
case '.':
case '!': /* end of sentence characters */
case '?':
endflag = YES;
*word++ = c;
break;
case ' ':
case '\t': /* word delimiters - white space */
case '\n':
if( beginflag == YES )
continue; /* skip leading whitespace */
*word = '\0'; /* terminate word */
return( endflag ); /* Non-EOF return */
default: /* just another character */
endflag = NO;
*word++ = c;
}
beginflag = NO; /* no longer at beginning of word */
}
*word = '\0'; /* terminate the last word */
return( EOF );
}
#ifdef bsd
/*
* getopt - get option letter from argv
*/
#include <stdio.h>
char *optarg; /* Global argument pointer. */
int optind = 0; /* Global argv index. */
static char *scan = NULL; /* Private scan pointer. */
extern char *index();
int
getopt(argc, argv, optstring)
int argc;
char *argv[];
char *optstring;
{
register char c;
register char *place;
optarg = NULL;
if (scan == NULL || *scan == '\0') {
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
return(EOF);
if (strcmp(argv[optind], "--")==0) {
optind++;
return(EOF);
}
scan = argv[optind]+1;
optind++;
}
c = *scan++;
place = index(optstring, c);
if (place == NULL || c == ':') {
fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
return('?');
}
place++;
if (*place == ':') {
if (*scan != '\0') {
optarg = scan;
scan = NULL;
} else if (optind < argc) {
optarg = argv[optind];
optind++;
} else {
fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
return('?');
}
}
return(c);
}
#endif
--------------------------------------------------------------------
Ed Reeder
Intel Corp.
Hillsboro, OR
Technical Details
Message-ID:
<222@gandalf.littlei.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!littlei!reederReferences:
<1988Jan19.102343.3255@nonvon.uucp> <316@dsinc.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!littlei!reeder From: reeder@littlei.UUCP (reeder) Newsgroups: comp.editors Subject: Re: Reformatting in vi (format program) Message-ID: <222@gandalf.littlei.UUCP> Date: 29 Jan 88 17:36:20 GMT References: <1988Jan19.102343.3255@nonvon.uucp> <316@dsinc.UUCP> Reply-To: reeder@.UUCP (Ed Reeder) Distribution: na Organization: Intel Corp., ISO Systems Development, Hillsboro, OR Lines: 273