xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 15890)
113110Srrh #ifndef lint
2*15890Srrh static char sccsid[] = "@(#)bibargs.c	2.3	01/24/84";
313110Srrh #endif not lint
415061Sgarrison /*
515061Sgarrison         Authored by: Tim Budd, University of Arizona, 1983.
615061Sgarrison                 version 7/4/83
713110Srrh 
815061Sgarrison         Various modifications suggested by:
915061Sgarrison                 David Cherveny - Duke University Medical Center
1015061Sgarrison                 Phil Garrison - UC Berkeley
1115061Sgarrison                 M. J. Hawley - Yale University
1215061Sgarrison 
1315061Sgarrison 
1415061Sgarrison 
1515061Sgarrison 
1612910Sgarrison         read argument strings for bib and listrefs
1712910Sgarrison         do name formatting, printing lines, other actions common to both
1812910Sgarrison                                                         */
1912910Sgarrison # include <stdio.h>
2012910Sgarrison # include <ctype.h>
2112910Sgarrison # include "bib.h"
2212910Sgarrison # define LINELENGTH 1024
2312910Sgarrison # define MAXDEFS     500             /* maximum number of defined words */
2412910Sgarrison 
2512910Sgarrison /* global variables */
2615061Sgarrison    char bibfname[120];          /* file name currently being read            */
2715061Sgarrison    int  biblineno;              /* line number currently being referenced    */
2812910Sgarrison    int  abbrev       = false;   /* automatically abbreviate names            */
2912910Sgarrison    int  capsmcap     = false;   /* print names in caps small caps (CACM form)*/
3012910Sgarrison    int  numrev       = 0;       /* number of authors names to reverse        */
3112910Sgarrison    int  edabbrev     = false;   /* abbreviate editors names ?                */
3212910Sgarrison    int  edcapsmcap   = false;   /* print editors in cap small caps           */
3312910Sgarrison    int  ednumrev     = 0;       /* number of editors to reverse              */
3412910Sgarrison    int  sort         = false;   /* sort references ? (default no)            */
3512910Sgarrison    int  foot         = false;   /* footnoted references ? (default endnotes) */
3612910Sgarrison    int  hyphen       = false;   /* hypenate contiguous references            */
3712910Sgarrison    int  ordcite      = true;    /* order multiple citations                  */
3812910Sgarrison    char sortstr[80]  = "1";     /* sorting template                          */
3912910Sgarrison    char trailstr[80] = "";      /* trailing characters to output             */
4012910Sgarrison    char pfile[120];             /* private file name                         */
4112910Sgarrison    int  personal = false;       /* personal file given ? (default no)        */
4212910Sgarrison    char citetemplate[80] = "1"; /* citation template                         */
4312910Sgarrison    char *words[MAXDEFS];        /* defined words                             */
4412910Sgarrison    char *defs[MAXDEFS];         /* defined word definitions                  */
4512910Sgarrison    int  wordtop = -1;           /* top of defined words array                */
4612910Sgarrison 
4712910Sgarrison /* where output goes */
4812910Sgarrison    extern FILE *tfd;
4915061Sgarrison /* reference file information */
5015061Sgarrison    extern long int refspos[];
5115061Sgarrison    extern char reffile[];
5215061Sgarrison    extern FILE *rfd;
5315061Sgarrison    extern char *citestr[];
5415061Sgarrison    extern int numrefs;
5512910Sgarrison 
5612910Sgarrison /* doargs - read command argument line for both bib and listrefs
5712910Sgarrison             set switch values
5812910Sgarrison             call rdtext on file arguments, after dumping
5912910Sgarrison             default style file if no alternative style is given
6012910Sgarrison */
6112910Sgarrison    int doargs(argc, argv, defstyle)
6212910Sgarrison    int argc;
6312910Sgarrison    char **argv, defstyle[];
6412910Sgarrison {  int numfiles, i, style;
6512910Sgarrison    char *p, *q, *walloc();
6612910Sgarrison    FILE *fd;
6712910Sgarrison 
6812910Sgarrison    numfiles = 0;
6912910Sgarrison    style = true;
7012910Sgarrison    words[0] = walloc("BMACLIB");
7112910Sgarrison    defs[0]  = walloc(BMACLIB);
7212910Sgarrison    wordtop++;
7312910Sgarrison    fputs(".ds l] ",tfd);
7412910Sgarrison    fputs(BMACLIB, tfd);
7512910Sgarrison    fputs("\n", tfd);
7612910Sgarrison 
7712910Sgarrison    for (i = 1; i < argc; i++)
7812910Sgarrison       if (argv[i][0] == '-')
7912910Sgarrison          switch(argv[i][1]) {
8012910Sgarrison 
8115061Sgarrison             case 'a':  for (p = &argv[i][2]; *p; p++)
8215061Sgarrison                           if (*p == 'a' || *p == 0)
8312961Sgarrison                              abbrev = true;
8412961Sgarrison                            else if (*p == 'x')
8512961Sgarrison                              capsmcap = true;
8612961Sgarrison                            else if (*p == 'r') {
8712961Sgarrison                              if (*(p+1))
8812961Sgarrison                                 numrev = atoi(p+1);
8912961Sgarrison                               else
9012961Sgarrison                                 numrev = 1000;
9112961Sgarrison                               break;
9212961Sgarrison                               }
9312910Sgarrison                        break;
9412910Sgarrison 
9512910Sgarrison             case 'c':  if (argv[i][2] == 0)
9612910Sgarrison                           error("citation string expected");
9712910Sgarrison                        else
9812910Sgarrison                           for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
9912910Sgarrison                        break;
10012910Sgarrison 
10112910Sgarrison             case 'e':  for (p = &argv[i][2]; *p; p++)
10212910Sgarrison                           if (*p == 'a')
10312910Sgarrison                              edabbrev = true;
10412910Sgarrison                            else if (*p == 'x')
10512910Sgarrison                              edcapsmcap = true;
10612910Sgarrison                            else if (*p == 'r') {
10712910Sgarrison                              if (*(p+1))
10812910Sgarrison                                 ednumrev = atoi(p+1);
10912910Sgarrison                               else
11012910Sgarrison                                 ednumrev = 1000;
11112910Sgarrison                               break;
11212910Sgarrison                               }
11312910Sgarrison                        break;
11412910Sgarrison 
11512910Sgarrison             case 'f':  foot = true;
11612910Sgarrison                        hyphen = false;
11712910Sgarrison                        break;
11812910Sgarrison 
11912910Sgarrison             case 'h':  hyphen = ordcite = true;
12012910Sgarrison                        break;
12112910Sgarrison 
12212910Sgarrison             case 'n':  for (p = &argv[i][2]; *p; p++)
12312910Sgarrison                           if (*p == 'a')
12412910Sgarrison                              abbrev = false;
12512910Sgarrison                           else if (*p == 'f')
12612910Sgarrison                              foot = false;
12712910Sgarrison                           else if (*p == 'h')
12812910Sgarrison                              hyphen = false;
12912910Sgarrison                           else if (*p == 'o')
13012910Sgarrison                              ordcite = false;
13112910Sgarrison                           else if (*p == 'r')
13212910Sgarrison                              numrev = 0;
13312910Sgarrison                           else if (*p == 's')
13412910Sgarrison                              sort = false;
13512910Sgarrison                           else if (*p == 'x')
13612910Sgarrison                              capsmcap = false;
13712910Sgarrison                        break;
13812910Sgarrison 
13912910Sgarrison             case 'o':  ordcite = true;
14012910Sgarrison                        break;
14112910Sgarrison 
14212910Sgarrison             case 'p':  if (argv[i][2])
14312910Sgarrison                           p = &argv[i][2];
14412910Sgarrison                        else {  /* take next arg */
14512910Sgarrison                           i++;
14612910Sgarrison                           p = argv[i];
14712910Sgarrison                           }
14812910Sgarrison                        strcpy(pfile, p);
14912910Sgarrison                        personal = true;
15012910Sgarrison                        break;
15112910Sgarrison 
15215061Sgarrison             case 'r':  if (argv[i][2] == 0)  /* this is now replaced by -ar */
15312910Sgarrison                           numrev = 1000;
15412910Sgarrison                        else
15512910Sgarrison                           numrev = atoi(&argv[i][2]);
15612910Sgarrison                        break;
15712910Sgarrison 
15812910Sgarrison             case 's':  sort = true;
15912910Sgarrison                        if (argv[i][2])
16012910Sgarrison                           for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
16112910Sgarrison                        break;
16212910Sgarrison 
16315061Sgarrison             case 't':  style = false;           /* fall through */
16415061Sgarrison             case 'i':  if (argv[i][2])
16512910Sgarrison                           p = &argv[i][2];
16612910Sgarrison                        else { /* take next arg */
16712910Sgarrison                           i++;
16812910Sgarrison                           p = argv[i];
16912910Sgarrison                           }
17012910Sgarrison                        incfile(p);
17112910Sgarrison                        break;
17212910Sgarrison 
17315061Sgarrison             case 'x':  capsmcap = true; /* this is now replaced by -ax */
17412910Sgarrison                        break;
17512910Sgarrison 
17612910Sgarrison             case 0:    if (style) {  /* no style command given, take default */
17712910Sgarrison                           style = false;
17812910Sgarrison                           incfile( defstyle );
17912910Sgarrison                           }
18015061Sgarrison                        strcpy(bibfname,"<stdin>");
18112910Sgarrison                        rdtext(stdin);
18212910Sgarrison                        numfiles++;
18312910Sgarrison                        break;
18412910Sgarrison 
18512910Sgarrison             default:   fputs(argv[i], stderr);
18612910Sgarrison                        error(": invalid switch");
18712910Sgarrison             }
18812910Sgarrison       else { /* file name */
18912910Sgarrison          numfiles++;
19012910Sgarrison          if (style) {
19112910Sgarrison             style = false;
19212910Sgarrison             incfile( defstyle );
19312910Sgarrison             }
19412910Sgarrison          fd = fopen(argv[i], "r");
19512910Sgarrison          if (fd == NULL) {
19612910Sgarrison             fputs(argv[i], stderr);
19712910Sgarrison             error(": can't open");
19812910Sgarrison             }
19912910Sgarrison          else {
20015061Sgarrison             strcpy(bibfname, argv[i]);
20112910Sgarrison             rdtext(fd);
20212910Sgarrison             fclose(fd);
20312910Sgarrison             }
20412910Sgarrison          }
20512910Sgarrison 
20612910Sgarrison    if (style) incfile( defstyle );
20712910Sgarrison    return(numfiles);
20812910Sgarrison 
20912910Sgarrison }
21012910Sgarrison 
21112910Sgarrison /* incfile - read in an included file  */
21212910Sgarrison incfile(np)
21312910Sgarrison    char *np;
21412910Sgarrison {  char name[120];
21512910Sgarrison    FILE *fd;
21615061Sgarrison    char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
21715061Sgarrison    int  i, j, getwrd();
21812910Sgarrison 
21915061Sgarrison    strcpy(bibfname, np);
22012910Sgarrison    fd = fopen(np, "r");
22112910Sgarrison    if (fd == NULL && *np != '/') {
22212910Sgarrison       strcpy(name, "bib.");
22312910Sgarrison       strcat(name, np);
22415061Sgarrison       strcpy(bibfname, name);
22512910Sgarrison       fd = fopen(name, "r");
22612910Sgarrison       }
22712910Sgarrison    if (fd == NULL && *np != '/') {
22812910Sgarrison       strcpy(name,BMACLIB);
22912910Sgarrison       strcat(name, "/bib.");
23012910Sgarrison       strcat(name, np);
23115061Sgarrison       strcpy(bibfname, name);
23212910Sgarrison       fd = fopen(name, "r");
23312910Sgarrison       }
23412910Sgarrison    if (fd == NULL) {
23515061Sgarrison       bibwarning("%s: can't open", np);
23615061Sgarrison       exit(1);
23712910Sgarrison       }
23812910Sgarrison 
23915061Sgarrison    /* now go off and process file */
24015061Sgarrison    biblineno = 1;
24115061Sgarrison    while (tfgets(line, LINELENGTH, fd) != NULL) {
24215061Sgarrison       biblineno++;
24312910Sgarrison       switch(line[0]) {
24412910Sgarrison 
24512910Sgarrison          case '#': break;
24612910Sgarrison 
24712961Sgarrison          case 'A': for (p = &line[1]; *p; p++)
24815061Sgarrison                       if (*p == 'A' || *p == '\0')
24912961Sgarrison                          abbrev = true;
25012961Sgarrison                       else if (*p == 'X')
25112961Sgarrison                          capsmcap = true;
25212961Sgarrison                       else if (*p == 'R') {
25312961Sgarrison                          if (*(p+1))
25412961Sgarrison                             numrev = atoi(p+1);
25512961Sgarrison                          else
25612961Sgarrison                             numrev = 1000;
25712961Sgarrison                          break;
25812961Sgarrison                          }
25912910Sgarrison                    break;
26012910Sgarrison 
26112910Sgarrison          case 'C': for (p = &line[1]; *p == ' '; p++) ;
26212910Sgarrison                    strcpy(citetemplate, p);
26312910Sgarrison                    break;
26412910Sgarrison 
26512910Sgarrison          case 'D': if ((i = getwrd(line, 1, word)) == 0)
26612910Sgarrison                       error("word expected in definition");
26712910Sgarrison                    for (j = 0; j <= wordtop; j++)
26812910Sgarrison                       if (strcmp(word, words[j]) == 0)
26912910Sgarrison                          break;
27012910Sgarrison                    if (j > wordtop) {
27112910Sgarrison                       if ((j = ++wordtop) > MAXDEFS)
27212910Sgarrison                          error("too many defintions");
27312910Sgarrison                       words[wordtop] = walloc(word);
27412910Sgarrison                       }
27512910Sgarrison                    for (p = &line[i]; *p == ' '; p++) ;
27612910Sgarrison                    for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
27712910Sgarrison                        dline[strlen(dline)-1] = '\n';
27815061Sgarrison                        if (tfgets(line, LINELENGTH, fd) == NULL) break;
27912910Sgarrison                        strcat(dline, line);
28012910Sgarrison                        }
28112910Sgarrison                    defs[j] = walloc(dline);
28212910Sgarrison                    break;
28312910Sgarrison 
28412910Sgarrison          case 'E': for (p = &line[1]; *p; p++)
28512910Sgarrison                       if (*p == 'A')
28612910Sgarrison                          edabbrev = true;
28712910Sgarrison                       else if (*p == 'X')
28812910Sgarrison                          edcapsmcap = true;
28912910Sgarrison                       else if (*p == 'R') {
29012910Sgarrison                          if (*(p+1))
29112910Sgarrison                             ednumrev = atoi(p+1);
29212910Sgarrison                          else
29312910Sgarrison                             ednumrev = 1000;
29412910Sgarrison                          break;
29512910Sgarrison                          }
29612910Sgarrison                    break;
29712910Sgarrison 
29812910Sgarrison          case 'F': foot = true;
29912910Sgarrison                    hyphen = false;
30012910Sgarrison                    break;
30112910Sgarrison 
30212910Sgarrison          case 'I': for (p = &line[1]; *p == ' '; p++);
30312910Sgarrison                    expand(p);
30412910Sgarrison                    incfile(p);
30512910Sgarrison                    break;
30612910Sgarrison 
30712910Sgarrison          case 'H': hyphen = ordcite = true;
30812910Sgarrison                    break;
30912910Sgarrison 
31012910Sgarrison          case 'O': ordcite = true;
31112910Sgarrison                    break;
31212910Sgarrison 
31315061Sgarrison          case 'R': if (line[1] == 0)  /* this is now replaced by AR */
31412910Sgarrison                       numrev = 1000;
31512910Sgarrison                    else
31612910Sgarrison                       numrev = atoi(&line[1]);
31712910Sgarrison                    break;
31812910Sgarrison 
31912910Sgarrison          case 'S': sort = true;
32012910Sgarrison                    for (p = &line[1]; *p == ' '; p++) ;
32112910Sgarrison                    strcpy(sortstr, p);
32212910Sgarrison                    break;
32312910Sgarrison 
32412910Sgarrison          case 'T': for (p = &line[1]; *p == ' '; p++) ;
32512910Sgarrison                    strcpy(trailstr, p);
32612910Sgarrison                    break;
32712910Sgarrison 
32815061Sgarrison          case 'X': capsmcap = true;     /* this is now replace by AX */
32912910Sgarrison                    break;
33012910Sgarrison 
33112910Sgarrison          default:  fprintf(tfd,"%s\n",line);
33215061Sgarrison                    while (fgets(line, LINELENGTH, fd) != NULL)
33312910Sgarrison                       fputs(line, tfd);
33412910Sgarrison                    return;
33512910Sgarrison          }
33615061Sgarrison 
33715061Sgarrison    }
33815061Sgarrison    /* close up */
33915061Sgarrison    fclose(fd);
34012910Sgarrison }
34112910Sgarrison 
34215061Sgarrison /* bibwarning - print out a warning message */
34315061Sgarrison   bibwarning(msg, arg)
34415061Sgarrison   char *msg, *arg;
34515061Sgarrison {
34615061Sgarrison   fprintf(stderr,"`%s', line %d: ", bibfname, biblineno);
34715061Sgarrison   fprintf(stderr, msg, arg);
34815061Sgarrison }
34915061Sgarrison 
35015061Sgarrison /* error - report unrecoverable error message */
35115061Sgarrison   error(str)
35215061Sgarrison   char str[];
35315061Sgarrison {
35415061Sgarrison   bibwarning("%s\n", str);
35515061Sgarrison   exit(1);
35615061Sgarrison }
35715061Sgarrison 
35815061Sgarrison #ifdef READWRITE
35915061Sgarrison /*
36015061Sgarrison ** fixrfd( mode ) -- re-opens the rfd file to be read or write,
36115061Sgarrison **      depending on the mode.  Uses a static int to save the current mode
36215061Sgarrison **      and avoid unnecessary re-openings.
36315061Sgarrison */
36415061Sgarrison fixrfd( mode )
36515061Sgarrison register int mode;
36615061Sgarrison {
36715061Sgarrison 	static int cur_mode = WRITE;    /* rfd open for writing initially */
36815061Sgarrison 
36915061Sgarrison 	if (mode != cur_mode)
37015061Sgarrison 	{
37115061Sgarrison 		rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
37215061Sgarrison 		cur_mode = mode;
37315061Sgarrison 		if (rfd == NULL)
37415061Sgarrison 		      error("Hell!  Couldn't re-open reference file");
37515061Sgarrison 	}
37615061Sgarrison }
37715061Sgarrison #endif
37815061Sgarrison 
37915061Sgarrison 
38015061Sgarrison /* tfgets - fgets which trims off newline */
38115061Sgarrison    char *tfgets(line, n, ptr)
38215061Sgarrison    char line[];
38315061Sgarrison    int  n;
38415061Sgarrison    FILE *ptr;
38515061Sgarrison {  char *p;
38615061Sgarrison 
38715061Sgarrison    p = fgets(line, n, ptr);
38815061Sgarrison    if (p == NULL)
38915061Sgarrison       return(NULL);
39015061Sgarrison    else
39115061Sgarrison       for (p = line; *p; p++)
39215061Sgarrison          if (*p == '\n')
39315061Sgarrison             *p = 0;
39415061Sgarrison    return(line);
39515061Sgarrison }
39615061Sgarrison 
39715061Sgarrison /* getwrd - place next word from in[i] into out */
39815061Sgarrison int getwrd(in, i, out)
39915061Sgarrison    char in[], out[];
40015061Sgarrison    int i;
40115061Sgarrison {  int j;
40215061Sgarrison 
40315061Sgarrison    j = 0;
40415061Sgarrison    while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
40515061Sgarrison       i++;
40615061Sgarrison    if (in[i])
40715061Sgarrison       while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
40815061Sgarrison          out[j++] = in[i++];
40915061Sgarrison    else
41015061Sgarrison       i = 0;    /* signals end of in[i..]   */
41115061Sgarrison    out[j] = 0;
41215061Sgarrison    return (i);
41315061Sgarrison }
41415061Sgarrison 
41515061Sgarrison /* walloc - allocate enough space for a word */
41615061Sgarrison char *walloc(word)
41715061Sgarrison    char *word;
41815061Sgarrison {  char *i, *malloc();
41915061Sgarrison    i = malloc(1 + strlen(word));
42015061Sgarrison    if (i == NULL)
42115061Sgarrison       error("out of storage");
42215061Sgarrison    strcpy(i, word);
42315061Sgarrison    return(i);
42415061Sgarrison }
42515061Sgarrison 
42612910Sgarrison /* isword - see if character is legit word char */
42712910Sgarrison int iswordc(c)
42812910Sgarrison char c;
42912910Sgarrison {
43012910Sgarrison    if (isalnum(c) || c == '&' || c == '_')
43112910Sgarrison       return(true);
43212910Sgarrison    return(false);
43312910Sgarrison }
43412910Sgarrison 
43512910Sgarrison /* expand - expand reference, replacing defined words */
43612910Sgarrison    expand(line)
43712910Sgarrison    char *line;
43812910Sgarrison {  char line2[REFSIZE], word[LINELENGTH], *p, *q, *w;
43912910Sgarrison    int  replaced, i;
44012910Sgarrison 
44112910Sgarrison    replaced  = true;
44212910Sgarrison    while (replaced) {
44312910Sgarrison       replaced = false;
44412910Sgarrison       p = line;
44512910Sgarrison       q = line2;
44612910Sgarrison       while (*p) {
44712910Sgarrison          if (isalnum(*p)) {
44812910Sgarrison             for (w = word; *p && iswordc(*p); )
44912910Sgarrison                *w++ = *p++;
45012910Sgarrison             *w = 0;
45112910Sgarrison             for (i = 0; i <= wordtop; i++)
45212910Sgarrison                if (strcmp(word, words[i]) == 0) {
45312910Sgarrison                   strcpy(word, defs[i]);
45412910Sgarrison                   replaced = true;
45512910Sgarrison                   break;
45612910Sgarrison                   }
45712910Sgarrison             for (w = word; *w; )
45812910Sgarrison                *q++ = *w++;
45912910Sgarrison             }
46012910Sgarrison          else
46112910Sgarrison             *q++ = *p++;
46212910Sgarrison          }
46312910Sgarrison       *q = 0;
46412910Sgarrison       p = line;
46512910Sgarrison       q = line2;
46612910Sgarrison       while (*p++ = *q++);
46712910Sgarrison       }
46812910Sgarrison }
46912910Sgarrison 
47015061Sgarrison /* rdref - read text for an already cited reference */
47115061Sgarrison    rdref(i, ref)
47215061Sgarrison    long int  i;
47315061Sgarrison    char ref[REFSIZE];
47415061Sgarrison {
47515061Sgarrison    ref[0] = 0;
47615061Sgarrison #ifdef READWRITE
47715061Sgarrison    fixrfd( READ );                      /* fix access mode of rfd, if nec. */
47815061Sgarrison #endif
47915061Sgarrison    fseek(rfd, i, 0);
48015061Sgarrison    fread(ref, 1, REFSIZE, rfd);
48115061Sgarrison }
48215061Sgarrison 
48312910Sgarrison /* breakname - break a name into first and last name */
48412910Sgarrison    breakname(line, first, last)
48512910Sgarrison    char line[], first[], last[];
48612910Sgarrison {  char *p, *q, *r, *t, *f;
48712910Sgarrison 
48812910Sgarrison    for (t = line; *t != '\n'; t++);
48912910Sgarrison    for (t--; isspace(*t); t--);
49012910Sgarrison 
49112910Sgarrison    /* now strip off last name */
49212910Sgarrison    for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
49312910Sgarrison       if (q == line)
49412910Sgarrison          break;
49512910Sgarrison    f = q;
49615061Sgarrison    if (q != line) {
49712910Sgarrison       q++;
49815061Sgarrison       for (; isspace(*f); f--);
49915061Sgarrison       f++;
50015061Sgarrison       }
50112910Sgarrison 
50212910Sgarrison    /* first name is start to f, last name is q to t */
50312910Sgarrison 
50415061Sgarrison    for (r = first, p = line; p != f; )
50512910Sgarrison       *r++ = *p++;
50612910Sgarrison    *r = 0;
50712910Sgarrison    for (r = last, p = q, t++; q != t; )
50812910Sgarrison       *r++ = *q++;
50912910Sgarrison    *r = 0;
51015061Sgarrison 
51112910Sgarrison }
51212910Sgarrison 
51312910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
51412910Sgarrison    int match(str1, str2)
51512910Sgarrison    char str1[], str2[];
51612910Sgarrison {  int  i, j;
51712910Sgarrison    char a, b;
51812910Sgarrison 
51912910Sgarrison    for (i = 0; str2[i]; i++) {
52012910Sgarrison       for (j = 0; str1[j]; j++) {
52112910Sgarrison          if (isupper(a = str2[i+j]))
52212910Sgarrison             a = (a - 'A') + 'a';
52312910Sgarrison          if (isupper(b = str1[j]))
52412910Sgarrison             b = (b - 'A') + 'a';
52512910Sgarrison          if (a != b)
52612910Sgarrison             break;
52712910Sgarrison          }
52812910Sgarrison       if (str1[j] == 0)
52912910Sgarrison          return(true);
53012910Sgarrison       }
53112910Sgarrison    return(false);
53212910Sgarrison }
53312910Sgarrison 
53412910Sgarrison /* scopy - append a copy of one string to another */
53512910Sgarrison    char *scopy(p, q)
53612910Sgarrison    char *p, *q;
53712910Sgarrison {
53812910Sgarrison    while (*p++ = *q++)
53912910Sgarrison       ;
54012910Sgarrison    return(--p);
54112910Sgarrison }
54212910Sgarrison 
54315061Sgarrison /* rcomp - reference comparison routine for qsort utility */
54415061Sgarrison    int rcomp(ap, bp)
54515061Sgarrison    long int *ap, *bp;
54615061Sgarrison {  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
54715061Sgarrison    char *p, *q, *getfield();
54815061Sgarrison    int  neg, res;
54915061Sgarrison    int  fields_found;
55015061Sgarrison 
55115061Sgarrison    rdref(*ap, ref1);
55215061Sgarrison    rdref(*bp, ref2);
55315061Sgarrison    for (p = sortstr; *p; p = q) {
55415061Sgarrison       if (*p == '-') {
55515061Sgarrison          p++;
55615061Sgarrison          neg = true;
55715061Sgarrison          }
55815061Sgarrison       else
55915061Sgarrison          neg = false;
56015061Sgarrison       q = getfield(p, field1, ref1);
56115061Sgarrison       fields_found = true;
56215061Sgarrison       if (q == 0) {
56315061Sgarrison 	 res = 1;
56415061Sgarrison 	 fields_found = false;
56515061Sgarrison       } else if (strcmp (field1, "") == 0) {	/* field not found */
56615061Sgarrison          if (*p == 'A') {
56715061Sgarrison             getfield("F", field1, ref1);
56815061Sgarrison 	    if (strcmp (field1, "") == 0) {
56915061Sgarrison                getfield("I", field1, ref1);
57015061Sgarrison 	       if (strcmp (field1, "") == 0) {
57115061Sgarrison 	          res = 1;
57215061Sgarrison 		  fields_found = false;
57315061Sgarrison 	       }
57415061Sgarrison 	    }
57515061Sgarrison 	 } else {
57615061Sgarrison 	    res = 1;
57715061Sgarrison 	    fields_found = false;
57815061Sgarrison 	 }
57915061Sgarrison       }
58015061Sgarrison 
58115061Sgarrison       if (getfield(p, field2, ref2) == 0) {
58215061Sgarrison 	 res = -1;
58315061Sgarrison 	 fields_found = false;
58415061Sgarrison       } else if (strcmp (field2, "") == 0) {	/* field not found */
58515061Sgarrison          if (*p == 'A') {
58615061Sgarrison             getfield("F", field2, ref2);
58715061Sgarrison 	    if (strcmp (field2, "") == 0) {
58815061Sgarrison                getfield("I", field2, ref2);
58915061Sgarrison 	       if (strcmp (field2, "") == 0) {
59015061Sgarrison 	          res = -1;
59115061Sgarrison 		  fields_found = false;
59215061Sgarrison 	       }
59315061Sgarrison 	    }
59415061Sgarrison 	 } else {
59515061Sgarrison 	    res = -1;
59615061Sgarrison 	    fields_found = false;
59715061Sgarrison 	 }
59815061Sgarrison       }
59915061Sgarrison       if (fields_found) {
60015061Sgarrison          if (*p == 'A') {
60115061Sgarrison             if (isupper(field1[0]))
60215061Sgarrison                field1[0] -= 'A' - 'a';
60315061Sgarrison             if (isupper(field2[0]))
60415061Sgarrison                field2[0] -= 'A' - 'a';
60515061Sgarrison             }
60615061Sgarrison          res = strcmp(field1, field2);
60715061Sgarrison          }
60815061Sgarrison       if (neg)
60915061Sgarrison          res = - res;
61015061Sgarrison       if (res != 0)
61115061Sgarrison          break;
61215061Sgarrison       }
61315061Sgarrison    if (res == 0)
61415061Sgarrison       if (ap < bp)
61515061Sgarrison          res = -1;
61615061Sgarrison       else
61715061Sgarrison          res = 1;
61815061Sgarrison    return(res);
61915061Sgarrison }
62015061Sgarrison 
62115061Sgarrison /* makecites - make citation strings */
62215061Sgarrison    makecites(citestr)
62315061Sgarrison    char *citestr[];
62415061Sgarrison {  char ref[REFSIZE], tempcite[100], *malloc();
62515061Sgarrison    int  i;
62615061Sgarrison 
62715061Sgarrison    for (i = 0; i <= numrefs; i++) {
62815061Sgarrison       rdref(refspos[i], ref);
62915061Sgarrison       bldcite(tempcite, i, ref);
63015061Sgarrison       citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */
63115061Sgarrison       if (citestr[i] == NULL)
63215061Sgarrison          error("out of storage");
63315061Sgarrison       strcpy(citestr[i], tempcite);
63415061Sgarrison       }
63515061Sgarrison }
63615061Sgarrison 
63715061Sgarrison /* bldcite - build a single citation string */
63815061Sgarrison    bldcite(cp, i, ref)
63915061Sgarrison    char *cp, ref[];
64015061Sgarrison    int  i;
641*15890Srrh {  char *p, *q, c, *fp, field[REFSIZE];
642*15890Srrh    char *getfield(), *aabet(), *aabetlast(), *astro();
64315061Sgarrison 
64415061Sgarrison    getfield("F", field, ref);
64515061Sgarrison    if (field[0] != 0)
64615061Sgarrison       for (p = field; *p; p++)
64715061Sgarrison          *cp++ = *p;
64815061Sgarrison    else {
64915061Sgarrison       p = citetemplate;
65015061Sgarrison       field[0] = 0;
65115061Sgarrison       while (c = *p++) {
65215061Sgarrison          if (isalpha(c)) {                      /* field name   */
65315061Sgarrison             q = getfield(p-1, field, ref);
65415061Sgarrison             if (q != 0) {
65515061Sgarrison                p = q;
65615061Sgarrison                for (fp = field; *fp; )
65715061Sgarrison                   *cp++ = *fp++;
65815061Sgarrison                }
65915061Sgarrison             }
66015061Sgarrison          else if (c == '1') {                   /* numeric  order */
66115061Sgarrison             sprintf(field,"%d",1 + i);
66215061Sgarrison             for (fp = field; *fp; )
66315061Sgarrison                *cp++ = *fp++;
66415061Sgarrison             }
66515061Sgarrison          else if (c == '2')                     /* alternate alphabetic */
66615061Sgarrison             cp = aabet(cp, ref);
66715061Sgarrison          else if (c == '3')                     /* Astrophysical Journal style*/
66815061Sgarrison             cp = astro(cp, ref);
669*15890Srrh          else if (c == '9')                     /* Last name of Senior Author*/
670*15890Srrh             cp = aabetlast(cp, ref);
67115061Sgarrison /*       else if (c == '4')          here is how to add new styles */
67215061Sgarrison          else if (c == '{') {                   /* other information   */
67315061Sgarrison             while (*p != '}')
67415061Sgarrison                if (*p == 0)
67515061Sgarrison                   error("unexpected end of citation template");
67615061Sgarrison                else
67715061Sgarrison                   *cp++ = *p++;
67815061Sgarrison             p++;
67915061Sgarrison             }
68015061Sgarrison          else if (c == '<') {
68115061Sgarrison             while (*p != '>') {
68215061Sgarrison                if (*p == 0)
68315061Sgarrison                   error("unexpected end of citation template");
68415061Sgarrison                else
68515061Sgarrison                   *cp++ = *p++;
68615061Sgarrison                }
68715061Sgarrison             p++;
68815061Sgarrison             }
68915061Sgarrison          else if (c != '@')
69015061Sgarrison             *cp++ = c;
69115061Sgarrison          }
69215061Sgarrison       }
69315061Sgarrison    *cp++ = 0;
69415061Sgarrison }
69515061Sgarrison 
69615061Sgarrison /* alternate alphabetic citation style -
69715061Sgarrison         if 1 author - first three letters of last name
69815061Sgarrison         if 2 authors - first two letters of first, followed by first letter of
69915061Sgarrison                                 seond
70015061Sgarrison         if 3 or more authors - first letter of first three authors */
70115061Sgarrison    char *aabet(cp, ref)
70215061Sgarrison    char *cp, ref[];
70315061Sgarrison {  char field[REFSIZE], temp[100], *np, *fp;
70415061Sgarrison    int j, getname();
70515061Sgarrison 
70615061Sgarrison    if (getname(1, field, temp, ref)) {
70715061Sgarrison       np = cp;
70815061Sgarrison       fp = field;
70915061Sgarrison       for (j = 1; j <= 3; j++)
71015061Sgarrison          if (*fp != 0)
71115061Sgarrison             *cp++ = *fp++;
71215061Sgarrison       if (getname(2, field, temp, ref))
71315061Sgarrison          np[2] = field[0];
71415061Sgarrison       if (getname(3, field, temp, ref)) {
71515061Sgarrison          np[1] = np[2];
71615061Sgarrison          np[2] = field[0];
71715061Sgarrison          }
71815061Sgarrison       }
71915061Sgarrison return(cp);
72015061Sgarrison }
72115061Sgarrison 
722*15890Srrh /* alternate alphabetic citation style -
723*15890Srrh 	entire last name of senior author
724*15890Srrh */
725*15890Srrh    char *aabetlast(cp, ref)
726*15890Srrh    char *cp, ref[];
727*15890Srrh {  char field[REFSIZE], temp[100];
728*15890Srrh    char	*fp;
729*15890Srrh    int getname();
730*15890Srrh 
731*15890Srrh    if (getname(1, field, temp, ref)) {
732*15890Srrh       for (fp = field; *fp; )
733*15890Srrh          *cp++ = *fp++;
734*15890Srrh    }
735*15890Srrh    return(cp);
736*15890Srrh }
737*15890Srrh 
73815061Sgarrison /* Astrophysical Journal style
73915061Sgarrison         if 1 author - last name date
74015061Sgarrison         if 2 authors - last name and last name date
74115061Sgarrison         if 3 authors - last name, last name and last name date
74215061Sgarrison         if 4 or more authors - last name et al. date */
74315061Sgarrison    char *astro(cp, ref)
74415061Sgarrison    char *cp, ref[];
74515061Sgarrison {  char name1[100], name2[100], name3[100], temp[100], *fp;
74615061Sgarrison    int getname();
74715061Sgarrison 
74815061Sgarrison    if (getname(1, name1, temp, ref)) {
74915061Sgarrison       for (fp = name1; *fp; )
75015061Sgarrison          *cp++ = *fp++;
75115061Sgarrison       if (getname(4, name3, temp, ref)) {
75215061Sgarrison          for (fp = " et al."; *fp; )
75315061Sgarrison             *cp++ = *fp++;
75415061Sgarrison          }
75515061Sgarrison       else if (getname(2, name2, temp, ref)) {
75615061Sgarrison          if (getname(3, name3, temp, ref)) {
75715061Sgarrison             for (fp = "\\*(c]"; *fp; )
75815061Sgarrison                *cp++ = *fp++;
75915061Sgarrison             for (fp = name2; *fp; )
76015061Sgarrison                *cp++ = *fp++;
76115061Sgarrison             for (fp = "\\*(m]"; *fp; )
76215061Sgarrison                *cp++ = *fp++;
76315061Sgarrison             for (fp = name3; *fp; )
76415061Sgarrison                *cp++ = *fp++;
76515061Sgarrison             }
76615061Sgarrison          else {
76715061Sgarrison             for (fp = "\\*(n]"; *fp; )
76815061Sgarrison                *cp++ = *fp++;
76915061Sgarrison             for (fp = name2; *fp; )
77015061Sgarrison                *cp++ = *fp++;
77115061Sgarrison             }
77215061Sgarrison          }
77315061Sgarrison     }
77415061Sgarrison return(cp);
77515061Sgarrison }
77615061Sgarrison 
77715061Sgarrison /* getfield - get a single field from reference */
77815061Sgarrison    char *getfield(ptr, field, ref)
77915061Sgarrison    char *ptr, field[], ref[];
78015061Sgarrison {  char *p, *q, temp[100];
78115061Sgarrison    int  n, len, i, getname();
78215061Sgarrison 
78315061Sgarrison    field[0] = 0;
78415061Sgarrison    if (*ptr == 'A')
78515061Sgarrison       getname(1, field, temp, ref);
78615061Sgarrison    else
78715061Sgarrison       for (p = ref; *p; p++)
78815061Sgarrison          if (*p == '%' && *(p+1) == *ptr) {
78915061Sgarrison             for (p = p + 2; *p == ' '; p++)
79015061Sgarrison                ;
79115061Sgarrison             for (q = field; (*p != '\n') && (*p != '\0'); )
79215061Sgarrison                *q++ = *p++;
79315061Sgarrison             *q = 0;
79415061Sgarrison             break;
79515061Sgarrison             }
79615061Sgarrison    n = 0;
79715061Sgarrison    len = strlen(field);
79815061Sgarrison    if (*++ptr == '-') {
79915061Sgarrison       for (ptr++; isdigit(*ptr); ptr++)
80015061Sgarrison          n = 10 * n + (*ptr - '0');
80115061Sgarrison       if (n > len)
80215061Sgarrison          n = 0;
80315061Sgarrison       else
80415061Sgarrison          n = len - n;
80515061Sgarrison       for (i = 0; field[i] = field[i+n]; i++)
80615061Sgarrison          ;
80715061Sgarrison       }
80815061Sgarrison    else if (isdigit(*ptr)) {
80915061Sgarrison       for (; isdigit(*ptr); ptr++)
81015061Sgarrison          n = 10 * n + (*ptr - '0');
81115061Sgarrison       if (n > len)
81215061Sgarrison          n = len;
81315061Sgarrison       field[n] = 0;
81415061Sgarrison       }
81515061Sgarrison 
81615061Sgarrison    if (*ptr == 'u') {
81715061Sgarrison       ptr++;
81815061Sgarrison       for (p = field; *p; p++)
81915061Sgarrison          if (islower(*p))
82015061Sgarrison             *p = (*p - 'a') + 'A';
82115061Sgarrison       }
82215061Sgarrison    else if (*ptr == 'l') {
82315061Sgarrison       ptr++;
82415061Sgarrison       for (p = field; *p; p++)
82515061Sgarrison          if (isupper(*p))
82615061Sgarrison             *p = (*p - 'A') + 'a';
82715061Sgarrison       }
82815061Sgarrison    return(ptr);
82915061Sgarrison }
83015061Sgarrison 
83115061Sgarrison /* getname - get the nth name field from reference, breaking into
83215061Sgarrison              first and last names */
83315061Sgarrison    int getname(n, last, first, ref)
83415061Sgarrison    int  n;
83515061Sgarrison    char last[], first[], ref[];
83615061Sgarrison {  char *p;
83715061Sgarrison    int  m;
83815061Sgarrison 
83915061Sgarrison    m = n;
84015061Sgarrison    for (p = ref; *p; p++)
84115061Sgarrison       if (*p == '%' & *(p+1) == 'A') {
84215061Sgarrison          n--;
84315061Sgarrison          if (n == 0) {
84415061Sgarrison             for (p = p + 2; *p == ' '; p++) ;
84515061Sgarrison             breakname(p, first, last) ;
84615061Sgarrison             return(true);
84715061Sgarrison             }
84815061Sgarrison          }
84915061Sgarrison 
85015061Sgarrison    if (n == m)          /* no authors, try editors */
85115061Sgarrison       for (p = ref; *p; p++)
85215061Sgarrison          if (*p == '%' & *(p+1) == 'E') {
85315061Sgarrison             n--;
85415061Sgarrison             if (n == 0) {
85515061Sgarrison                for (p = p + 2; *p == ' '; p++) ;
85615061Sgarrison                breakname(p, first, last) ;
85715061Sgarrison                return(true);
85815061Sgarrison                }
85915061Sgarrison             }
86015061Sgarrison 
86115061Sgarrison    if (n == m) {        /* no editors, either, try institution */
86215061Sgarrison       first[0] = last[0] = '\0';
86315061Sgarrison       getfield("I", last, ref);
86415061Sgarrison       if (last[0] != '\0')
86515061Sgarrison          return(true);
86615061Sgarrison       }
86715061Sgarrison 
86815061Sgarrison    return(false);
86915061Sgarrison }
87015061Sgarrison 
87115061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
87215061Sgarrison                   single character disambiguators */
87315061Sgarrison    disambiguate()
87415061Sgarrison {  int i, j;
87515061Sgarrison    char adstr[2];
87615061Sgarrison 
87715061Sgarrison    for (i = 0; i < numrefs; i = j) {
87815061Sgarrison       j = i + 1;
87915061Sgarrison       if (strcmp(citestr[i], citestr[j])==0) {
88015061Sgarrison          adstr[0] = 'a'; adstr[1] = 0;
88115061Sgarrison          for (j = i+1; strcmp(citestr[i],citestr[j]) == 0; j++) {
88215061Sgarrison             adstr[0] = 'a' + (j-i);
88315061Sgarrison             strcat(citestr[j], adstr);
88415061Sgarrison             if (j == numrefs)
88515061Sgarrison                break;
88615061Sgarrison             }
88715061Sgarrison          adstr[0] = 'a';
88815061Sgarrison          strcat(citestr[i], adstr);
88915061Sgarrison          }
89015061Sgarrison      }
89115061Sgarrison }
89215061Sgarrison 
89315061Sgarrison 
89412910Sgarrison /* bldname - build a name field
89512910Sgarrison              doing abbreviations, reversals, and caps/small caps
89612910Sgarrison */
89712910Sgarrison    bldname(first, last, name, reverse)
89812910Sgarrison    char *first, *last, name[];
89912910Sgarrison    int reverse;
90012910Sgarrison {
90112910Sgarrison    char newfirst[120], newlast[120], *p, *q, *f, *l, *scopy();
90212910Sgarrison    int  flag;
90312910Sgarrison 
90412910Sgarrison    if (abbrev) {
90512910Sgarrison       p = first;
90612910Sgarrison       q = newfirst;
90712910Sgarrison       flag = false;
90812910Sgarrison       while (*p) {
90912910Sgarrison          while (*p == ' ')
91012910Sgarrison             p++;
91112910Sgarrison          if (*p == 0)
91212910Sgarrison             break;
91312910Sgarrison          if (isupper(*p)) {
91415061Sgarrison             if (flag)           /* between initial gap */
91512910Sgarrison                q = scopy(q, "\\*(a]");
91612910Sgarrison             flag = true;
91712910Sgarrison             *q++ = *p;
91815061Sgarrison             q = scopy(q, "\\*(p]");
91912910Sgarrison             }
92012910Sgarrison          if (*++p == '.')
92112910Sgarrison             p++;
92212910Sgarrison          else while (*p != 0 && ! isspace(*p))
92312910Sgarrison             p++;
92412910Sgarrison          }
92512910Sgarrison       *q = 0;
92612910Sgarrison       f = newfirst;
92712910Sgarrison       }
92812910Sgarrison    else
92912910Sgarrison       f = first;
93012910Sgarrison 
93112910Sgarrison    if (capsmcap) {
93212910Sgarrison       p = last;
93312910Sgarrison       q = newlast;
93412910Sgarrison       flag = 0;  /* 1 - printing cap, 2 - printing small */
93512910Sgarrison       while (*p)
93612910Sgarrison          if (islower(*p)) {
93712910Sgarrison             if (flag != 2)
93812910Sgarrison                q = scopy(q, "\\s-2");
93912910Sgarrison             flag = 2;
94012910Sgarrison             *q++ = (*p++ - 'a') + 'A';
94112910Sgarrison             }
94212910Sgarrison          else {
94312910Sgarrison             if (flag == 2)
94412910Sgarrison                q = scopy(q,"\\s+2");
94512910Sgarrison             flag = 1;
94612910Sgarrison             *q++ = *p++;
94712910Sgarrison             }
94812910Sgarrison       if (flag == 2)
94912910Sgarrison          q = scopy(q, "\\s+2");
95012910Sgarrison       *q = 0;
95112910Sgarrison       l = newlast;
95212910Sgarrison       }
95312910Sgarrison    else
95412910Sgarrison       l = last;
95512910Sgarrison 
95615061Sgarrison    if (f[0] == 0)
95715061Sgarrison       sprintf(name, "%s\n", l);
95815061Sgarrison    else if (reverse)
95915061Sgarrison       sprintf(name, "%s\\*(b]%s\n", l, f);
96012910Sgarrison    else
96112910Sgarrison       sprintf(name, "%s %s\n", f, l);
96212910Sgarrison }
96312910Sgarrison 
96412910Sgarrison /* prtauth - print author or editor field */
96512910Sgarrison    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
96612910Sgarrison    char c, *line;
96712910Sgarrison    int  num, max, abbrev, capsmcap, numrev;
96812910Sgarrison    FILE *ofd;
96912910Sgarrison {  char first[LINELENGTH], last[LINELENGTH];
97012910Sgarrison 
97112910Sgarrison    if (num <= numrev || abbrev || capsmcap) {
97212910Sgarrison       breakname(line, first, last);
97312910Sgarrison       bldname(first, last, line, num <= numrev);
97412910Sgarrison       }
97512910Sgarrison    if (num == 1)
97612910Sgarrison       fprintf(ofd,".ds [%c %s", c, line);
97712910Sgarrison    else if (num < max)
97812910Sgarrison       fprintf(ofd,".as [%c \\*(c]%s", c, line);
97912910Sgarrison    else if (max == 2)
98012910Sgarrison       fprintf(ofd,".as [%c \\*(n]%s", c, line);
98112910Sgarrison    else
98212910Sgarrison       fprintf(ofd,".as [%c \\*(m]%s", c, line);
98312910Sgarrison    if (num == max && index(trailstr, c))
98412910Sgarrison       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
98512910Sgarrison }
98612910Sgarrison 
98712910Sgarrison /* doline - actually print out a line of reference information */
98812910Sgarrison    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
98912910Sgarrison    char c, *line;
99012910Sgarrison    int numauths, maxauths, numeds, maxeds;
99112910Sgarrison    FILE *ofd;
99212910Sgarrison {
99312910Sgarrison 
99412910Sgarrison    switch(c) {
99512910Sgarrison       case 'A':
99612910Sgarrison           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
99712910Sgarrison           break;
99812910Sgarrison 
99912910Sgarrison        case 'E':
100012910Sgarrison           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
100112910Sgarrison           if (numeds == maxeds)
100212910Sgarrison              fprintf(ofd,".nr [E %d\n", maxeds);
100312910Sgarrison           break;
100412910Sgarrison 
100512910Sgarrison        case 'P':
100612910Sgarrison           if (index(line, '-'))
100712910Sgarrison              fprintf(ofd,".nr [P 1\n");
100812910Sgarrison           else
100912910Sgarrison              fprintf(ofd,".nr [P 0\n");
101012910Sgarrison           fprintf(ofd,".ds [P %s",line);
101112910Sgarrison           if (index(trailstr, 'P'))
101212910Sgarrison              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
101312910Sgarrison           break;
101412910Sgarrison 
101512910Sgarrison        case 'F':
101612910Sgarrison        case 'K': break;
101712910Sgarrison 
101812910Sgarrison        default:
101912910Sgarrison           fprintf(ofd,".ds [%c %s", c, line);
102012910Sgarrison           if (index(trailstr, c))
102112910Sgarrison              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
102212910Sgarrison           }
102312910Sgarrison }
102412910Sgarrison 
102515061Sgarrison /* dumpref - dump reference number i */
102615061Sgarrison    dumpref(i, ofd)
102715061Sgarrison    int i;
102815061Sgarrison    FILE *ofd;
102915061Sgarrison {  char ref[REFSIZE], *p, line[REFSIZE];
103015061Sgarrison    int numauths, maxauths, numeds, maxeds;
103115061Sgarrison 
103215061Sgarrison    rdref(refspos[i], ref);
103315061Sgarrison    maxauths = maxeds = 0;
103415061Sgarrison    numauths = numeds = 0;
103515061Sgarrison    for (p = ref; *p; p++)
103615061Sgarrison       if (*p == '%')
103715061Sgarrison          if (*(p+1) == 'A') maxauths++;
103815061Sgarrison          else if (*(p+1) == 'E') maxeds++;
103915061Sgarrison    fprintf(ofd, ".[-\n");
104015061Sgarrison    fprintf(ofd, ".ds [F %s\n",citestr[i]);
104115061Sgarrison    fseek(rfd, (long) refspos[i], 0);
104215061Sgarrison    while (fgets(line, REFSIZE, rfd) != NULL) {
104315061Sgarrison       if (line[0] == 0)        break;
104415061Sgarrison       else if (line[0] == '.') fprintf(ofd,"%s",line);
104515061Sgarrison       else {
104615061Sgarrison          if (line[0] == '%') {
104715061Sgarrison             for (p = &line[2]; *p == ' '; p++);
104815061Sgarrison             if (line[1] == 'A')       numauths++;
104915061Sgarrison             else if (line[1] == 'E')  numeds++;
105015061Sgarrison 
105115061Sgarrison             doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
105215061Sgarrison             }
105315061Sgarrison          }
105415061Sgarrison       }
105515061Sgarrison    fprintf(ofd,".][\n");
105615061Sgarrison }
1057