[unix-pc.sources] NroffGraphics Part 1 of 2

wnp@killer.Dallas.TX.US (Wolf Paul) (03/27/89)

Per several requests, here is NroffGraphics, a package providing a
post-processor scheme for nroff and various dot matrix printers.

Enjoy!

Wolf Paul
wnp@killer.dallas.tx.us
------------
Newsgroups: comp.sources.unix
Subject: v15i046:  Tools for nroff graphics on dot-matrix printers, Part01/02
Message-ID: <911@fig.bbn.com>
Date: 7 Jun 88 18:29:51 GMT
Lines: 1923
Approved: rsalz@uunet.UU.NET

Submitted-by: snark!eric (Eric Raymond)
Posting-number: Volume 15, Issue 46
Archive-name: nroffgraphics/part01

[  I haven't tried this.  --r$ ]

This package of nroff extension utilities enables you to do three things:

1) Convert from old-style nroff driver tables to new-style ditroff all-ASCII
   tables, and vice versa (see convtab.1)

2) Design your own extension character sets for use with nroff on any printer
   supporting an Epson MX80-compatible graphics mode, or something not too
   unlike it (the beginnings of a terminfo-like specification language for
   composing graphics strings from rasters are provided).

3) Get full use of special printer highlighting and alternate fonts from nroff.

A set of 'standard' graphics for old-style nroff is provided.

he convtab(1) utility is based in part on the table/elbat toolset floated
to comp.sources some time back by Matt Crawford, Ian Darwin, and Bruce
Townsend. The existence of ditroff format makes their design obsolete, but
important parts of their implementation live on in otread.c and otwrite.c
respectively.

Their documentation warns that the format for Berkeley tab files is different
and thus "this package will not work on Berkely (sic) systems without
substantial hacking". The same probably applies to convtab.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  MANIFEST Makefile READ.ME convtab.1 convtab.c ditread.c
#   ditwrite.c dotmatrix.1 escapes.c otread.c otwrite.c post.proto
#   term.5 termtab.c termtab.h
# Wrapped by rsalz@fig.bbn.com on Tue Jun  7 14:26:48 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(623 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	
X Makefile                   1	
X READ.ME                    1	
X convtab.1                  1	
X convtab.c                  1	
X ditread.c                  1	
X ditwrite.c                 1	
X dotmatrix.1                1	
X dotmatrix.c                2	
X escapes.c                  1	
X mx80.pix                   2	
X otread.c                   1	
X otwrite.c                  1	
X post.proto                 1	
X term.5                     1	
X termtab.c                  1	
X termtab.h                  1	
END_OF_FILE
if test 623 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1390 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Makefile for the nroff driver-customization tools
X#
XLP = mx80
X
XDESTDIR = /usr/lib/nterm	# ditroff systems
XTABFILE = tab.$(LP)
X
X#DESTDIR = /usr/lib/term	# pre-ditroff systems
X#TABFILE = tab$(LP)
X
XDEFS =
XCFLAGS = $(DEFS) -O	# -DKANJI if your nroff is the international version
XLDFLAGS = -s
XLFLAGS = $(DEFS)
X
XDERIVED = $(TABFILE) $(LP).c $(LP).test
X
X.SUFFIXES: .1 .5 .lp
X.1.lp:
X	nroff -man -T$(LP) $< | $(LP) >$*.lp
X.5.lp:
X	nroff -man -T$(LP) $< | $(LP) >$*.lp
X
Xall:	convtab dotmatrix
X
Xinstall: $(LP) $(TABFILE)
X	mv $(TABFILE) $(DESTDIR)
X
XCONVOBJS = termtab.o ditread.o otread.o otwrite.o ditwrite.o
Xconvtab: convtab.o escapes.o $(CONVOBJS)
X	$(CC) $(LFLAGS) convtab.o escapes.o $(CONVOBJS) -o convtab
Xdotmatrix: dotmatrix.o escapes.o
X	$(CC) $(CFLAGS) dotmatrix.o escapes.o -o dotmatrix
X
Xconvtab.o: convtab.c termtab.h
Xtermtab.o: termtab.c termtab.h
Xditread.o: ditread.c termtab.h
Xotwrite.o: otwrite.c termtab.h
Xditwrite.o: ditwrite.c termtab.h
Xotread.o: otread.c termtab.h
Xescapes.o: escapes.c
Xdotmatrix.o: dotmatrix.c
X
X$(DERIVED): dotmatrix $(LP).pix
X	dotmatrix <$(LP).pix
X
Xlint:	
X	lint $(LFLAGS) convtab.c escapes.c $(CONVOBJS:.o=.c)
X	lint $(LFLAGS) dotmatrix.c escapes.c
X
Xclean:
X	rm -f a.out *.o $(DERIVED) $(LP).raw $(LP).lp
X
Xtest: $(DERIVED)
X	nroff -T$(LP) $(LP).test | tee $(LP).raw | $(LP) | tee $(LP).lp | lp
X
Xshar:
X	shar READ.ME Makefile *.[ch15] *.pix post.proto >dotmatrix.shar
END_OF_FILE
if test 1390 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'READ.ME' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'READ.ME'\"
else
echo shar: Extracting \"'READ.ME'\" \(1573 characters\)
sed "s/^X//" >'READ.ME' <<'END_OF_FILE'
XThis package of nroff extension utilities enables you to do three things:
X
X1) Convert from old-style nroff driver tables to new-style ditroff all-ASCII
X   tables, and vice versa (see convtab.1)
X
X2) Design your own extension character sets for use with nroff on any printer
X   supporting an Epson MX80-compatible graphics mode, or something not too
X   unlike it (the beginnings of a terminfo-like specification language for
X   composing graphics strings from rasters are provided).
X
X3) Get full use of special printer highlighting and alternate fonts from nroff.
X
XA set of 'standard' graphics for old-style nroff is provided.
X
XThe convtab(1) utility is based in part on the table/elbat toolset floated
Xto comp.sources some time back by Matt Crawford, Ian Darwin, and Bruce
XTownsend. The existence of ditroff format makes their design obsolete, but
Ximportant parts of their implementation live on in otread.c and otwrite.c
Xrespectively.
X
XTheir documentation warns that the format for Berkeley tab files is different
Xand thus "this package will not work on Berkely (sic) systems without
Xsubstantial hacking". The same probably applies to convtab. Interested parties
Xare urged to send me a copy of their mods for the master version.
X
XThe code lints clean and has been written with (hardware) portability in mind.
XIt uses a few USG-isms such as getopt(3) for which PD equivalents are
Xavailable.
X
X      Eric S. Raymond
X      UUCP:  {{seismo,ihnp4,rutgers}!cbmvax,sdcrdcf!burdvax,vu-vlsi}!snark!eric
X      Post:  22 South Warren Avenue, Malvern, PA 19355    Phone: (215)-296-5718
END_OF_FILE
if test 1573 -ne `wc -c <'READ.ME'`; then
    echo shar: \"'READ.ME'\" unpacked with wrong size!
