sources-request@munnari.oz (05/27/88)
Submitted by: richb@sunaus.oz (Rich Burridge) Posting-number: Volume 15, Issue 12 Archive-name: mp/Part01 The mp program is used in conjunction with the print option of your mail program. It generates a PostScript output file, which is a pretty printed version of your mail message. It has been tested on a Sun using /usr/ucb/mail and the window- based mailtool program. With little or no modification, it should be possible to make this work with other mailers. See the README file for more details. Rich. ------CUT HERE------CUT HERE------ #! /bin/sh # this is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh to create the files: # README # Makefile # mp.c # mp.pro.ps # mp.1 # This archive created: Wed May 25 12:00:29 EST 1988 # # export PATH; PATH=/bin:$PATH # if [ -f README ] then echo shar: will not over-write existing file README else echo shar: extracting 'README', 1531 characters cat > README <<'Funky_Stuff' mp README v1.4 3/3/87 ------------------------ The mp program is to be used in conjunction with mailtool or mail for producing a pretty print of your mail items. It uses a PostScript prologue file which normally resides in /usr/local, but this can be overwritten by use of the -p option. Do a "make" followed by a "make install" which will compile the mp program and put the files in their default locations. You will probably have to be super-user when you do the "make install" This version of mp, which has been rewritten from the original by Steve Holden (Sun UK) in the ICON language, to C. It is designed to be used in conjunction with the print button in the mailtool program, or the 'pipe' command from withing mail. Add (or alter) the following two lines in your .mailrc file: set printmail='mp | lpr' set cmd="mp | lpr &" Source your .mailrc file again, and you are ready. This has been tested with a LaserWriter with an A4 paper tray, running Transcript v2.0. Please let us know if this requires any modification to run in the US. Any problems, suggestions, bugs or flames to me or Steve please. Rich Burridge Steve Holden Sun Microsystems Sun Microsystems, 49/53 Hotham Parade, Lord Street, Sydney, N.S.W. 2164, Cheshire, SK1 3ND, AUSTRALIA. ENGLAND. sun!sunaus!richb sun!sunuk!nuksun!steve rburridge@Sun.COM sholden@Sun.COM Funky_Stuff len=`wc -c < README` if [ $len != 1531 ] ; then echo error: README was $len bytes long, should have been 1531 fi fi # end of overwriting check if [ -f Makefile ] then echo shar: will not over-write existing file Makefile else echo shar: extracting 'Makefile', 539 characters cat > Makefile <<'Funky_Stuff' # # mp distribtution source makefile steve holden # C version by Rich Burridge. # # @(#)Makefile 1.4 3/3/88. # FILES = README Makefile mp.c mp.pro.ps mp.1 CFLAGS = -g TAPE = /dev/rst0 mp: mp.c cc $(CFLAGS) -o mp mp.c install: install mp /usr/local/bin cp mp.pro.ps /usr/local backup: cp mp.c mp.c~ cp mp.pro.ps mp.pro.ps~ lint: lint mp.c shar: shar.script $(FILES) > archive clean: rm -f mp distribution: -mt -f $(TAPE) rewind tar cvbf 126 $(TAPE) $(FILES) purge: -rm -f *.c *.ps mp.1 testmail Makefile Funky_Stuff len=`wc -c < Makefile` if [ $len != 539 ] ; then echo error: Makefile was $len bytes long, should have been 539 fi fi # end of overwriting check if [ -f mp.c ] then echo shar: will not over-write existing file mp.c else echo shar: extracting 'mp.c', 7190 characters cat > mp.c <<'Funky_Stuff' /* mp.c - take a mail file and format each line for the LaserWriter. * * Original written in the Icon language by Steve Holden - Sun UK. * Converted to C and modified by Rich Burridge - Sun Australia. * * v1.4 3 March 1988. */ #include <stdio.h> #include <sys/types.h> #include <sys/file.h> #include <string.h> #include <time.h> #define PATCHLEVEL 2 #define FPRINTF (void) fprintf /* To make lint happy. */ #define PRINTF (void) printf #define SPRINTF (void) sprintf #define SSCANF (void) sscanf #define STRCPY (void) strcpy #define STRNCPY (void) strncpy /* States for the mail processing automation. */ #define FROMLINE 0 /* Searching for the initial From line. */ #define DOHEADER 1 /* Processing rest of message header. */ #define DOMESSAGE 2 /* Processing text in message body. */ #define EQUAL(val) !strncmp(val,nextline,strlen(val)) #define LINELENGTH 80 /* Number of characters per line. */ #define MAXLINE 256 /* Length of character strings. */ #define PAGELENGTH 60 /* Number of lines per page. */ time_t time() ; struct tm *localtime() ; char *asctime(), *getlogin(), *gets() ; char subject[MAXLINE] ; /* Subject line for this message. */ FILE *fopen(), *pf ; int lindex ; /* Index pointer to nextline. */ int linect = 0 ; /* Line count on current page. */ int maybe_more = 0 ; /* Message header continuation line indicator. */ int non_space ; /* Indicates if nextline has a non-space char. */ int pn = 1 ; /* Page number within message. */ int removednl ; /* Set if a newline was removed from this line. */ /*ARGSUSED*/ main(argc,argv) int argc ; char **argv ; { char **args ; char nextline[MAXLINE] ; /* Next line of the mail message. */ char prologue[MAXLINE] ; /* Name of PostScript prologue file. */ char username[MAXLINE] ; /* The username of the mail file owner. */ int state ; /* State of message processing automation. */ long clock ; /* Used by the localtime function call. */ struct tm *tm ; /* Used by the localtime and asctime calls. */ char *progname = *argv ; /* This programs name. */ STRCPY(prologue, "/usr/local/mp.pro.ps") ; /* Set up default values. */ STRCPY(username, getlogin()) ; if (argv) { for (args = ++argv; *args; args++) if (strcmp(*args, "-p") == 0) { if (*(args+1) == NULL) prologue[0] = '\0' ; else STRCPY(prologue, *(args+1)) ; args++ ; if (!strlen(prologue)) { FPRINTF(stderr,"%s: -p needs prologue name as next argument.\n",progname) ; exit(1) ; } } else { FPRINTF(stderr,"%s: Unknown option %s\n",progname,*args) ; exit(1) ; } } if ((pf = fopen(prologue, "r")) == NULL) { FPRINTF(stderr,"%s: Prologue file not found.\n",progname) ; exit(1) ; } while (fgets(nextline,MAXLINE,pf) != NULL) PRINTF("%s",nextline) ; defwrite("loginname",username) ; clock = time((time_t *) 0) ; tm = localtime(&clock) ; defwrite("timenow",asctime(tm)) ; PRINTF("%%%%EndProlog\n") ; state = FROMLINE ; startpage() ; while (fgets(nextline,LINELENGTH+1,stdin) != NULL) { removednl = 0 ; if (nextline[strlen(nextline)-1] == '\n') { removednl = 1 ; nextline[strlen(nextline)-1] = '\0' ; } non_space = 0 ; for (lindex = 0; lindex < strlen(nextline); lindex++) if (nextline[lindex] != ' ') { non_space = 1 ; break ; } switch (state) { case FROMLINE : if (EQUAL("From")) { boldshow(nextline) ; state = DOHEADER ; } break ; case DOHEADER : if (EQUAL("From") || EQUAL("Date") || EQUAL("Subject")) { mixedshow(nextline) ; maybe_more = 0 ; } else if (EQUAL("To") || EQUAL("Cc")) { mixedshow(nextline) ; maybe_more = 1 ; } else if (EQUAL(" ") && non_space && maybe_more) textshow(nextline) ; else if ((EQUAL(" ") && (!non_space)) || (!strlen(nextline))) { state = DOMESSAGE ; PRINTF("Courier\n") ; PRINTF("() showline\n") ; } else maybe_more = 0 ; break ; case DOMESSAGE : textshow(nextline) ; } } endpage() ; PRINTF("%%%%Trailer\n") ; PRINTF("%%%%Pages: %1d\n",pn) ; } boldshow(s) char *s ; { useline() ; PRINTF("Bold ") ; startline() ; expand(s) ; endline() ; } mixedshow(s) char *s ; { char first[MAXLINE] ; useline() ; SSCANF(s,"%s",first) ; PRINTF("Bold (%s) show Roman (",first) ; expand(&s[strlen(first)]) ; endline() ; if (!strcmp("Subject:",first)) { PRINTF("/subject (") ; expand(&s[strlen(first)]) ; STRCPY(subject,&s[strlen(first)]) ; PRINTF(") def\n") ; } } textshow(s) char *s ; { if (*s == '\014') { if (removednl) /* Is this the bogus formfeed at the end? */ { linect = PAGELENGTH ; useline() ; } return ; } useline() ; startline() ; expand(s) ; endline() ; } expand(s) char *s ; { int i,j,n ; n = 0 ; for (i = 0; i < strlen(s); i++) { switch (s[i]) { case '\\' : PRINTF("\\\\") ; n++ ; break ; case '(' : PRINTF("\\(") ; n++ ; break ; case ')' : PRINTF("\\)") ; n++ ; break ; case '\t' : for (j = 0; j < (8 - (n % 8)); j++) PRINTF(" ") ; n = n + 8 - (n % 8) ; break ; default : PRINTF("%c",s[i]) ; n++ ; } if (!(i % LINELENGTH) && i) { endline() ; startline() ; } } } useline() { if (++linect > PAGELENGTH) { endpage() ; startpage() ; PRINTF("/subject (") ; expand(subject) ; PRINTF(") def\n") ; } } startline() { PRINTF("(") ; } startpage() { PRINTF("%%%%Page: ? %1d\n",pn) ; } endline() { PRINTF(") showline\n") ; } endpage() { linect = 0 ; PRINTF("(%1d) endpage\n",pn++) ; } defwrite(name,def) char *name, *def ; { PRINTF("/%s (%s) def\n",name,def) ; } Funky_Stuff len=`wc -c < mp.c` if [ $len != 7190 ] ; then echo error: mp.c was $len bytes long, should have been 7190 fi fi # end of overwriting check if [ -f mp.pro.ps ] then echo shar: will not over-write existing file mp.pro.ps else echo shar: extracting 'mp.pro.ps', 1754 characters cat > mp.pro.ps <<'Funky_Stuff' %!PS-Adobe-1.0 %%Creator: Steve Holden %%Modifed: Rich Burridge %%Title: @(#)mp.pro.ps 1.4 3/3/88 %%CreationDate: see above %%DocumentFonts: Times-Bold Times-Roman Courier %%Pages: (atend) %%EndComments % /subject () def save /nuksunmailsave exch def /font1d /Times-Bold findfont 10 scalefont def /font2d /Times-Roman findfont 10 scalefont def /font3d /Courier findfont 9 scalefont def /fontHd /Helvetica-BoldOblique findfont 15 scalefont def /fontH2 /Helvetica-BoldOblique findfont 10 scalefont def /fontNd /Times-Bold findfont 12 scalefont def /Bold {font1d setfont} def /Roman {font2d setfont} def /Courier {font3d setfont} def /fontH {fontHd setfont} def /fontD {fontH2 setfont} def /fontN {fontNd setfont} def Courier /endpage { gsave fontH newpath 90 756 moveto 100 736 10 180 270 arc 536 736 10 270 0 arc 536 756 10 0 90 arc 100 756 10 90 180 arc closepath 0.75 setgray fill newpath 318 746 15 0 360 arc gsave 1 setgray fill grestore closepath 0 setgray stroke 100 740 moveto (Mail for ) show loginname (\(null\)) eq {(printing)} {loginname} ifelse show fontD timenow stringwidth pop neg 536 add 740 moveto timenow show fontN dup stringwidth pop 2 div neg 318 add 740 moveto show fontH newpath 90 60 moveto 100 40 10 180 270 arc 536 40 10 270 0 arc 536 60 10 0 90 arc 100 60 10 90 180 arc closepath 0.75 setgray fill 0 setgray 100 44 moveto subject show grestore showpage % display it newpage % reset parameters for next } def /newpage { /lct 0 def /ypos 700 def 100 ypos moveto } def /showline { show /ypos ypos 10 sub def 100 ypos moveto } def newpage % establish first page parameters Funky_Stuff len=`wc -c < mp.pro.ps` if [ $len != 1754 ] ; then echo error: mp.pro.ps was $len bytes long, should have been 1754 fi fi # end of overwriting check if [ -f mp.1 ] then echo shar: will not over-write existing file mp.1 else echo shar: extracting 'mp.1', 1056 characters cat > mp.1 <<'Funky_Stuff' .TH MP 1 "3 March 1988" .\"@(#)mp.1 1.4 3/3/88 .SH NAME mp \- mail printer .SH SYNOPSIS \fBmp\fP [ \fB-p\fP \fIprolog filename\fP ] .SH DESCRIPTION .IX mp "" "\fLmp\fP \(em mail printing program" .IX mail "mp command" "" "\fLmp\fP \(em mail printing" .IX "mail printing" "mp command" "" "\fLmp\fP \(em mail printing" \fIMp\fP produces PostScript output which can be used to print mail on a LaserWriter. The format adopted has shaded stripes containing banner information at the top and bottom of every page. \fIMp\fP reads standard input for the mail file and sends its output to standard output. .SH OPTIONS .TP \fB-p\fP \fIprolog filename\fP The default location for the PostScript prologue file is /usr/local/mp.pro.ps. This options allows a different location to be specified. .SH FILES .TP /usr/local/mp.pro.ps PostScript prologue to define required vocabulary for mail printing. Editing this file will alow you to introduce some stylistic variation in the printing of mail. .TP .SH "SEE ALSO" mail(1) .SH BUGS Does not process more than one file. Funky_Stuff len=`wc -c < mp.1` if [ $len != 1056 ] ; then echo error: mp.1 was $len bytes long, should have been 1056 fi fi # end of overwriting check