[net.sources] ntfile

ian (04/20/83)

Here's the problem:
	From utcsrgv!ken (Ken Newman)

	I offer the following as a useful challenge for a nroff/troff
	utility that I think would be a worthwhile hack. Would it be
	possible to have a program to read in nroff or troff input and
	tell you what options to use when nroff/troffing it? E.g. it
	could tell you whether to use ms or me, whether you need tbl,
	col, eqn, etc and in what order to do this? People who don't
	use these programs a whole lot (like me) get a bit lost when
	they receive text for input to a formatter (like over the net)
	and there are no instructions for formatting it. Also these
	programs are very expensive to experiment with to get the right
	options. If you can whip something up, please post to
	net.sources. Thnx in advnx.

Here's one solution. Delete from the beginning of this file to
the signature block, sh(1) the remainder, and type
	make -f makefile.ntfile
(more simply: do this in a clean directory and mv makefile.ntfile to makefile,
then just type make).
Then you can run the program by typing
	ntfile <nrofftextfile
I hope somebody finds it useful. It's really a rather simple exercise
in the use of lex(1).

Ian F. Darwin,
Toronto, Ontario, Canada
...decvax!utzoo!utcsrgv!utcsstat!ian

: here beginneth the shell file to put ntfile in your directory
echo ntfile.1
cat>ntfile.1<<{EOF}
.TH NTFILE 1 83-04-18
.SH NAME
ntfile - intuit nroff/troff preprocessor(s) and macro package.
.SH SYNOPSIS
ntfile < fileoftext
.br
<process>|ntfile
.br
The output is an approximate shell command to process the file.
.SH DESCRIPTION
.B ntfile
is my version of the program to intuit which n/troff preprocessor
and macro package is needed for a given n/troff file. It knows a little
about refer, tbl and eqn, and the man, me, mm and ms macro packages.
It does not know about col, since that is a post-processor for
specific output devices.
.SH BUGS
It does not intuit the register flags needed to make the macro
packages behave exactly as intended; this is non-deterministic.
.PP
It does not know what to do if elements of multiple macro packages
appear to exist in the file.
.PP
It does not track the control character; if you change this with '.cc'
then you get a warning (but maybe no useful output).
.PP
It does not follow '.so' chains; this would be a useful addition.
You do get a warning.
.PP
It does not know about PIC and IDEAL constructs.
{EOF}
echo makefile.ntfile
cat>makefile.ntfile<<{EOF}
ntfile: ntfile.l
	lex ntfile.l
	cc  lex.yy.c -ll -o ntfile
{EOF}
echo ntfile.l
cat>ntfile.l<<{EOF}
	/* ntfile - nroff/troff 'file' type */
	/* method: for each *unique* construct, increment the */
	/* variable corresponding to the name of the macro    */
	/* package or preprocessor. At the end, use these     */
	/* variables to infer the corresponding command line  */

	int	cc={0},eqn={0},
		man={0},me={0},mm={0},ms={0},
		refer={0},so={0},tbl={0};

D	"."
%%
^{D}"["		refer++;
^{D}cc		cc++;
^{D}E[NQ]	eqn++;
^{D}H[ U]	mm++;
^{D}ip		me++;
^{D}lp		me++;
^{D}LP		ms++;
^{D}MH		ms++;
^{D}NH		ms++;
^{D}P$		mm++;
^{D}pp		me++;
^{D}sh		me++;
^{D}SH		ms++;
^{D}so		so++;
^{D}TH		man++;
^{D}tp		me++;
^{D}T[SE]	tbl++;
^{D}uh		me++;
.		/* eat me, no issue */;
\n		/* eat me, no issue */;
%%
yywrap(){
/* Here we infer the command line needed to process the input file.  */
/* If constructs from multiple macro packages are used, this program */
/* will (erroneously) put out multiple '-m...' arguments. A better   */
/* method might be to choose the 'most likely' based on the increment*/
/* values; this would need considerably more care in the choice of   */
/* the constructs to be looked for by the lex portion of the program.*/

if (cc) fprintf(stderr,"ntfile: caution cc has been changed\n");
if (so) fprintf(stderr,"ntfile: caution .so file(s) not processed.\n");
if(refer) printf("refer | ");
if(tbl) printf("tbl | ");
if(eqn) printf("eqn | ");
printf("nroff");
if (man) printf(" -man");
if (me) printf(" -me");
if (mm) printf(" -mm");
if (ms) printf(" -ms");
putchar('\n');
/* debug();			/* comment out if not wanted */
return(1);
}
debug(){
printf("debug: cc=%d eqn=%d man=%d me=%d mm=%d ms=%d refer=%d so=%d tbl=%d\n",
		cc,  eqn,   man,   me,   mm,   ms,   refer,   so,   tbl);
}
{EOF}