fi
# end of 'READ.ME'
fi
if test -f 'convtab.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'convtab.1'\"
else
echo shar: Extracting \"'convtab.1'\" \(3120 characters\)
sed "s/^X//" >'convtab.1' <<'END_OF_FILE'
X.TH CONVTAB 1 "Feb 23, 1988"
X.SH NAME
Xconvtab \- convert nroff driver tables to ditroff form and vice-versa
X.SH SYNOPSIS
X.BR convtab " [ [" -vxd "] "
X.IR files... "] ..."
X.PP
X.SH DESCRIPTION
XThis tool may be used to convert nroff driver files between the all-ASCII form
Xused by \fIditroff\fR(1) and the undocumented format used by old nroff. If
Xcalled with no file arguments, it filters a ditroff file to old nroff form.
X.PP
XIf called with file arguments, it looks for a ``tab.'' prefix (denoting a
Xditroff-format file) or (failing that) a ``tab'' prefix (denoting an
Xnroff-format file). Each file mentioned on the command line is then
Xconverted to a correspondingly-named file of the other form.
X.PP
XThe -v flag causes convtab to get chatty about what it's doing and what
Xfiles it's converting. The -d flag forces -v and suppresses the actual
Xfile conversions, so you can use it to verify what convtab would do with
Xa given command line. Flags and filenames may be freely intermixed and
Xare interpreted left to right on the command line.
X.SH INCOMPATIBILITIES
XNote that conversion from ditroff to nroff form may lose information, as
Xnroff only allows redefinition of its ``wired-in'' escapes. Normally, if
Xconvtab encounters an escape in a ditroff-format file than nroff doesn't
Xhandle, it will emit a diagnostic and exit (but the -x flag allows it to
Xcontinue in this case).
X.PP
XConversion from old nroff to ditroff files may also lose information, about
Xwhat characters are allowed to be underlined for the .I highlight. Old-form
Xdriver tables encoded this information in the high bit of each character's
Xleading length byte. There is no documented way to include such information
Xin the new format.
X.PP
XAlso, be aware that new nroff no longer assumes (as did older versions)
Xthat the \fBtwnl\fR string turns off boldfacing. When converting old files
Xto the new form, you may want to edit out any highlight-clearing string
Xoccurring after \en in the \fBtwnl\fR entry.
X.SH WARNING
XBe aware that the new format's character-escape conventions are
Xnot documented. It certainly accepts C-style three-digit-octal escapes and
Xthe \eb, \en and \er escapes for backspace and newline (this much can be gleaned
Xfrom looking at the driver files supplied with the system). The \et escape
Xis therefore probably also good.
X.PP
XBut, for convenience in generating old-form driver tables from scratch,
X.IR convtab (1)
Xalso accepts two-digit hex escapes of the form \ex\fIdd\fR, and the special
Xescape \ee for the ASCII ESC character (hex 0x1B).
X.PP
XWhen converting new-format files to old form, it might therefore be wise to
Xcheck that these interpretations don't munch text that new nroff wants to see
Xliterally. A quick way to verify this is to convert a copy of the old form to
Xnew format again and diff the two new-format versions. If they differ, it's
Xeither the result of a spurious escape or a bug (and if the latter, please
Xreport it to the author!).
X.SH AUTHOR
XEric S. Raymond (...!rutgers!vu-vlsi!snark!eric) Feb 1988
X.br
XParts of this code are based on Bruce Townsend's table/elbat tools.
X.SH SEE ALSO
Xdotmatrix(1), term(5)
END_OF_FILE
if test 3120 -ne `wc -c <'convtab.1'`; then
    echo shar: \"'convtab.1'\" unpacked with wrong size!
fi
# end of 'convtab.1'
fi
if test -f 'convtab.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'convtab.c'\"
else
echo shar: Extracting \"'convtab.c'\" \(3575 characters\)
sed "s/^X//" >'convtab.c' <<'END_OF_FILE'
X/*
X * convtab.c -- convert old nroff driver tables to new form and vice-versa
X *
X * This main calls four functions dit{read,write} and ot{read,write} which seal
X * away the operations of reading and writing new (dit*) and old (ot*) style
X * nroff driver tables. All set up or read from the common nrtab_t structure.
X *
X * Common accesses to the structure are implemented in termtab.c, which
X * contains code for a flavor of string storage pool that both use. The
X * escapes.c module provides common character-escape and escape-expansion
X * handling.
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include "termtab.h"
X
Xextern char *mktemp(), *strcpy();
Xextern void perror();
X
Xextern int ignorebad;	/* ditread.o supplies this */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X    int verbose = 0, debug = 0, filecount = 0;
X    FILE *ifp, *ofp;
X    nrtab_t *ttab;
X    extern errno;
X
X    for (++argv, --argc; argc; argv++, argc--)
X    {
X	char sw = argv[0][0];
X	char opt = argv[0][1];
X
X	if (sw == '-' || sw == '+')	/* a switch argument */
X	{
X	    switch(opt)
X	    {
X	    case 'x':
X		ignorebad = (sw == '-');
X		if (verbose)
X		    (void) printf("convtab: ignorebad %s\n",
X				  ignorebad ? "set" : "cleared");
X		break;
X
X	    case 'v':
X		verbose = (sw == '-');
X		if (verbose)
X		    (void) printf("convtab: verbose %s\n",
X				  verbose ? "set" : "cleared");
X		break;
X
X	    case 'd':
X		if (debug = (sw == '-'))
X		    verbose = 1;
X		if (verbose)
X		    (void) printf("convtab: debug %s\n",
X				  debug ? "set" : "cleared");
X		break;
X	    }
X	}
X	else				/* a filename argument */
X	{
X	    char target[BUFSIZ];
X	    char tempf[20];
X
X	    filecount++;
X
X	    (void) strcpy(tempf, "/tmp/convtabXXXXX");
X	    (void) mktemp(tempf);
X
X	    if (strncmp(argv[0], "tab.", 4) == 0)
X	    {
X		(void) sprintf(target, "tab%s", argv[0] + 4);
X		if (verbose)
X		    (void) fprintf(stderr,
X			"convtab: %s (ditroff format) to %s (old format)\n",
X			argv[0], target);
X		if (!debug)
X		{
X		    ifp = fopen(argv[0], "r");
X		    ofp = fopen(tempf, "w");
X
X		    ttab = ditread(ifp);
X		    otwrite(ttab, ofp);
X
X		    if (unlink(target) == -1)
X			perror("convtab (unlink failed)");
X		    if (link(tempf, target) == -1)
X			perror("convtab (link failed)");
X		    if (unlink(tempf) == -1)
X			perror("convtab (unlink failed)");
X		}
X	    }
X	    else if (strncmp(argv[0], "tab", 3) == 0)
X	    {
X		(void) sprintf(target, "tab.%s", argv[0] + 3);
X		if (verbose)
X		    (void) fprintf(stderr,
X			"convtab: %s (old format) to %s (ditroff format)\n",
X			argv[0], target);
X		if (!debug)
X		{
X		    ifp = fopen(argv[0], "r");
X		    ofp = fopen(tempf, "w");
X
X		    ttab = otread(ifp);
X		    (void) fprintf(ofp, "%s\n", target + 4);
X		    ditwrite(ttab, ofp);
X
X		    if (unlink(target) == -1)
X			perror("convtab (unlink failed)");
X		    if (link(tempf, target) == -1)
X			perror("convtab (link failed)");
X		    if (unlink(tempf) == -1)
X			perror("convtab (unlink failed)");
X		}
X	    }
X	    else
X		(void) fprintf(stderr,
X			   "convtab: skipping %s, (name prefix no good)\n",
X			   argv[0]);
X	}
X    }
X
X    /* no filenames given? that's OK, just convert new to old as a filter */
X    if (filecount == 0)
X    {
X	ttab = ditread(ifp);
X	otwrite(ttab, ofp);
X    }
X
X    return(0);
X}
X
X/* convtab.c ends here */
END_OF_FILE
if test 3575 -ne `wc -c <'convtab.c'`; then
    echo shar: \"'convtab.c'\" unpacked with wrong size!
