home *** CD-ROM | disk | FTP | other *** search
- From: bgray@marque.mu.edu (Bill Gray)
- Newsgroups: comp.sources.misc
- Subject: v02i102: fmt: a simple text formatter
- Message-ID: <8804201443.AA29460@marque.mu.edu>
- Date: 20 Apr 88 20:43:49 GMT
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 2, Issue 102
- Submitted-By: "Bill Gray" <bgray@marque.mu.edu>
- Archive-Name: usg-fmt
-
- [The Makefile is distinctly System-V-ish. However, I'm somewhat uncertain as
- to whether this came from the BSD "fmt" or not.... ++bsa]
-
- -------------------------------------------------------------
-
- echo x - fmt.1 1>&2
- sed 's/^X//' >fmt.1 <<'----enD-oF-fmt.1----'
- X.TH FMT 1 LOCAL
- X.SH NAME
- Xfmt \- a simple text formatter
- X.SH SYNOPSIS
- X.B fmt
- X[
- X.B \-i
- X] [
- X.B \-j
- X] [
- X.B \-l n
- X] [
- X.B \-p n
- X] [
- X.B \-t n
- X] [ filenames ]
- X.SH DESCRIPTION
- X.I Fmt
- Xis a simple text formatter. With no options present, the default
- Xbehavior of
- X.I fmt
- Xis to copy its input (from specified files or from stdin, if no files
- Xare specified) to its output but with input reformatted into lines no
- Xlonger than 72 characters long. A blank line is taken to indicate the
- Xbeginning of a new paragraph. Lines that begin with a period are
- Xpreserved.
- X.PP
- XThe following options modify this behavior:
- X.TP
- X.B \-i
- XThis option will cause
- X.I fmt
- Xto preserve indentations. Blanks or tabs at the beginning of a line
- Xwill be considered the beginning of a new paragraph.
- X.TP
- X.B \-j
- XJustify output lines. (The default behavior of
- X.I fmt
- Xis to output lines with a ragged right margin).
- X.TP
- X.B \-l n
- XThis option can be used to change the line length from the default of 72
- Xcharacters.
- X.TP
- X.B \-p n
- XChange the page offset. This option will cause the output lines to be
- Xoffset the indicated number of columns from the left.
- X.TP
- X.B \-t n
- XSet tab size. This option is useful only with the
- X.B \-i
- Xoption since tabs are preserved only at the beginning of lines and are
- Xthrown away by default.
- X.SH TIPS
- XIn
- X.IR vi ,
- Xyou can define a macro that will reformat paragraphs by typing
- X.I ":map V {!}fmt^M"
- Xor by putting the line
- X.ti +7n
- X.I "map V {!}fmt^M"
- X.br
- Xin your
- X.I .exrc
- Xfile. After defining this macro, pressing
- X.I V
- Xwill cause the paragraph under the cursor to be reformatted. (Use the
- X.I u
- Xkey to
- X.I undo
- Xif necessary.
- X.SH "SEE ALSO"
- Xnroff(1), vi(1)
- ----enD-oF-fmt.1----
- echo x - fmt.c 1>&2
- sed 's/^X//' >fmt.c <<'----enD-oF-fmt.c----'
- X/*
- Xfile: fmt.c
- X04/88 bgray
- X*/
- X
- X/* a simple text formatter */
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- Xint iflag = FALSE;
- Xint jflag = FALSE;
- Xint maxlen = 72;
- Xint tabsize = 8;
- Xint offset = 0;
- Xint spaces = 0;
- X
- Xchar *progname = NULL;
- Xchar *delimiters = " \t\n\r\f";
- Xchar *usage = "usage: %s [-ij] [-l n] [-p n] [-t n] [file ...]\n";
- X
- Xint dir = FALSE;
- Xint holecnt = 0;
- Xchar *holeptr[256]; /* holeptr[0] is unused */
- X
- Xchar iline[2048] = "\0";
- Xchar *ilp = iline;
- Xchar oline[2048] = "\0";
- Xchar *olp = oline;
- X
- Xextern char *optarg;
- Xextern int optind;
- X
- Xint max();
- Xvoid exit();
- Xchar *basename(), *strtok();
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int c;
- X
- X progname = basename(argv[0]);
- X while ((c = getopt(argc, argv, "ijl:p:t:")) != EOF)
- X switch(c) {
- X case 'i' : iflag = TRUE; break;
- X case 'j' : jflag = TRUE; break;
- X case 'l' : maxlen = max(0, atoi(optarg)); break;
- X case 'p' : offset = max(0, atoi(optarg)); break;
- X case 't' : tabsize = max(1, atoi(optarg)); break;
- X default : fprintf(stderr, usage, progname); exit(1); break;
- X }
- X
- X if (optind >= argc)
- X format();
- X else for ( ; (optind < argc); optind++) {
- X if (freopen(argv[optind], "r", stdin) != NULL)
- X format();
- X else {
- X fprintf(stderr, "Couldn't open file: %s", argv[optind]);
- X exit(1);
- X }
- X }
- X return(0);
- X} /* main */
- X
- X
- X
- Xformat()
- X{
- X char *p;
- X
- X while (ilp = gets(iline))
- X if (*ilp == '\0')
- X skipline(1);
- X else if (*ilp == '.') {
- X putline();
- X while (*olp++ = *ilp++);
- X putline();
- X }
- X else {
- X if ((iflag) && (isspace(*ilp))) {
- X putline();
- X copyindent();
- X }
- X p = strtok(ilp, delimiters);
- X while (*p) {
- X putword(p);
- X p = strtok(NULL, delimiters);
- X }
- X }
- X putline();
- X} /* format */
- X
- X
- X
- Xcopyindent()
- X{
- X int col = 1;
- X
- X for ( ; (isspace(*ilp)); col++) {
- X if (*ilp++ == '\t')
- X for ( ; (col % tabsize); col++)
- X *olp++ = ' ';
- X *olp++ = ' ';
- X }
- X} /* copyindent */
- X
- X
- X
- Xputword(p)
- Xchar *p;
- X{
- X int plen;
- X
- X plen = strlen(p);
- X if ((olp - oline) + spaces + plen > maxlen) {
- X if ((jflag) && (holecnt))
- X justifyline();
- X putline();
- X }
- X if (spaces) {
- X holeptr[++holecnt] = olp;
- X for ( ; (spaces > 0); spaces--)
- X *olp++ = ' ';
- X }
- X spaces = 1 + endofsentence(p, plen);
- X while (*p)
- X *olp++ = *p++;
- X} /* putword */
- X
- X
- X
- Xjustifyline()
- X{
- X int n;
- X char *fp;
- X char *tp;
- X
- X dir = (! (dir));
- X fp = olp - 1;
- X olp = &oline[maxlen];
- X tp = olp - 1;
- X while (tp > fp) {
- X while (fp >= holeptr[holecnt])
- X *tp-- = *fp--;
- X if (dir)
- X n = ((tp - fp) - 1) / holecnt + 1;
- X else
- X n = (tp - fp) / holecnt;
- X while (n--)
- X *tp-- = ' ';
- X holecnt--;
- X }
- X} /* justifyline */
- X
- X
- X
- Xputline()
- X{
- X *olp = '\0';
- X if (*oline)
- X printf("%*s\n", offset + strlen(oline), oline);
- X *oline = '\0';
- X olp = oline;
- X spaces = 0;
- X holecnt = 0;
- X} /* putline */
- X
- X
- X
- Xskipline(n)
- Xint n;
- X{
- X putline();
- X for ( ; (n > 0); n--)
- X printf("\n");
- X} /* skipline */
- X
- X
- X
- Xint endofsentence(p, plen)
- Xchar *p;
- Xint plen;
- X{
- X if (plen < 3)
- X return(FALSE);
- X if (!strchr(".:?!", *(p + plen - 1)))
- X return(FALSE);
- X if (abbr(p))
- X return(FALSE);
- X return(TRUE);
- X} /* endofsentence */
- X
- X
- X
- Xint abbr(s)
- Xchar *s;
- X{
- X char *p, *q, *r;
- X
- X while (*s == '(') s++;
- X q = ".i.e.g.dr.mr.mrs.st.";
- X for ( ; (*q); q++) {
- X p = q;
- X r = s;
- X while ((*r) && (*p++ == (*r++ | 0x20))) ;
- X if (!*r)
- X return(TRUE);
- X }
- X return(FALSE);
- X} /* abbr */
- X
- X
- X
- Xchar *basename(s)
- Xchar *s;
- X{
- X char *p;
- X
- X if (p = strrchr(s, '/'))
- X return(++p);
- X else
- X return(s);
- X} /* basename */
- X
- X
- X
- Xint max(a, b)
- Xint a, b;
- X{
- X return((a > b) ? a : b);
- X} /* max */
- X
- ----enD-oF-fmt.c----
- echo x - Makefile 1>&2
- sed 's/^X//' >Makefile <<'----enD-oF-Makefile----'
- X# file: fmt/Makefile
- X# 04/88 bgray
- X
- X
- XBINDIR = /usr/lbin
- XMANDIR = /usr/man/u_man/man1
- XCATMAN = /usr/catman/u_man/man1
- X
- XLIBS =
- XCFLAGS = -O
- XLDFLAGS = -s
- XCC = /bin/cc
- XRM = /bin/rm -f
- XMV = /bin/mv -f
- XCP = /bin/cp
- X
- XFORMATTER = nroff
- X
- XOBJS =
- X
- X
- Xall: fmt fmt.doc
- X
- Xfmt: fmt.c
- X $(CC) $(LDFLAGS) -o fmt fmt.c
- X
- Xfmt.doc: fmt.1
- X ${FORMATTER} -man fmt.1 > fmt.doc
- X
- Xinstall: all
- X $(CP) fmt $(BINDIR)
- X chown bin $(BINDIR)/fmt
- X chgrp bin $(BINDIR)/fmt
- X chmod 755 $(BINDIR)/fmt
- X $(CP) fmt.doc $(CATMAN)/fmt.1
- X chown bin $(CATMAN)/fmt.1
- X chgrp bin $(CATMAN)/fmt.1
- X chmod 644 $(CATMAN)/fmt.1
- X
- ----enD-oF-Makefile----
- exit
-
- Bill Gray
- --
- bgray@marque.mu.edu { uunet | uwvax }!marque.mu.edu!bgray
-