🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.editors
Article #3080

Re: Reformatting in vi (format program)

#3080
From: reeder
Date: Fri, 29 Jan 1988 17:36
273 lines
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!reeder
References: <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