fi
# end of 'convtab.c'
fi
if test -f 'ditread.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ditread.c'\"
else
echo shar: Extracting \"'ditread.c'\" \(6379 characters\)
sed "s/^X//" >'ditread.c' <<'END_OF_FILE'
X/*
X * ditread.c -- read ditroff-format tables into internal form
X *
X * Use this function to read a ditroff-style all-ASCII driver table into the
X * internal form given in the term.h header file.
X *
X * Standard C-style octal, hex and character escapes are accepted in string
X * and character fields. Due to lack of documentation, I don't know whether
X * {n,t}roff accepts hex escapes or character escape other than \[bnrt].
X *
X * The global ignorebad may be set to any nonzero value to cause this function
X * to simply skip invalid ditroff characters (such as \(bx) rather than
X * aborting when they are encountered. Otherwise, all errors emit a diagnostic
X * to stderr and call exit(1).
X *
X * This code expects to be able to call an escape processor escape() to do
X * its input character processing.
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include <ctype.h>
X#include "termtab.h"
X
Xextern char *strcpy(), *strchr(), *calloc();
Xextern void exit();
X
X#define CTRL(c)	((c) & 0x1F)
X#define META	0x80
X
Xint ignorebad;	/* if nz, skip invalid character names instead of bombing */
X
Xstatic char buf[BUFSIZ];	/* common input buffer */
X
Xstatic char *digetstr(key, fp)
X/* fill in the next string slot in the fixed-format part of the table */
Xchar	*key;
XFILE	*fp;
X{
X    char *lq, *rq;
X
X    (void) fgets(buf, BUFSIZ, fp);
X    if (strncmp(buf, key, strlen(key)))
X    {
X	(void) fprintf(stderr, "tabconv: expected %s, saw %s", key, buf);
X	exit(1);
X    }
X
X    /* delimit the value string part */
X    if ((lq = strchr(buf + strlen(key), '"')) == (char *)NULL)
X    {
X	(void) fprintf(stderr, "tabconv: missing leading quote at %s", buf);
X	exit(1);
X    }
X    if ((rq = strchr(++lq, '"')) == (char *)NULL)
X    {
X	(void) fprintf(stderr, "tabconv: missing trailing quote at %s", buf);
X	exit(1);
X    }
X    *rq = '\0';
X    
X    (void) escape(lq, lq);
X    return(lq);
X}
X
Xstatic void digetint(key, loc, fp)
Xchar	*key;
Xint	*loc;
XFILE	*fp;
X{
X    (void) fgets(buf, BUFSIZ, fp);
X    if (strncmp(buf, key, strlen(key)))
X    {
X	(void) fprintf(stderr, "tabconv: expected %s, saw %s", key, buf);
X	exit(1);
X    }
X
X    if (sscanf(buf + strlen(key), " %d", loc) != 1)
X    {
X	(void) fprintf(stderr, "tabconv: bad integer format at %s", buf);
X	exit(1);
X    }
X}
X
Xstatic int digetchr(tp, fp)
Xnrtab_t	*tp;
XFILE	*fp;
X{
X    char charname[BUFSIZ], charval[BUFSIZ];
X    register char **sp;
X    int fc, width;
X
X    if (fgets(buf, BUFSIZ, fp) == (char *)NULL)
X	return(EOF);
X
X    /* we must discard the width info, the old format doesn't support it */
X    if ((fc = sscanf(buf, "%s %d %s", charname, &width, charval + 1)) != 3)
X    {
X	(void) fprintf(stderr,
X	    "tabconv: only %d fields found, bad char definition at %s",fc,buf);
X	exit(1);
X    }
X
X    /* find the referenced character name in the {n,t}roff name table */
X    for (sp = ntnames; *sp != (char *)NULL; sp++)
X	if (strcmp(*sp, charname) == 0)
X	    break;
X    if (*sp == (char *)NULL)
X    {
X	(void) fprintf(stderr, "tabconv: bad character name at %s", buf);
X	if (!ignorebad)
X	    exit(1);
X    }
X    else	/* character name found OK */
X    {
X	/* the hackery below is so we don't botch zero-width characters */
X	if ((charval[0] = width) == 0)
X	    charval[0] |= META;
X
X	(void) escape(charval + 1, charval + 1);
X	tp->codetab[sp - ntnames] = addstring(charval, &tp->pool);
X
X	if (width == 0)
X	    tp->codetab[sp - ntnames][0] &=~ META;
X    }
X    return(0);
X}
X
Xnrtab_t *ditread(fp)
X/* fill in a terminal table structure from a ditroff-format description */
XFILE *fp;
X{
X    register char ch;
X
X#ifndef lint
X    nrtab_t	*tp = (nrtab_t *) calloc(sizeof(nrtab_t), 1);
X#else
X    nrtab_t	*tp = (nrtab_t *)NULL;
X#endif /* lint */
X
X    /* initialize the string table part of the malloc'd structure */
X    (void) newstrings(&tp->pool);
X
X    /* read in the fixed-format part of the table first */
X
X    /* read name line */
X    (void) fgets(buf, BUFSIZ, fp);
X    buf[strlen(buf) - 1] = '\0';
X    tp->name = addstring(buf, &tp->pool);
X
X    /* read integer printer parameters */
X    digetint("bset", &tp->bset, fp);
X    digetint("breset", &tp->breset, fp);
X    digetint("Hor", &tp->Hor, fp);
X    digetint("Vert", &tp->Vert, fp);
X    digetint("Newline", &tp->Newline, fp);
X    digetint("Char", &tp->Char, fp);
X#ifdef KANJI
X    digetint("Kchar", &tp->Kchar, fp);
X#endif KANJI
X    digetint("Em", &tp->Em, fp);
X    digetint("Halfline", &tp->Halfline, fp);
X    digetint("Adj", &tp->Adj, fp);
X
X    /* read string-valued parameters */
X    tp->twinit	= addstring(digetstr("twinit", fp), &tp->pool);
X    tp->twrest	= addstring(digetstr("twrest", fp), &tp->pool);
X    tp->twnl	= addstring(digetstr("twnl", fp), &tp->pool);
X    tp->hlr	= addstring(digetstr("hlr", fp), &tp->pool);
X    tp->hlf	= addstring(digetstr("hlf", fp), &tp->pool);
X    tp->flr	= addstring(digetstr("flr", fp), &tp->pool);
X    tp->bdon	= addstring(digetstr("bdon", fp), &tp->pool);
X    tp->bdoff	= addstring(digetstr("bdoff", fp), &tp->pool);
X    tp->iton	= addstring(digetstr("iton", fp), &tp->pool);
X    tp->itoff	= addstring(digetstr("itoff", fp), &tp->pool);
X    tp->ploton	= addstring(digetstr("ploton", fp), &tp->pool);
X    tp->plotoff = addstring(digetstr("plotoff", fp), &tp->pool);
X    tp->up	= addstring(digetstr("up", fp), &tp->pool);
X    tp->down	= addstring(digetstr("down", fp), &tp->pool);
X    tp->right	= addstring(digetstr("right", fp), &tp->pool);
X    tp->left	= addstring(digetstr("left", fp), &tp->pool);
X
X    /* skip blank line(s), then expect character set keyword */
X    do {
X    	(void) fgets(buf, BUFSIZ, fp);
X    } while
X	(buf[0] == '\n');
X    if (strcmp(buf, "charset\n"))
X    {
X	(void) fprintf(stderr, "tabconv: charset keyword missing\n");
X	exit(1);
X    }
X
X    /* insert defaults for printable characters */
X    for (ch = CHARMIN; ch < CHARMAX && isprint(ch); ch++)
X    {
X	buf[0] = 1;				/* set default width */
X	(void) strcpy(buf + 1, ntnames[ch - CHARMIN]);
X	tp->codetab[ch-CHARMIN] = addstring(buf, &tp->pool);
X    }
X
X    /* now read the character definitions */
X    while (digetchr(tp, fp) != EOF)
X	continue;
X
X    return(tp);
X}
X
X/* ditread.c ends here */
END_OF_FILE
if test 6379 -ne `wc -c <'ditread.c'`; then
    echo shar: \"'ditread.c'\" unpacked with wrong size!
