home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.questions:14859 comp.sources.wanted:5455 comp.editors:3089
- Newsgroups: comp.unix.questions,comp.sources.wanted,comp.editors
- Path: sparky!uunet!nwnexus!osiris
- From: David Ruggiero <osiris@halcyon.com>
- Subject: SUMMARY: What do *you* use to format mail text?
- Message-ID: <1992Dec21.170313.14176@nwnexus.WA.COM>
- Followup-To: comp.unix.questions
- Originator: osiris@halcyon.com
- Keywords: mail format script
- Sender: sso@nwnexus.WA.COM (System Security Officer)
- Reply-To: osiris@halcyon.halcyon.com (David Ruggiero)
- Organization: [none - why fight entropy?]
- Date: Mon, 21 Dec 1992 17:03:13 GMT
- Lines: 505
-
-
- I had asked the question (in several newsgroups) about scripts people
- use to format their incoming/outgoing mail text, including evening out
- line lengths and adding indent characters. Several people responded: a
- few were quite unhelpful, suggesting I use emacs (sorry), long series
- of arcane vi commands (that's what I'm trying to get away from!), or
- fmt(1) (despite the clear statement in my post that fmt couldn't do
- what I needed).
-
- Many, however, were very knowledgable and provided scripts of various
- degrees of capability and complexity to get the job done. Thanks to
- all five of you recognized below...using these routines, I find I
- can now waste my time on the net much more efficiently. :)
-
- David Ruggiero (osiris@halcyon.com)
-
- ------insert_#1-----------------------------------------------------------
- {I'll actually start by completely countering what I said above and give
- this nifty vi command string to format one line at a time. Simple and
- effective and fast. - jdr}
-
-
- From: galway@chtm.eece.unm.edu (Denis McKeon)
- Newsgroups: comp.unix.questions
-
- While '!fmt' does a nice job for large blocks, I find I prefer to work
- a line at a time (possibly repeated for paragraphs):
-
- map + J074lBhr
-
- This joins lines and then splits them between words left of column 74.
- Inter-sentence spacing is unaffected. The solution doesn't depend on
- anything external to 'vi' - you could use it within a 'vi' clone under
- DOS, for instance. There is no fork overhead (which was a bigger
- problem when I was running Unix on an 8088 in a DEC Rainbow). Since
- David said he was using vi, he could add this to his .exrc file or
- EXINIT environment variable. Your mileage may vary.
-
- ------insert_#2----------------------------------------------------------
- {Now a short but effective script that uses nroff to do the dirty work.
- This is slower, but it works and can be customized to your particular
- needs. This is a great lesson in using existing tools rather that writing
- your own! - jdr}
-
-
- From: Ray A. Jones <ray@camco1.celestial.com>
-
- Among other "map" items in my .exrc file, I have
-
- map OS mz}bmx:'z,'x!xfmt
- ^^^
- | Function key F4
- When I want to reformat a paragraph, I put the cursor on the first character
- of the paragraph and press F4. If you want to use it that way, replace OS
- with whatever key or function key you want.
-
- {This is the "xfmt" script, referenced above:}
-
- echo "" >/tmp/.xy
- echo ".na
- .nh
- .ll 6.5i" >/tmp/xx
- cat - >>/tmp/xx
- nroff /tmp/xx|sed -e "/^$/d" |cat - /tmp/.xy
- rm /tmp/xx /tmp/.xy
-
- ------insert_#3-----------------------------------------------------------
- {A good suggestion for a good reference. - jdr}
-
- From: kkress@phent.UUCP (Kenneth R. Kress)
- Subject: Mail formatting scripts
-
- In "Sed & Awk" by Dale Dougherty (O'Reilly & Associates, Inc.)
- such a script is described. It uses nawk (which I don't have) and is
- too long for me to want to type in. If you can get your hands on the
- book, look at "adj" in the Miscellany of Scripts chapter (in my edition,
- p. 329-336).
-
- -----insert_#4------------------------------------------------------------
- {A highly customizable perl script ('reform') that works well. - jdr}
-
- From: lwall@netlabs.com <Larry Wall>
-
- #!/usr/bin/perl
- # Usage: reform [-lNUM] [-rNUM] [-iNUM] [-sNUM] [files]
-
- # Set default values for left margin, right margin, indent
- # and paragraph spacing.
- $l = 0;
- $r = 0;
- $i = 0;
- $s = 1;
-
- # Process any switches.
- while ($ARGV[0] =~ /^-/) {
- $_ = shift;
- /^-(l|r|i|s)(\d+)/ && (eval "\$$1 = \$2", next);
- die "Unrecognized switch: $_\n";
- }
-
- # Calculate format strings.
- $r = $l + 65 unless $r;
- $r -= $l; # make $r relative to $l
- die "Margins too close\n" if $l + $i >= $r;
-
- $LEFT = ' ' x $l;
- $INDENT = ' ' x $i;
- $RIGHT1 = '^' . '<' x ($r - 1 - $i);
- $RIGHT2 = '^' . '<' x ($r - 1);
- $SPACING = "\n" x $s;
-
- # Define a format at run time.
- $form = <<"End of Format Definition";
- format STDOUT =
- $LEFT$INDENT$RIGHT1
- \$_
- $LEFT$RIGHT2~~
- \$_
- $SPACING.
- End of Format Definition
-
- print $form if $debugging;
- eval $form;
-
- # Set paragraph mode on input.
- $/ = '';
-
- # For each paragraph...
- while (<>) {
- s/\s+/ /g; # Canonicalize white space.
- s/ $//; # Trim final space.
- s/([Ia-z0-9][)'"]*[.!?][)'"]*) /$1 /g; # Fix sentence ends.
- write; # Spit out new paragraph.
- }
- -----insert_#5 (long)--------------------------------------------------------
- {Finally, a full-blown C program. Enjoy! - jdr}
-
- From: amos shapir <amos@CS.HUJI.AC.IL>
- Here is the whole package, man pages included:
-
- --Cut-here-------X---------------X---------------X---------------X----
- #!/bin/sh
- # This is a shell archive (shar 3.32)
- # made 12/20/1992 06:54 UTC by amos@hal
- # Source directory /a/falafel/home/phd/amos/misc/adj
- #
- # existing files WILL be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 685 -rw-r--r-- adj.txt
- # 1164 -rw-r--r-- adj.6
- # 3395 -rw-r--r-- adj.c
- # 316 -rw-r--r-- ctr.6
- # 271 -rw-r--r-- ctr.c
- #
- if touch 2>&1 | fgrep 'amc' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= adj.txt ==============
- echo "x - extracting adj.txt (Text)"
- sed 's/^X//' << 'SHAR_EOF' > adj.txt &&
- X Have you ever
- X wished you had something
- X to replace nroff? Something
- X small, fast and versatile, yet at
- X the same time flexible and powerful?
- X Well, your troubles are over. 'Adj' is
- X not as powerful as nroff or TeX, but
- X it's ok for small portions of text, (and
- X much more useful than 4BSD's 'fmt').
- X Combined with the trivial centering
- X filter 'ctr', it can do fancy stuff
- X like this text. This text was
- X produced by the command:
- X
- Xadj -w 19,26,31,35,37,39,40,40,40,39,37,35,31,26,19 | ctr -w 60
- SHAR_EOF
- $TOUCH -am 1025141788 adj.txt &&
- chmod 0644 adj.txt ||
- echo "restore of adj.txt failed"
- set `wc -c adj.txt`;Wc_c=$1
- if test "$Wc_c" != "685"; then
- echo original size 685, current size $Wc_c
- fi
- # ============= adj.6 ==============
- echo "x - extracting adj.6 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > adj.6 &&
- X.TH ADJ 6 Local
- X.UC 4
- X.SH NAME
- Xadj \- fill and adjust text lines
- X.SH SYNOPSIS
- X.B adj
- X[
- X.B \-h
- X] [
- X.B \-n
- X] [
- X.B \-p
- X] [
- X.B \-w
- X.I n1,...
- X] [ file ]
- X.SH DESCRIPTION
- X.I Adj
- Xcopies the given file (standard input if none is given) to the standard output,
- Xfilling lines and adjusting the right margin. Indentation and empty lines
- Xare preserved.
- X.PP
- XNormally, words (uninterrupted sequences of non-blank characters) are not
- Xbroken, unless the
- X.B \-h
- X(hyphen) flag is given.
- X.PP
- XThe
- X.B \-n
- X(no adjust) prevents
- X.I adj
- Xfrom adjusting the right margin.
- X.PP
- XIf the
- X.B \-p
- X(paragraph) option is specified, indentation is preserved only on
- Xthe first line of a paragraph, assuming paragraphs are separated by empty lines.
- X.PP
- XThe
- X.B \-w
- X.I n
- X(width) option sets the line width to
- X.I n
- X(default 65).
- XWhen given as
- X.B \-w
- X.I n1,n2,...
- X(a comma-separated sequence of numbers) the output lines will be
- X.I "n1, n2"
- Xetc. characters long, respectively.
- XWhen the sequence is exhausted, it is restarted.
- X.SH "SEE ALSO"
- Xctr(6)
- X.SH BUGS
- X.B \-n
- Xdoes not break words intelligently.
- X.PP
- XChange of indentation is done ungracefully.
- X.PP
- XThere's probably a better way tp specify line lengths.
- SHAR_EOF
- $TOUCH -am 0319114087 adj.6 &&
- chmod 0644 adj.6 ||
- echo "restore of adj.6 failed"
- set `wc -c adj.6`;Wc_c=$1
- if test "$Wc_c" != "1164"; then
- echo original size 1164, current size $Wc_c
- fi
- # ============= adj.c ==============
- echo "x - extracting adj.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > adj.c &&
- X/*
- X * Trivial line-fill filter
- X * white space at col 1 and empty lines
- X * are preserved.
- X * flags: -n - dont adjust right margin
- X * -w {n} line is {n} chars wide
- X * -w {n1,n2,...} line is cyclically n1, n2... chars wide
- X * -h - break words with a hyphen
- X * -p - indent only 1st line of a paragraph
- X */
- X#define MAXB 1024
- X#define MAXW 100 /* words in a line */
- X#define NLL 50 /* line lengths vector size */
- X#define EOF (-1)
- X/* flags */
- X#define NOADJ 01 /* no adjust */
- X#define HYPHN 02 /* hyphenate */
- X#define PARAG 04 /* indent 1 line */
- X#define UNBUF 010 /* unbuffered */
- Xint ll[NLL] = { 65 }; /* line lengths */
- Xint nll; /* current line length index */
- Xint nw; /* current no. of words */
- Xint ind; /* current indentation */
- Xstatic char buf[MAXB];
- Xmain(argc, argv)
- X char **argv;
- X{
- X register char *pb, *pw, *pe;
- X register c, flags, nl;
- X
- X flags = 0;
- X while(--argc > 0)
- X if(**++argv == '-')
- X switch(argv[0][1]) {
- X case 'n':
- X flags = NOADJ;
- X break;
- X case 'h':
- X flags = HYPHN;
- X break;
- X case 'p':
- X flags |= PARAG;
- X break;
- X case 'w':
- X --argc;
- X pb = *++argv;
- X nl=0;
- X do {
- X for(ll[nl]=0; *pb>='0' && *pb<='9'; pb++)
- X ll[nl] = ll[nl]*10+*pb-'0';
- X nl++;
- X }while(*pb++);
- X break;
- X }
- X else {
- X close(0);
- X open(*argv, 0, 0);
- X }
- X/*
- X * When processing, buf looks like this:
- X * buf pw pb pe
- X * v----+-+----+-+----+v+-v-------v+
- X * |word| |word| |word| |wo |
- X * +----+-+----+-+----+-+----------+
- X * nw counts full words, nl empty lines.
- X */
- X nl = 2;
- X pb = pw = buf-1;
- X while((c = getchar()) != EOF) {
- X if(c==' ' || c=='\t' || c=='\n') {
- X if(pb>=buf && *pb!=' ') {
- X /* end of a sentence */
- X if(!(flags&HYPHN) &&
- X (*pb=='.' || *pb=='!' || *pb=='?'))
- X *++pb = '\037';
- X *++pb = ' ';
- X nw++;
- X pw = pb; /* word marker in buf */
- X }
- X if(c == '\n') {
- X if(++nl > 1) { /* end of paragraph */
- X if(nw > 0) {
- X putline(pb, NOADJ);
- X pb = pw = buf-1;
- X nw = 0;
- X }
- X putchar('\n');
- X ind = 0;
- X }
- X } else if(nl > 1) {
- X if(c == '\t')
- X ind = (ind/8+1)*8;
- X else
- X ind++;
- X }
- X } else if(c>' ' && c<0177) {
- X *++pb = c;
- X if(nl) {
- X nl = 0;
- X pe = &buf[ll[nll]-ind];
- X }
- X }
- X if(pb >= pe) { /* line overflow */
- X if(*pe == '\037') { /* that's the only case pb>pe */
- X *pe = *pb--;
- X pw = pe;
- X }
- X if((flags&HYPHN) && pb-pw>2) { /* insert hyphen */
- X *++pb = pe[-1];
- X pe[-1] = '-';
- X *++pb = c;
- X pw = pe;
- X nw++;
- X } else if(nw == 0) { /* insert blank */
- X *++pb = c;
- X pw = pe;
- X nw++;
- X }
- X putline(pw, flags);
- X for(pe=buf, ++pw; pw<=pb; )
- X *pe++ = *pw++;
- X pb = pe-1;
- X pw = buf-1;
- X pe = &buf[ll[nll]-ind];
- X nw = 0;
- X }
- X }
- X if(nw > 0)
- X putline(pb, NOADJ);
- X return(0);
- X}
- X
- X/*
- X * adjust & print line
- X */
- Xputline(pw, flags)
- X register char *pw;
- X{
- X register char *pb;
- X register i, n, b, m;
- X
- X for(i=ind; i>=8; i-=8)
- X putchar('\t');
- X for(; i>0; i--)
- X putchar(' ');
- X n = nw-1;
- X if(pw[-1] == '\037') /* end of sentence at end of line */
- X --pw;
- X b = buf+ll[nll]-ind-pw; /* no. of blanks to distribute */
- X m = n/2;
- X for(pb=buf; pb<pw; pb++) {
- X putchar(*pb == '\037' ? ' ' : *pb);
- X if(!(flags&NOADJ) && *pb==' ') {
- X m += b;
- X for(i=m/n; i>0; i--)
- X putchar(' ');
- X m %= n;
- X }
- X }
- X putchar('\n');
- X /* cyclic increment line lengths vector */
- X if(ll[++nll] == 0)
- X nll = 0;
- X if(flags&PARAG)
- X ind = 0;
- X}
- SHAR_EOF
- $TOUCH -am 0527174191 adj.c &&
- chmod 0644 adj.c ||
- echo "restore of adj.c failed"
- set `wc -c adj.c`;Wc_c=$1
- if test "$Wc_c" != "3395"; then
- echo original size 3395, current size $Wc_c
- fi
- # ============= ctr.6 ==============
- echo "x - extracting ctr.6 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > ctr.6 &&
- X.TH CTR 6 Local
- X.UC 4
- X.SH NAME
- Xctr \- center text lines
- X.SH SYNOPSIS
- X.B ctr
- X[
- X.B \-w
- X.I n
- X]
- X.SH DESCRIPTION
- X.I Ctr
- Xcopies its standard input to its standard output,
- Xcentering text in the output lines.
- X.PP
- XThe
- X.B \-w
- X.I n
- X(width) option sets the output line width to
- X.I n
- X(default 65).
- X.SH "SEE ALSO"
- Xadj(6)
- X.SH BUGS
- SHAR_EOF
- $TOUCH -am 0318144287 ctr.6 &&
- chmod 0644 ctr.6 ||
- echo "restore of ctr.6 failed"
- set `wc -c ctr.6`;Wc_c=$1
- if test "$Wc_c" != "316"; then
- echo original size 316, current size $Wc_c
- fi
- # ============= ctr.c ==============
- echo "x - extracting ctr.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > ctr.c &&
- X#define NULL ((char *)0)
- Xmain(argc, argv)
- X char **argv;
- X{
- X static int ll = 65; /* line length */
- X static buf[100];
- X
- X if(argc > 1 && **++argv == '-' && argv[0][1] == 'w')
- X ll = atoi(*++argv);
- X while(gets(buf) != NULL)
- X printf("%*s%s\n", (ll-strlen(buf))/2, "", buf);
- X}
- SHAR_EOF
- $TOUCH -am 0318150987 ctr.c &&
- chmod 0644 ctr.c ||
- echo "restore of ctr.c failed"
- set `wc -c ctr.c`;Wc_c=$1
- if test "$Wc_c" != "271"; then
- echo original size 271, current size $Wc_c
- fi
- exit 0
-
- --Cut-here-------X---------------X---------------X---------------X----
-
- -----end of all inserts----
-
- Hope these help others...again, thanks to those who took the time and trouble
- to respond.
-
-
- --
- David Ruggiero (jdavid@halcyon.com) Seattle, WA: Home of the Moss People
-