davidsen@crdos1.UUCP (Wm E. Davidsen) (05/03/88)
comp.sources.misc: Volume 3, Issue 11 Submitted-By: "Wm E. Davidsen" <davidsen@crdos1.UUCP> Archive-Name: indexmac There was a request for a way to generate an index using ?roff. Here is the code. At the beginning of the roff input place an .so index.mac to include the index macro. At each place in the text where you want an index entry, place a line of the form .IX "subject" When running ?roff, save the error output in a file: # create the file with the index data nroff -mm -Tljc.12 myfile.n >/dev/null 2>myfile.idx # sort the data and create the complete document sort myfile.idx | indexfmt | cat myfile.n - | nroff -man -Tljc.12 > myfile.prn You will have to use tbl, eqn, etc as needed. If you can use a standard format for the index, you can run it off as a separate document. I actually do something else with named pipes, bit it's not portable. You will probably want to hack this a little, but it does work as is. BUGS: if you mess up your input or command options the error messages are sent to the index file. The index should be created from a known good input. #!/bin/sh # shar: Shell Archiver (v1.20) # # Run the following text with /bin/sh to create: # index.mac # indexfmt.c # echo "x - extracting index.mac (Text)" sed 's/^X//' << 'SHAR_EOF' > index.mac && X.de IX X.tm \\$1;\\nP X.. SHAR_EOF chmod 0644 index.mac || echo "restore of index.mac fails" echo "x - extracting indexfmt.c (Text)" sed 's/^X//' << 'SHAR_EOF' > indexfmt.c && X/* X * ixformat - format an index file for output X * X * Bill Davidsen, June 1986 X * X * This program is a filter which accepts the list of subjects X * for an index, and the page on which they occur. It then emits X * output in xroff format with all refs to a single subject on X * one line. X */ X X#include <stdio.h> X#define MAXLINE 80 /* longest subject */ X#define MAXREFS 10 /* refs to any one subject */ X Xchar current[MAXLINE]; /* current subject */ Xint refs[MAXREFS]; /* current refs */ Xint nref = 0; /* # of refs to current subj */ X Xmain () X{ X char line[MAXLINE]; /* next subject */ X int page; /* page of current ref */ X X while (scanf ("%[^;];%d", line, &page) == 2) X { /* see if this is a new subject */ X while (getchar () != '\n'); /* skip to EOL */ X X if (nref == 0) X { /* this is the first one in */ X strcpy (current, line); X refs[nref++] = page; X /* get the proper footer on it */ X printf (".PH \"\"\n.PF \"//- index %% -//\"\n.nf\n"); X continue; X } X X if (strcmp (line, current)) X { /* starting a new subject, output this one */ X flushref (0); X X /* copy the new subject and page in */ X strcpy (current, line); X refs[0] = page; X nref = 1; X } X else X { /* add a reference to this subject */ X if (nref == MAXREFS) X flushref (1); X refs[nref++] = page; X } X } X X /* if there are references left, flush them */ X if (nref) X flushref (0); X exit (0); X} X XX/* X * flushref - output a subject and all current references to it. X */ X Xflushref (flag) X int flag; X{ X int ix; /* loop index */ X X printf ("%s ", current); X for (ix = 0; ix < nref;) X { /* output a reference, and comma if more */ X printf ("%d", refs[ix++]); X if (ix < nref) X putchar (','); X } X if (flag) X putchar (','); X putchar ('\n'); X} SHAR_EOF chmod 0644 indexfmt.c || echo "restore of indexfmt.c fails" exit 0 bill davidsen (wedu@ge-crd.ARPA -or- davidsen@crdos1.uucp) {uunet | philabs}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me