fi
# end of 'ditread.c'
fi
if test -f 'ditwrite.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ditwrite.c'\"
else
echo shar: Extracting \"'ditwrite.c'\" \(2818 characters\)
sed "s/^X//" >'ditwrite.c' <<'END_OF_FILE'
X/*
X * ditwrite.c -- dump an internal driver-table representation in ditroff form
X *
X * Dumps a driver-table structure in all-ASCII ditroff format. Uses octal
X * escape and \b, \t, \n, \r for nonprintable characters.
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include <ctype.h>
X#include "termtab.h"
X
Xstatic void tdump(fp, label, val)
X/* dump a string (in quotes) with a given label prepended */
XFILE *fp;
Xchar *label;
Xchar *val;
X{
X    if (val != (char *)NULL)
X    {
X	char outbuf[BUFSIZ];
X
X	(void) expand(val, outbuf);
X	(void) fprintf(fp, "%-12s\"%s\"\n", outbuf, label);
X    }
X}
X
Xstatic void cdump(fp, label, width, val)
X/* dump a character with its width */
XFILE *fp;
Xchar *label;
Xint width;
Xchar *val;
X{
X    if (val != (char *)NULL)
X    {
X	char outbuf[BUFSIZ];
X
X	(void) expand(val, outbuf);
X	(void) fprintf(fp, "%s %d %s\n", outbuf, label, width);
X    }
X}
X
Xvoid ditwrite(tp, fp)
Xnrtab_t *tp;
XFILE	*fp;
X{
X    register char **ctab = tp->codetab;
X
X    /* first, dump integer parameters */
X    (void) fprintf(fp, "bset        %d\n", tp->bset);
X    (void) fprintf(fp, "breset      %d\n", tp->breset);
X    (void) fprintf(fp, "Hor         %d\n", tp->Hor);
X    (void) fprintf(fp, "Vert        %d\n", tp->Vert);
X    (void) fprintf(fp, "Newline     %d\n", tp->Newline);
X    (void) fprintf(fp, "Char        %d\n", tp->Char);
X#ifdef KANJI
X    (void) fprintf(fp, "Kchar        %d\n", tp->Kchar);
X#endif KANJI
X    (void) fprintf(fp, "Em          %d\n", tp->Em);
X    (void) fprintf(fp, "Halfline    %d\n", tp->Halfline);
X    (void) fprintf(fp, "Adj         %d\n", tp->Adj);
X
X    /* next, dump standard control strings */
X    tdump(fp, "twinit", tp->twinit);
X    tdump(fp, "twrest", tp->twrest);
X    tdump(fp, "twnl", tp->twnl);
X    tdump(fp, "hlr", tp->hlr);
X    tdump(fp, "hlf", tp->hlf);
X    tdump(fp, "flr", tp->flr);
X    tdump(fp, "bdon", tp->bdon);
X    tdump(fp, "bdoff", tp->bdoff);
X    tdump(fp, "iton", tp->iton);
X    tdump(fp, "itoff", tp->itoff);
X    tdump(fp, "ploton", tp->ploton);
X    tdump(fp, "plotoff", tp->plotoff);
X    tdump(fp, "up", tp->up);
X    tdump(fp, "down", tp->down);
X    tdump(fp, "right", tp->right);
X    tdump(fp, "left", tp->left);
X
X    /* finally, dump the character table */
X    (void) fputs("\ncharset\n", fp);
X    for (ctab = ntnames; ctab[0] != (char *)NULL; ctab++)
X    {
X	char *cstr = tp->codetab[ctab - ntnames];
X
X	if ((cstr[0] || cstr[1]) && strcmp(ctab[0], cstr + 1))
X	    cdump(fp, ctab[0], cstr[0], cstr + 1);
X    }
X}
X
X/* ditwrite.c ends here */
END_OF_FILE
if test 2818 -ne `wc -c <'ditwrite.c'`; then
    echo shar: \"'ditwrite.c'\" unpacked with wrong size!
