Path: 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 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 #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 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