fi
# end of 'ditwrite.c'
fi
if test -f 'dotmatrix.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dotmatrix.1'\"
else
echo shar: Extracting \"'dotmatrix.1'\" \(4836 characters\)
sed "s/^X//" >'dotmatrix.1' <<'END_OF_FILE'
X.TH DOTMATRIX 1 "Feb 23, 1988"
X.SH NAME
Xdotmatrix \- make driver table and postprocessor for dot-matrix printer
X.SH SYNOPSIS
X.BR dotmatrix
X[
X.IR -nvtpdq " ] [ " postprocessor-name " ]"
X.PP
X.SH DESCRIPTION
XThis utility interprets a file containing various directives specifying
Xcharacter set graphics, highlight sequences, and the like. By default, it
Xproduces as output the following files:
X.TP 10
Xtab.mx80
Xa ditroff-format driver file
X.TP 10
Xmx80.c
Xa postprocessor for use with nroff
X.TP 10
Xmx80.test 
Xa test file that exercises the driver and postprocessor.
X.PP
XIf a command line argument is given, it is taken as the name for the generated
Xpostprocessor and substituted for the `mx80' in the default names above.
X.PP
XThe directives file format is all-ASCII, line oriented, and similar to that of
Xa ditroff table. In fact, everything up to and including a line reading
X`charset' is passed through unaltered to the driver table (except that comments
Xbeginning with # are stripped out).
X.PP
XFollowing the charset directive, the normal character set table is replaced by
Xa sequence of \fBcomment\fR, \fBmode\fR, \fBtoggle\fR, \fBoverstrike\fR and
X\fBpicture\fR directives.
XComments beginning with # may be present anywhere but in the body of
Xa picture section and will be discarded (except that comments trailing a
X\fBpicture\fR directive are include in the appropriate place in the generated
Xtest file).
X.PP
XThe directives are as follows:
X.SS
X\fBcomment\fR <text>
XText following a comment directive is embedded in a comment in the generated
Xpostprocessor source. It is recommended that you use this feature to identify
Xthe font and its author and explain any special features it may have.
X.SS
X\fBmode\fR <name> <height> <format>
X.PP
XDeclares a print mode. The first argument must be a mode name of 10 or fewer
Xletters. The second must be a decimal numeric height in pixels. The third must
Xbe a printf-style string with the following escapes defined:
X.IP
X.TP
X%h
Xhigh byte of graphic length in pixels
X.TP
X%l
Xlow byte of graphic length in pixels
X.TP
X%c
Xgraphic raster by column, leftmost column first
X.RE
XAll normal C-style escapes and the \\e convention for ESC are also accepted.
X.SS
X\fBtoggle\fR <escape> <on> <off>
X.PP
XDeclares a given escape to be a toggle in the postprocessor, and gives the
Xtwo on and off strings that will implement it.
X.SS
X\fBoverstrike\fR <escape> <char>
X.PP
XDeclares a given escape to be an overstrike toggle in the postprocessor, and
Xgives the overstrike character to use.
X.SS
X\fBpicture\fR <name> <em-width> <mode> <width>
X.PP
XThe \fBpicture\fR directive takes four arguments. The first is the nroff
Xescape name, the second is the picture's width in ems. The third must match
Xa declared mode, and the fourth should be a decimal numeric width.
X.PP
XEach picture directive must be followed by an 8-line bit image for the escape.
XAsterisk characters will be read as `on'. Trailing non-asterisks designating
Xbits off may be omitted.
X.PP
XThe -n option prevents \fIdotmatrix\fR(1) from trying to put any knowledge of 
Xthe printer into the driver; only standard escapes for the generated
Xpostprocessor will be generated (see the NOTE below).
X.PP
XThe -v option causes the program to echo each input line along with remarks
Xabout how it's being processed. The -q option makes the program extra quiet,
Xsuppressing normal messages about which special characters and highlights
Xneed to be handled in the postprocessor and which will be emitted through the
Xdriver table alone.
X.PP
XThe -t, -p and -d options suppress creation of the test,
Xpostprocessor source and driver table files respectively.
X.PP
XWhen creating new picture files, it is recommended that you start from an
Xexisting file and modify it, rather than starting from scratch.
X.SH DIAGNOSTICS
XVarious self-explanatory diagnostics may be emitted to stderr. 0 is returned
Xfrom a correct run, 1 if a parse error terminated translation of the input
Xfile, 2 if some output file could not be opened.
X.SH FILES
X.TP 12
Xpost.proto
Xprototype C code for the printer-specific postprocessor
X.SH NOTE
XNroff barfs on nuls in escape strings. This is what makes the postprocessor
Xnecessary. In place of escapes that would include nuls, the generated driver
Xtable will emit strings to the postprocessor of the form SI + <char> + SO (so
Xthey'll pass through \fIcol\fR(1) correctly without the -p option).
X.PP
XIf you use col, <data> must be printable; this effectively limits you to
Xat most 96 escapes containing NULs (though \fIdotmatrix\fR(1) will generate
Xescapes with <char> 128 to 255 without complaining). Using col probably also
Xmeans you want to use a driver table generated with the the -n option, to
Xforce all the nonprintable-character emission into the postprocessor.
X.SH AUTHOR
XEric S. Raymond (...!rutgers!vu-vlsi!snark!eric) Feb 1988
X.SH SEE ALSO
Xconvtab(1), term(5)
END_OF_FILE
if test 4836 -ne `wc -c <'dotmatrix.1'`; then
    echo shar: \"'dotmatrix.1'\" unpacked with wrong size!
fi
# end of 'dotmatrix.1'
fi
if test -f 'escapes.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'escapes.c'\"
else
echo shar: Extracting \"'escapes.c'\" \(2229 characters\)
sed "s/^X//" >'escapes.c' <<'END_OF_FILE'
X/*
X * escape.c -- interpret and expand character escapes
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include <ctype.h>
X
Xint escape(cp, tp)
X/* interpret standard C-style octal and hex escapes plus \e for ESC */
Xchar	*cp, *tp;
X{
X    extern char *strchr();
X    int ccount = 0;
X
X    while (*cp)
X    {
X	int	cval = 0;
X
X	if (*cp == '\\' && strchr("0123456789xX", cp[1]))
X	{
X	    char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
X	    int dcount = 0;
X
X	    if (*++cp == 'x' || *cp == 'X')
X		for (++cp; (dp = strchr(hex, *cp)) && dcount++ < 2; cp++)
X		    cval = (cval * 16) + (dp - hex) / 2;
X	    else if (*cp == '0')
X		while (strchr("01234567", *cp) && dcount++ < 3)
X		    cval = (cval * 8) + (*cp++ - '0');
X	    else
X		while (strchr("0123456789", *cp) && dcount++ < 3)
X		    cval = (cval * 10) + (*cp++ - '0');
X	}
X	else if (*cp == '\\')		/* C-style character escape */
X	{
X	    switch (*++cp)
X	    {
X	    case '\\': cval = '\\'; break;
X	    case 'n': cval = '\n'; break;
X	    case 't': cval = '\t'; break;
X	    case 'b': cval = '\b'; break;
X	    case 'r': cval = '\r'; break;
X	    case 'e': cval = 0x1b; break;
X	    default: cval = *cp;
X	    }
X	    cp++;
X	}
X	else
X	    cval = *cp++;
X	*tp++ = cval;
X	ccount++;
X    }
X    *tp = '\0';
X    return(ccount);
X}
X
Xint expand(sp, tp)
X/* generate a restricted set of escapes for nonprintable chars in a string */
Xchar *sp;
Xchar *tp;
X{
X    char *start;
X
X    for (start = tp; *sp; sp++)
X    {
X	if (!isprint(*sp) || *sp == '\\')
X	    *tp++ = '\\';
X
X	if (*sp == '\\')
X	    *tp++ = '\\';
X	else if (*sp == '\b')
X	    *tp++ = '\b';
X	else if (*sp == '\n')
X	    *tp++ = '\n';
X	else if (*sp == '\t')
X	    *tp++ = '\t';
X	else if (*sp == '\r')
X	    *tp++ = '\r';
X	else if (isprint(*sp))
X	    *tp++ = *sp;
X	else
X	{
X	    (void) sprintf(tp, "\\%03.3o", toascii(*sp));
X	    tp += strlen(tp);
X	}
X    }
X    *tp = '\0';
X    return(tp - start);
X}
X
X/* escape.c ends here */
END_OF_FILE
if test 2229 -ne `wc -c <'escapes.c'`; then
    echo shar: \"'escapes.c'\" unpacked with wrong size!
fi
# end of 'escapes.c'
fi
if test -f 'otread.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'otread.c'\"
else
echo shar: Extracting \"'otread.c'\" \(2820 characters\)
sed "s/^X//" >'otread.c' <<'END_OF_FILE'
X/*
X * otread.c -- read a driver table in old nroff format into core
X *
X * Use this function to read an old-nroff-style driver table into the
X * internal form given in the term.h header file. Note that the terminal
X * name slot is *not* filled in.
X *
X * This function will return NULL if the input file is too short (i.e its
X * length is less than sizeof(int) + sizeof(t_stor) + the byte count
X * in the file's first int). It will also return NULL if it finds an offset
X * larger than the string table size.
X *
X * Warning: the driver structure pointer handed back uses static storage,
X * a second otread() call will overwrite it.
X *
X * Also, the code performs mildly unnatural acts on some structure fields.
X * See the last comment before the end of the routine and beware. If the
X * method fails it's more than likely to result in garbaged pointers in the
X * returned internal-representation structure and core dumps later on.
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include "termtab.h"
X
Xextern char *malloc();
X
Xnrtab_t *otread(tfp)
XFILE *tfp;
X{
X    int		c_size, *ip;
X    register char	**pp, *mptr;
X    static nrext_t	external;
X    static nrtab_t	internal;
X
X    /* string table size */
X    if (fread((char *)&c_size, sizeof(int), 1, tfp) != 1)
X	return((nrtab_t *)NULL);
X
X    /* fixed-size header part */
X    if (fread((char *)&external, sizeof(external), 1, tfp) != 1)
X	return((nrtab_t *)NULL);
X
X    /* now read the strings table into core */
X    if (fread(mptr = malloc((unsigned)c_size), c_size, 1, tfp) != 1)
X	return((nrtab_t *)NULL);
X
X    internal.bset = external.bset;
X    internal.breset = external.breset;
X    internal.Hor = external.Hor;
X    internal.Vert = external.Vert;
X    internal.Newline = external.Newline;
X    internal.Char = external.Char;
X    internal.Em = external.Em;
X    internal.Halfline = external.Halfline;
X    internal.Adj = external.Adj;
X
X    /*
X     * Wooo-ah! Tricky-shit alert! We step through the fields of the external
X     * and internal representation structures as though they were arrays of
X     * (int) and (char *) respectively. C's structure-padding rules *seem*
X     * to almost guarantee this will work, but I wouldn't bet the farm on it
X     * given some of the weird broken architectures and compilers out there.
X     */
X    for (ip = &external.twinit, pp = &internal.twinit; pp < &internal.zzz; )
X	if (*ip > c_size)
X	    return((nrtab_t *)NULL);
X	else
X	    *pp++ = mptr + *ip++;
X
X    return(&internal);
X}
X
X/* otread.c ends here */
END_OF_FILE
if test 2820 -ne `wc -c <'otread.c'`; then
    echo shar: \"'otread.c'\" unpacked with wrong size!
fi
# end of 'otread.c'
fi
if test -f 'otwrite.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'otwrite.c'\"
else
echo shar: Extracting \"'otwrite.c'\" \(6014 characters\)
sed "s/^X//" >'otwrite.c' <<'END_OF_FILE'
X/*
X * otwrite.c -- dump an internal driver-table representation in old-nroff form
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X *
X * This stuff was Bruce Townsend & Ian Darwin's table.c code in a former life,
X * but the data structures are different and cleaner now.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include "termtab.h"
X
Xextern char *strcpy();
Xextern void exit();
X
Xstatic void addchar(string, pp)
Xchar	*string;
Xstrtab	*pp;
X{
X    pp->c_pointer[pp->n_strings] = pp->c_end;
X    pp->c_end += (pp->c_length[pp->n_strings] = strlen(string + 2) + 2) + 1;
X    if (pp->c_end >= pp->c_data + C_SIZE)
X    {
X	(void) fprintf(stderr, "Table size too small, increase it!\n");
X	exit(1);
X    }
X    /*
X     * copy in the first two bytes without checking for a NUL, this is
X     * so we handle the (legal!) case of 0-length characters correctly
X     */
X    *pp->c_pointer[pp->n_strings] = *string++;
X    *(pp->c_pointer[pp->n_strings]+1) = *string++;
X
X     /* now copy the rest */
X    (void) strcpy(pp->c_pointer[pp->n_strings++] + 2, string);
X}
X
Xstatic int findchar(string, pp)
Xstrtab	*pp;
Xchar	*string;
X{
X    int	c_len, s_len, i;
X
X    for (i = 0; i < pp->n_strings; i++)
X    {
X	if ((c_len = pp->c_length[i]) >= (s_len = strlen (string+2) + 2))
X	{
X	    if (!char_comp (string, pp->c_pointer[i] + c_len - s_len, s_len))
X		return (pp->c_pointer[i] + c_len - s_len - pp->c_data);
X	}
X    }
X    (void) fprintf(stderr,
X		   "Serious bug! character %s not found in table\n", string);
X    exit(1);
X    /* NOTREACHED */
X}
X
Xstatic void write_err()
X{
X    (void) fprintf(stderr, "Write to file failed\n");
X    exit(1);
X}
X
Xvoid otwrite(tp, fp)
Xnrtab_t *tp;
XFILE	*fp;
X{
X    int	i, j, i_len, j_len, ch;
X    char	*tail, *start, *char_pointer;
X    static nrext_t t_stor;
X    static strtab otab;
X
X    newstrings(&otab);
X
X    /*
X     * copy the integer values from the initialized structure
X     * to the storage structure
X     */
X    t_stor.bset = tp->bset;
X    t_stor.breset = tp->breset;
X    t_stor.Hor = tp->Hor;
X    t_stor.Vert = tp->Vert;
X    t_stor.Newline = tp->Newline;
X    t_stor.Char = tp->Char;
X    t_stor.Em = tp->Em;
X    t_stor.Halfline = tp->Halfline;
X    t_stor.Adj = tp->Adj;
X
X    /*
X     * force an empty string with a 0-length head character to exist
X     * at offset 0 of the otab string table
X     */
X    (void) addchar("\000\000", &otab);
X
X    /*
X     * copy control strings out of the in-core form into the otab string table
X     */
X    (void) addstring(tp->twinit, &otab);
X    (void) addstring(tp->twrest, &otab);
X    (void) addstring(tp->twnl, &otab);
X    (void) addstring(tp->hlr, &otab);
X    (void) addstring(tp->hlf, &otab);
X    (void) addstring(tp->flr, &otab);
X    (void) addstring(tp->bdon, &otab);
X    (void) addstring(tp->bdoff, &otab);
X    (void) addstring(tp->iton, &otab);
X    (void) addstring(tp->itoff, &otab);
X    (void) addstring(tp->ploton, &otab);
X    (void) addstring(tp->plotoff, &otab);
X    (void) addstring(tp->up, &otab);
X    (void) addstring(tp->down, &otab);
X    (void) addstring(tp->right, &otab);
X    (void) addstring(tp->left, &otab);
X
X    /* copy character expansions to the new table */
X    for (ch = CHARMIN; ch < CHARMAX; ch++)
X	if (tp->codetab[ch - CHARMIN] != (char *)NULL)
X	    addchar(tp->codetab[ch - CHARMIN], &otab);
X
X    /* eliminate strings which are tails of other strings */
X    for (i = 0; i < otab.n_strings; i++)
X    {
X	if (!otab.c_pointer[i])
X	    continue;	/* String cleared out */
X	i_len = otab.c_length[i];
X	for (j = 0; j < otab.n_strings; j++)
X	{
X	    if (i == j || ! otab.c_pointer[j]) continue;
X	    j_len = otab.c_length[j];
X	    if (i_len <= j_len)	/* string i could be tail of string j */
X	    {
X		tail = otab.c_pointer[j] + j_len - i_len;
X		if (! char_comp(otab.c_pointer[i], tail, i_len)) {
X		    otab.c_pointer[i] = 0;
X		    break;
X		}
X	    }
X	}
X    }
X
X    /* Compress the otab.c_data array */
X    char_pointer = otab.c_data;
X    for (i = j = 0; i < otab.n_strings; i++)
X    {
X	if (! (start = otab.c_pointer[i]))
X	    continue;
X	otab.c_pointer[j] = char_pointer;
X	otab.c_length[j++] = otab.c_length[i];
X	for (i_len = otab.c_length[i]; i_len--;)
X	    *char_pointer++ = *start++;
X	*char_pointer++ = 0;
X    }
X    otab.n_strings = j;
X    otab.c_size = char_pointer - otab.c_data;
X
X    /* Now find each string in this table and provide an index to it */
X    t_stor.twinit = findstring(tp->twinit, &otab);
X    t_stor.twrest = findstring(tp->twrest, &otab);
X    t_stor.twnl = findstring(tp->twnl, &otab);
X    t_stor.hlr = findstring(tp->hlr, &otab);
X    t_stor.hlf = findstring(tp->hlf, &otab);
X    t_stor.flr = findstring(tp->flr, &otab);
X    t_stor.bdon = findstring(tp->bdon, &otab);
X    t_stor.bdoff = findstring(tp->bdoff, &otab);
X    t_stor.iton = findstring(tp->iton, &otab);
X    t_stor.itoff = findstring(tp->itoff, &otab);
X    t_stor.ploton = findstring(tp->ploton, &otab);
X    t_stor.plotoff = findstring(tp->plotoff, &otab);
X    t_stor.up = findstring(tp->up, &otab);
X    t_stor.down = findstring(tp->down, &otab);
X    t_stor.right = findstring(tp->right, &otab);
X    t_stor.left = findstring(tp->left, &otab);
X
X    for (ch = CHARMIN; ch < CHARMAX; ch++)
X	if (tp->codetab[ch-CHARMIN] == (char *)NULL)
X	    t_stor.codetab[ch-CHARMIN] = 0;	/* empty expansion */
X	else
X	    t_stor.codetab[ch-CHARMIN]=findchar(tp->codetab[ch-CHARMIN],&otab);
X
X    t_stor.zzz = 0;
X
X    /* Write the character storage block size */
X    if (fwrite((char *)&otab.c_size, sizeof(otab.c_size), 1, fp) != 1)
X	write_err();
X
X    /* now the fixed part */
X    if (fwrite(&t_stor, sizeof(t_stor), 1, fp) != 1)
X	write_err();
X
X    /* finally, write the code table */
X    if (fwrite(otab.c_data,sizeof(*otab.c_data),otab.c_size,fp) != otab.c_size)
X	write_err();
X}
X
X/* otwrite.c ends here */
END_OF_FILE
if test 6014 -ne `wc -c <'otwrite.c'`; then
    echo shar: \"'otwrite.c'\" unpacked with wrong size!
fi
# end of 'otwrite.c'
fi
if test -f 'post.proto' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'post.proto'\"
else
echo shar: Extracting \"'post.proto'\" \(1671 characters\)
sed "s/^X//" >'post.proto' <<'END_OF_FILE'
X
X#include <stdio.h>
X#include <ctype.h>
X
X#define MGL	64	/* maximum number of columns in a graphic */
X#define BS	010	/* ASCII backspace (for overstrikes) */
X#define SI	0x17	/* ASCII SI starts a graphics escape */
X#define SO	0x16	/* ASCII SO ends a graphics escape */
X
Xstatic char	overc = ' ';
X
Xstruct xlat
X{
X    int     tstate;	/* -1 if normal, 0 if this one, 1 if next */
X    int	    len;	/* count of bytes in the graphic */
X    char    bytes[MGL];	/* tme actual bytes of the graphic */
X}
Xgraphic[] =
X{
X$A	/***** GRAPHIC TABLE GOES HERE *****/
X};
X
Xmain()
X{
X    register int    c, i, j;
X
X    while ((c = getchar()) != EOF)
X    {
X	if (c == SI)	/* a graphic or overstrike change */
X	{
X	    /* check that the key character is in range */
X	    if ((c = getchar()) && c >= ' ' && c < MAXSPCH)
X	    {
X		register struct xlat *gr = &graphic[c - ' '];
X
X		/* this is the logic for doing toggle pairs */
X		switch (gr->tstate)
X		{
X		case -1:	/* the character isn't a toggle */
X		    break;
X
X		case 0:		/* print start string */
X		    gr->tstate = 1;
X		    break;
X
X		case 1:		/* print end string */
X		    gr->tstate = 0;
X		    gr++;
X		    break;
X
X		case 2:		/* change overstrike */
X		    if (overc == gr->bytes[0])
X			overc = ' ';
X		    else
X			overc = gr->bytes[0];
X		    continue;	/* don't want to emit a graphic */
X		}
X
X		/* now emit the bytes of the adjusted character */
X		for (j = 0; j < gr->len; j++)
X		    putchar(gr->bytes[j]);
X	    }
X	}
X	else if (c == SO)		/* this appeases col(1) */ 
X	    continue;
X	else if (!isspace(overc))	/* overstrike is enabled */
X	{
X	    putchar(overc);
X	    putchar(BS);
X	    putchar(c);
X	}
X	else				/* ordinary character */
X	    putchar(c);
X    }
X}
X
END_OF_FILE
if test 1671 -ne `wc -c <'post.proto'`; then
    echo shar: \"'post.proto'\" unpacked with wrong size!
fi
# end of 'post.proto'
fi
if test -f 'term.5' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'term.5'\"
else
echo shar: Extracting \"'term.5'\" \(6726 characters\)
sed "s/^X//" >'term.5' <<'END_OF_FILE'
X.TH TERM 5
X.SH NAME
Xterm \- terminal driving tables for nroff (old format)
X.SH DESCRIPTION
XNote: if you have AT&T System Vr3 or are using the enhanced DWB software
Xwith
X.IR ditroff (1),
Xthis manual page will probably just mislead you! Your nroff driver files now
Xlive in /usr/lib/nterm in an all-ASCII format that should be documented as
X.IR nterm (5)
Xin your manuals.
X.PP
X.IR Nroff (1)
Xuses driving tables to customize its output for various types of
Xoutput devices, such as printing terminals, special word-processing
Xterminals (such as Diablo, Qume, or NEC Spinwriter mechanisms),
Xor special output filter programs.  These driving tables are written
Xas C programs, compiled, and installed in
X\f3/usr/lib/term/tab\f2name\fP ,
Xwhere
X.I name\^
Xis the name for that terminal type as given in
X.IR term (7).
XThe structure of the tables is as follows:
X.PP
X.nf
X.ta 5m 10m 15m 20m 25m 30m 35m 40m 45m 50m 55m 60m
X#define	INCH	240
X
Xstruct {
X	int bset;
X	int breset;
X	int Hor;
X	int Vert;
X	int Newline;
X	int Char;
X	int Em;
X	int Halfline;
X	int Adj;
X	char *twinit;
X	char *twrest;
X	char *twnl;
X	char *hlr;
X	char *hlf;
X	char *flr;
X	char *bdon;
X	char *bdoff;
X	char *iton;
X	char *itoff;
X	char *ploton;
X	char *plotoff;
X	char *up;
X	char *down;
X	char *right;
X	char *left;
X	char *codetab[256\-32];
X	char *zzz;
X} t;
X.fi
X.DT
X.PP
XThe meanings of the various fields are as follows:
X.TP 10
X.I bset\^
Xbits to set in the
X.I c_oflag\^
Xfield of the
X.I termio\^
Xstructure (see
X.IR tty (4))
Xbefore output.
X.TP 10
X.I breset\^
Xbits to reset in the
X.I c_oflag\^
Xfield of the
X.I termio\^
Xstructure
Xbefore output.
X.TP 10
X.I Hor\^
Xhorizontal resolution in fractions of an inch.
X.TP 10
X.I Vert\^
Xvertical resolution in fractions of an inch.
X.TP 10
X.I Newline\^
Xspace moved by a newline (linefeed) character in fractions
Xof an inch.
X.TP 10
X.I Char\^
Xquantum of character sizes, in fractions of an inch.
X(i.e., a character is a multiple of Char units wide)
X.TP 10
X.I Kchar\^
Xquantum of Kanji character sizes, in fractions of an inch.
X(i.e., a Kanji character is a multiple of Kchar units wide)
XMany systems do not have this element included in the structure.
X.TP 10
X.I Em\^
Xsize of an em in fractions of an inch.
X.TP 10
X.I Halfline\^
Xspace moved by a half-linefeed (or half-reverse-linefeed)
Xcharacter in fractions of an inch.
X.TP 10
X.I Adj\^
Xquantum of white space, in fractions of an inch.
X(i.e., white spaces are a multiple of Adj units wide)
X.IP
XNote: if this is less than the size of the space
Xcharacter (in units of Char; see below for how the
Xsizes of characters are defined),
X.I nroff\^
Xwill output
Xfractional spaces using plot mode.  Also, if the
X.B \-e
Xswitch to
X.I nroff\^
Xis used, Adj is set equal to Hor by
X.IR nroff .
X.TP 10
X.I twinit\^
Xset of characters used to initialize the terminal
Xin a mode suitable for
X.IR nroff .
X.TP 10
X.I twrest\^
Xset of characters used to restore the terminal to
Xnormal mode.
X.TP 10
X.I twnl\^
Xset of characters used to move down one line.
X.TP 10
X.I hlr\^
Xset of characters used to move up one-half line.
X.TP 10
X.I hlf\^
Xset of characters used to move down one-half line.
X.TP 10
X.I flr\^
Xset of characters used to move up one line.
X.TP 10
X.I bdon\^
Xset of characters used to turn on hardware boldface mode,
Xif any.
X.I Nroff\^
Xassumes that boldface mode is reset automatically by the
X.I twnl\^
Xstring, because many letter-quality printers reset the boldface
Xmode when they receive a carriage return;
Xthe
X.I twnl\^
Xstring should include whatever characters are necessary to
Xreset the boldface mode.
X.TP 10
X.I bdoff\^
Xset of characters used to turn off hardware boldface mode,
Xif any.
X.TP 10
X.I iton\^
Xset of characters used to turn on hardware italics mode,
Xif any.
X.TP 10
X.I itoff\^
Xset of characters used to turn off hardware italics mode,
Xif any.
X.TP 10
X.I ploton\^
Xset of characters used to turn on hardware plot mode
X(for Diablo type mechanisms), if any.
X.TP 10
X.I plotoff\^
Xset of characters used to turn off hardware plot mode
X(for Diablo type mechanisms), if any.
X.TP 10
X.I up\^
Xset of characters used to move up one resolution unit
X(Vert) in plot mode, if any.
X.TP 10
X.I down\^
Xset of characters used to move down one resolution unit
X(Vert) in plot mode, if any.
X.TP 10
X.I right\^
Xset of characters used to move right one resolution unit
X(Hor) in plot mode, if any.
X.TP 10
X.I left\^
Xset of characters used to move left one resolution unit
X(Hor) in plot mode, if any.
X.TP 10
X.I codetab\^
Xdefinition of characters needed to print an
X.I nroff\^
Xcharacter
Xon the terminal.
XThe first byte is the number of character units (Char) needed to hold the
Xcharacter; i.e., ``\\001'' is one unit wide, ``\\002'' is two
Xunits wide, etc.  The high-order bit (0200) is on if
Xthe character is to be underlined in underline mode
X(.ul).
XThe rest of the bytes are the characters used to produce the character in
Xquestion.  If the character has the sign (0200) bit on,
Xit is a code to move the terminal in plot mode.  It is
Xencoded as:
X.RS
X.IP "0100 bit on" 15
Xvertical motion.
X.IP "0100 bit off" 15
Xhorizontal motion.
X.IP "040 bit on" 15
Xnegative (up or left) motion.
X.IP "040 bit off" 15
Xpositive (down or right) motion.
X.IP "037 bits" 15
Xnumber of such motions to make.
X.RE
X.TP 10
X.I zzz\^
Xa zero terminator at the end.
X.PP
XAll quantities which are in units of fractions of an inch should
Xbe expressed as
X.RI INCH* num / denom ,
Xwhere
X.I num\^
Xand
X.I denom\^
Xare respectively the numerator and denominator of the fraction; i.e.,
X1/48 of an inch would be written as ``INCH/48''.
X.PP
XIf any sequence of characters does not pertain to the output device,
Xthat sequence should be given as a null string.
X.PP
XIf you have a source license:
X.br
XThe source code for the terminal
X.I name\^
Xlives in the directory /usr/src/cmd/text/roff.d/terms.d in a file called
X.BI tab name .c. 
XWhen a new terminal type is added, the file
X.I maketerms.c\^
Xshould be updated to `#include' the source to that driving table;
Xnote that the various terminal types are grouped into ``parts'' labelled
X.BR PART1 ,
X.BR PART2 ,
Xand
X.BR PART3 .
XIf necessary, more parts can be added.  Other changes necessary to
X.I maketerms.c\^
Xare left as an exercise to the reader.
XThe makefile
X.I terms.mk\^
Xin that directory should then be updated.
X.PP
XIf you do not have source license, but have Bruce Townsend's
X.I table\^
Xutility:
X.br
XThe source code for the terminal
X.I name\^
Xis in a file called
X.BI tab name .c.
XWhen a new terminal type is added, the file
X.I Makefile\^
Xin the same directory should be updated.
XJust add the name
X.BI tab name
Xto the definition of
X.BR TABFILES .
XThen type
X.BI "make tab" name.
XStore the result in
X.B /usr/lib/term.
X.SH FILES
X/usr/lib/term/tab\f2name\fP	driving tables
X.br
Xtab\f2name\fP.c	source for driving tables
X.SH SEE ALSO
Xtroff(1), term(7)
END_OF_FILE
if test 6726 -ne `wc -c <'term.5'`; then
    echo shar: \"'term.5'\" unpacked with wrong size!
fi
# end of 'term.5'
fi
if test -f 'termtab.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'termtab.c'\"
else
echo shar: Extracting \"'termtab.c'\" \(2812 characters\)
sed "s/^X//" >'termtab.c' <<'END_OF_FILE'
X/*
X * termtab.c -- common declarations for nroff table conversion
X *
X * This code brought to you as a public service by Eric S. Raymond, Feb 1988
X * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
X * freely, but don't try to make money selling it unless you're going to send
X * me a cut. Send bug reports, love letters and death threats to eric@snark
X * aka ...!rutgers!vu-vlsi!snark!eric.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include "termtab.h"
X
Xextern char *strcpy();
Xextern void exit();
X
Xchar *ntnames[] =	/* [nt]roff character name translation */
X{
X" ", "!","\"", "#", "$", "%", "&", "'",
X"(", ")", "*", "+", ",", "-", ".", "/",
X"0", "1", "2", "3", "4", "5", "6", "7",
X"8", "9", ":", ";", "<", "=", ">", "?",
X"@", "A", "B", "C", "D", "E", "F", "G",
X"H", "I", "J", "K", "L", "M", "N", "O",
X"P", "Q", "R", "S", "T", "U", "V", "W",
X"X", "Y", "Z", "[", "\\","]", "^", "_",
X"`", "a", "b", "c", "d", "e", "f", "g",
X"h", "i", "j", "k", "l", "m", "n", "o",
X"p", "q", "r", "s", "t", "u", "v", "w",
X"x", "y", "z", "{", "|", "}", "~","\\|",
X"hy", "bu", "sq", "em", "ru", "14", "12", "34", 
X"\\-","fi", "fl", "ff", "Fi", "Fl", "de", "dg", 
X"sc", "fm", "aa", "ga", "ul", "sl", "\\^", "\\ ", 
X"*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", 
X"*i", "*k", "*l", "*m", "*n", "*c", "*o", "*p", 
X"*r", "*s", "*t", "*u", "*f", "*x", "*q", "*w", 
X"*G", "*D", "*H", "*L", "*C", "*P", "*S", "*T", 
X"*U", "*F", "*Q", "*W", "sr", "ts", "rn", ">=", 
X"<=", "==", "mi", "~=", "ap", "!=", "->", "<-", 
X"ua", "da", "eq", "mu", "di", "+-", "cu", "ca", 
X"sb", "sp", "ib", "ip", "if", "pd", "gr", "no", 
X"is", "pt", "es", "mo", "pl", "rg", "co", "br", 
X"ct", "dd", "rh", "lh", "**", "bs", "or", "ci", 
X"lt", "lb", "rt", "rb", "lk", "rk", "bv", "lf", 
X"rf", "lc", "rc",
X(char *)NULL
X };
X
Xvoid newstrings(sp)
Xstrtab *sp;
X{
X    sp->c_end = sp->c_data;
X}
X
Xchar *addstring(string, pp)
Xstrtab	*pp;
Xchar	*string;
X{
X    pp->c_pointer[pp->n_strings] = pp->c_end;
X    pp->c_end += (pp->c_length[pp->n_strings] = strlen(string)) + 1;
X    if (pp->c_end >= pp->c_data + C_SIZE)
X    {
X	(void) fprintf(stderr, "Table size too small, increase it!\n");
X	exit(1);
X    }
X    return(strcpy(pp->c_pointer[pp->n_strings++], string));
X}
X
Xint char_comp(str1, str2, len)
Xchar	*str1, *str2;
Xint	len;
X{
X    while (len--)
X	if (*str1++ != *str2++)
X	    return(1);
X    return(0);
X}
X
Xint findstring(string, pp)
Xstrtab	*pp;
Xchar	*string;
X{
X    int	c_len, s_len, i;
X
X    for (i = 0; i < pp->n_strings; i++)
X    {
X	if ((c_len = pp->c_length[i]) >= (s_len = strlen(string))) {
X	    if (!char_comp (string, pp->c_pointer[i] + c_len - s_len, s_len))
X		return (pp->c_pointer[i] + c_len - s_len - pp->c_data);
X	}
X    }
X    (void) fprintf(stderr, "Serious bug! string not found in table\n");
X    exit(1);
X    /* NOTREACHED */
X}
X
X/* termtab.c ends here */
END_OF_FILE
if test 2812 -ne `wc -c <'termtab.c'`; then
    echo shar: \"'termtab.c'\" unpacked with wrong size!
fi
# end of 'termtab.c'
fi
if test -f 'termtab.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'termtab.h'\"
else
echo shar: Extracting \"'termtab.h'\" \(2551 characters\)
sed "s/^X//" >'termtab.h' <<'END_OF_FILE'
X/* termtab.h -- declaration of nroff terminal driver internal representation */
X
X/* you'll probably never need to change these */
X#define CHARMIN	32			/* minimum ASCII char nroff uses */
X#define CHARMAX	256			/* size of ASCII character set */
X
X#define C_SIZE	10000	/* The maximum amount of character data allowed
X			   in the initialized structure t - increase if
X			   necessary */
X
Xtypedef struct    /* string table internals */
X{
X    char	c_data[C_SIZE];
X    char	*c_pointer[CHARMAX - CHARMIN];
X    int		c_length[CHARMAX - CHARMIN];
X    char	*c_end;
X    int		n_strings, c_size;
X}
Xstrtab;
X
Xtypedef struct
X{
X    char *name;
X    int bset;
X    int breset;
X    int Hor;
X    int Vert;
X    int Newline;
X    int Char;
X#ifdef KANJI
X    int Kchar;
X#endif KANJI
X    int Em;
X    int Halfline;
X    int Adj;
X    char *twinit;
X    char *twrest;
X    char *twnl;
X    char *hlr;
X    char *hlf;
X    char *flr;
X    char *bdon;
X    char *bdoff;
X    char *iton;
X    char *itoff;
X    char *ploton;
X    char *plotoff;
X    char *up;
X    char *down;
X    char *right;
X    char *left;
X    char *codetab[CHARMAX - CHARMIN];
X    char *zzz;
X
X    strtab	pool;
X}
Xnrtab_t;
X
X/*
X * The format of an old-style tab file is:
X *
X * Type	Name		Size on most machines	Description
X * ----	----		---------------------	-----------
X * int	c_size		4 bytes	- The amount of character data in bytes
X *				that follows the t_stor structure.
X *
X * nrext_t oldform	1000 bytes - This is the storage for the "t"
X *			structure with one change. All the elements
X *			of the t structure which were pointers to
X *			strings are now integer indexes to one
X *			large character array.
X *
X * char	array[c_size]	(variable size)- This is the storage for the strings
X *			pointed to by the indexes.
X *
X * The total size of the tabfile in bytes should be:
X *	c_size + sizeof (c_size) + sizeof (t_stor)
X */
X
Xtypedef struct		/* This structure will be stored in the tab file */
X{
X    int bset;
X    int breset;
X    int Hor;
X    int Vert;
X    int Newline;
X    int Char;
X    int Em;
X    int Halfline;
X    int Adj;
X    int twinit;
X    int twrest;
X    int twnl;
X    int hlr;
X    int hlf;
X    int flr;
X    int bdon;
X    int bdoff;
X    int iton;
X    int itoff;
X    int ploton;
X    int plotoff;
X    int up;
X    int down;
X    int right;
X    int left;
X    int codetab[CHARMAX - CHARMIN];
X    int zzz;
X}
Xnrext_t;
X
Xextern char *ntnames[];
Xextern void newstrings();
Xextern char *addstring();
Xextern int char_comp(), findstring();
Xextern nrtab_t *ditread(), *otread();
Xextern void ditwrite(), otwrite();
X
X/* termtab.h ends here */
END_OF_FILE
if test 2551 -ne `wc -c <'termtab.h'`; then
    echo shar: \"'termtab.h'\" unpacked with wrong size!
fi
# end of 'termtab.h'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
-- 
Wolf N. Paul * 3387 Sam Rayburn Run * Carrollton TX 75007 * (214) 306-9101
UUCP:   killer!wnp                    ESL: 62832882
DOMAIN: wnp@killer.dallas.tx.us       TLX: 910-380-0585 EES PLANO UD