xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 15061)
113110Srrh #ifndef lint
2*15061Sgarrison static char sccsid[] = "@(#)bibargs.c	2.2	09/23/83";
313110Srrh #endif not lint
4*15061Sgarrison /*
5*15061Sgarrison         Authored by: Tim Budd, University of Arizona, 1983.
6*15061Sgarrison                 version 7/4/83
713110Srrh 
8*15061Sgarrison         Various modifications suggested by:
9*15061Sgarrison                 David Cherveny - Duke University Medical Center
10*15061Sgarrison                 Phil Garrison - UC Berkeley
11*15061Sgarrison                 M. J. Hawley - Yale University
12*15061Sgarrison 
13*15061Sgarrison 
14*15061Sgarrison 
15*15061Sgarrison 
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 */
26*15061Sgarrison    char bibfname[120];          /* file name currently being read            */
27*15061Sgarrison    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;
49*15061Sgarrison /* reference file information */
50*15061Sgarrison    extern long int refspos[];
51*15061Sgarrison    extern char reffile[];
52*15061Sgarrison    extern FILE *rfd;
53*15061Sgarrison    extern char *citestr[];
54*15061Sgarrison    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 
81*15061Sgarrison             case 'a':  for (p = &argv[i][2]; *p; p++)
82*15061Sgarrison                           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 
152*15061Sgarrison             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 
163*15061Sgarrison             case 't':  style = false;           /* fall through */
164*15061Sgarrison             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 
173*15061Sgarrison             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                           }
180*15061Sgarrison                        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 {
200*15061Sgarrison             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;
216*15061Sgarrison    char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
217*15061Sgarrison    int  i, j, getwrd();
21812910Sgarrison 
219*15061Sgarrison    strcpy(bibfname, np);
22012910Sgarrison    fd = fopen(np, "r");
22112910Sgarrison    if (fd == NULL && *np != '/') {
22212910Sgarrison       strcpy(name, "bib.");
22312910Sgarrison       strcat(name, np);
224*15061Sgarrison       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);
231*15061Sgarrison       strcpy(bibfname, name);
23212910Sgarrison       fd = fopen(name, "r");
23312910Sgarrison       }
23412910Sgarrison    if (fd == NULL) {
235*15061Sgarrison       bibwarning("%s: can't open", np);
236*15061Sgarrison       exit(1);
23712910Sgarrison       }
23812910Sgarrison 
239*15061Sgarrison    /* now go off and process file */
240*15061Sgarrison    biblineno = 1;
241*15061Sgarrison    while (tfgets(line, LINELENGTH, fd) != NULL) {
242*15061Sgarrison       biblineno++;
24312910Sgarrison       switch(line[0]) {
24412910Sgarrison 
24512910Sgarrison          case '#': break;
24612910Sgarrison 
24712961Sgarrison          case 'A': for (p = &line[1]; *p; p++)
248*15061Sgarrison                       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';
278*15061Sgarrison                        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 
313*15061Sgarrison          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 
328*15061Sgarrison          case 'X': capsmcap = true;     /* this is now replace by AX */
32912910Sgarrison                    break;
33012910Sgarrison 
33112910Sgarrison          default:  fprintf(tfd,"%s\n",line);
332*15061Sgarrison                    while (fgets(line, LINELENGTH, fd) != NULL)
33312910Sgarrison                       fputs(line, tfd);
33412910Sgarrison                    return;
33512910Sgarrison          }
336*15061Sgarrison 
337*15061Sgarrison    }
338*15061Sgarrison    /* close up */
339*15061Sgarrison    fclose(fd);
34012910Sgarrison }
34112910Sgarrison 
342*15061Sgarrison /* bibwarning - print out a warning message */
343*15061Sgarrison   bibwarning(msg, arg)
344*15061Sgarrison   char *msg, *arg;
345*15061Sgarrison {
346*15061Sgarrison   fprintf(stderr,"`%s', line %d: ", bibfname, biblineno);
347*15061Sgarrison   fprintf(stderr, msg, arg);
348*15061Sgarrison }
349*15061Sgarrison 
350*15061Sgarrison /* error - report unrecoverable error message */
351*15061Sgarrison   error(str)
352*15061Sgarrison   char str[];
353*15061Sgarrison {
354*15061Sgarrison   bibwarning("%s\n", str);
355*15061Sgarrison   exit(1);
356*15061Sgarrison }
357*15061Sgarrison 
358*15061Sgarrison #ifdef READWRITE
359*15061Sgarrison /*
360*15061Sgarrison ** fixrfd( mode ) -- re-opens the rfd file to be read or write,
361*15061Sgarrison **      depending on the mode.  Uses a static int to save the current mode
362*15061Sgarrison **      and avoid unnecessary re-openings.
363*15061Sgarrison */
364*15061Sgarrison fixrfd( mode )
365*15061Sgarrison register int mode;
366*15061Sgarrison {
367*15061Sgarrison 	static int cur_mode = WRITE;    /* rfd open for writing initially */
368*15061Sgarrison 
369*15061Sgarrison 	if (mode != cur_mode)
370*15061Sgarrison 	{
371*15061Sgarrison 		rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
372*15061Sgarrison 		cur_mode = mode;
373*15061Sgarrison 		if (rfd == NULL)
374*15061Sgarrison 		      error("Hell!  Couldn't re-open reference file");
375*15061Sgarrison 	}
376*15061Sgarrison }
377*15061Sgarrison #endif
378*15061Sgarrison 
379*15061Sgarrison 
380*15061Sgarrison /* tfgets - fgets which trims off newline */
381*15061Sgarrison    char *tfgets(line, n, ptr)
382*15061Sgarrison    char line[];
383*15061Sgarrison    int  n;
384*15061Sgarrison    FILE *ptr;
385*15061Sgarrison {  char *p;
386*15061Sgarrison 
387*15061Sgarrison    p = fgets(line, n, ptr);
388*15061Sgarrison    if (p == NULL)
389*15061Sgarrison       return(NULL);
390*15061Sgarrison    else
391*15061Sgarrison       for (p = line; *p; p++)
392*15061Sgarrison          if (*p == '\n')
393*15061Sgarrison             *p = 0;
394*15061Sgarrison    return(line);
395*15061Sgarrison }
396*15061Sgarrison 
397*15061Sgarrison /* getwrd - place next word from in[i] into out */
398*15061Sgarrison int getwrd(in, i, out)
399*15061Sgarrison    char in[], out[];
400*15061Sgarrison    int i;
401*15061Sgarrison {  int j;
402*15061Sgarrison 
403*15061Sgarrison    j = 0;
404*15061Sgarrison    while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
405*15061Sgarrison       i++;
406*15061Sgarrison    if (in[i])
407*15061Sgarrison       while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
408*15061Sgarrison          out[j++] = in[i++];
409*15061Sgarrison    else
410*15061Sgarrison       i = 0;    /* signals end of in[i..]   */
411*15061Sgarrison    out[j] = 0;
412*15061Sgarrison    return (i);
413*15061Sgarrison }
414*15061Sgarrison 
415*15061Sgarrison /* walloc - allocate enough space for a word */
416*15061Sgarrison char *walloc(word)
417*15061Sgarrison    char *word;
418*15061Sgarrison {  char *i, *malloc();
419*15061Sgarrison    i = malloc(1 + strlen(word));
420*15061Sgarrison    if (i == NULL)
421*15061Sgarrison       error("out of storage");
422*15061Sgarrison    strcpy(i, word);
423*15061Sgarrison    return(i);
424*15061Sgarrison }
425*15061Sgarrison 
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 
470*15061Sgarrison /* rdref - read text for an already cited reference */
471*15061Sgarrison    rdref(i, ref)
472*15061Sgarrison    long int  i;
473*15061Sgarrison    char ref[REFSIZE];
474*15061Sgarrison {
475*15061Sgarrison    ref[0] = 0;
476*15061Sgarrison #ifdef READWRITE
477*15061Sgarrison    fixrfd( READ );                      /* fix access mode of rfd, if nec. */
478*15061Sgarrison #endif
479*15061Sgarrison    fseek(rfd, i, 0);
480*15061Sgarrison    fread(ref, 1, REFSIZE, rfd);
481*15061Sgarrison }
482*15061Sgarrison 
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;
496*15061Sgarrison    if (q != line) {
49712910Sgarrison       q++;
498*15061Sgarrison       for (; isspace(*f); f--);
499*15061Sgarrison       f++;
500*15061Sgarrison       }
50112910Sgarrison 
50212910Sgarrison    /* first name is start to f, last name is q to t */
50312910Sgarrison 
504*15061Sgarrison    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;
510*15061Sgarrison 
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 
543*15061Sgarrison /* rcomp - reference comparison routine for qsort utility */
544*15061Sgarrison    int rcomp(ap, bp)
545*15061Sgarrison    long int *ap, *bp;
546*15061Sgarrison {  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
547*15061Sgarrison    char *p, *q, *getfield();
548*15061Sgarrison    int  neg, res;
549*15061Sgarrison    int  fields_found;
550*15061Sgarrison 
551*15061Sgarrison    rdref(*ap, ref1);
552*15061Sgarrison    rdref(*bp, ref2);
553*15061Sgarrison    for (p = sortstr; *p; p = q) {
554*15061Sgarrison       if (*p == '-') {
555*15061Sgarrison          p++;
556*15061Sgarrison          neg = true;
557*15061Sgarrison          }
558*15061Sgarrison       else
559*15061Sgarrison          neg = false;
560*15061Sgarrison       q = getfield(p, field1, ref1);
561*15061Sgarrison       fields_found = true;
562*15061Sgarrison       if (q == 0) {
563*15061Sgarrison 	 res = 1;
564*15061Sgarrison 	 fields_found = false;
565*15061Sgarrison       } else if (strcmp (field1, "") == 0) {	/* field not found */
566*15061Sgarrison          if (*p == 'A') {
567*15061Sgarrison             getfield("F", field1, ref1);
568*15061Sgarrison 	    if (strcmp (field1, "") == 0) {
569*15061Sgarrison                getfield("I", field1, ref1);
570*15061Sgarrison 	       if (strcmp (field1, "") == 0) {
571*15061Sgarrison 	          res = 1;
572*15061Sgarrison 		  fields_found = false;
573*15061Sgarrison 	       }
574*15061Sgarrison 	    }
575*15061Sgarrison 	 } else {
576*15061Sgarrison 	    res = 1;
577*15061Sgarrison 	    fields_found = false;
578*15061Sgarrison 	 }
579*15061Sgarrison       }
580*15061Sgarrison 
581*15061Sgarrison       if (getfield(p, field2, ref2) == 0) {
582*15061Sgarrison 	 res = -1;
583*15061Sgarrison 	 fields_found = false;
584*15061Sgarrison       } else if (strcmp (field2, "") == 0) {	/* field not found */
585*15061Sgarrison          if (*p == 'A') {
586*15061Sgarrison             getfield("F", field2, ref2);
587*15061Sgarrison 	    if (strcmp (field2, "") == 0) {
588*15061Sgarrison                getfield("I", field2, ref2);
589*15061Sgarrison 	       if (strcmp (field2, "") == 0) {
590*15061Sgarrison 	          res = -1;
591*15061Sgarrison 		  fields_found = false;
592*15061Sgarrison 	       }
593*15061Sgarrison 	    }
594*15061Sgarrison 	 } else {
595*15061Sgarrison 	    res = -1;
596*15061Sgarrison 	    fields_found = false;
597*15061Sgarrison 	 }
598*15061Sgarrison       }
599*15061Sgarrison       if (fields_found) {
600*15061Sgarrison          if (*p == 'A') {
601*15061Sgarrison             if (isupper(field1[0]))
602*15061Sgarrison                field1[0] -= 'A' - 'a';
603*15061Sgarrison             if (isupper(field2[0]))
604*15061Sgarrison                field2[0] -= 'A' - 'a';
605*15061Sgarrison             }
606*15061Sgarrison          res = strcmp(field1, field2);
607*15061Sgarrison          }
608*15061Sgarrison       if (neg)
609*15061Sgarrison          res = - res;
610*15061Sgarrison       if (res != 0)
611*15061Sgarrison          break;
612*15061Sgarrison       }
613*15061Sgarrison    if (res == 0)
614*15061Sgarrison       if (ap < bp)
615*15061Sgarrison          res = -1;
616*15061Sgarrison       else
617*15061Sgarrison          res = 1;
618*15061Sgarrison    return(res);
619*15061Sgarrison }
620*15061Sgarrison 
621*15061Sgarrison /* makecites - make citation strings */
622*15061Sgarrison    makecites(citestr)
623*15061Sgarrison    char *citestr[];
624*15061Sgarrison {  char ref[REFSIZE], tempcite[100], *malloc();
625*15061Sgarrison    int  i;
626*15061Sgarrison 
627*15061Sgarrison    for (i = 0; i <= numrefs; i++) {
628*15061Sgarrison       rdref(refspos[i], ref);
629*15061Sgarrison       bldcite(tempcite, i, ref);
630*15061Sgarrison       citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */
631*15061Sgarrison       if (citestr[i] == NULL)
632*15061Sgarrison          error("out of storage");
633*15061Sgarrison       strcpy(citestr[i], tempcite);
634*15061Sgarrison       }
635*15061Sgarrison }
636*15061Sgarrison 
637*15061Sgarrison /* bldcite - build a single citation string */
638*15061Sgarrison    bldcite(cp, i, ref)
639*15061Sgarrison    char *cp, ref[];
640*15061Sgarrison    int  i;
641*15061Sgarrison {  char *p, *q, c, *fp, field[REFSIZE], *getfield(), *aabet(), *astro();
642*15061Sgarrison 
643*15061Sgarrison    getfield("F", field, ref);
644*15061Sgarrison    if (field[0] != 0)
645*15061Sgarrison       for (p = field; *p; p++)
646*15061Sgarrison          *cp++ = *p;
647*15061Sgarrison    else {
648*15061Sgarrison       p = citetemplate;
649*15061Sgarrison       field[0] = 0;
650*15061Sgarrison       while (c = *p++) {
651*15061Sgarrison          if (isalpha(c)) {                      /* field name   */
652*15061Sgarrison             q = getfield(p-1, field, ref);
653*15061Sgarrison             if (q != 0) {
654*15061Sgarrison                p = q;
655*15061Sgarrison                for (fp = field; *fp; )
656*15061Sgarrison                   *cp++ = *fp++;
657*15061Sgarrison                }
658*15061Sgarrison             }
659*15061Sgarrison          else if (c == '1') {                   /* numeric  order */
660*15061Sgarrison             sprintf(field,"%d",1 + i);
661*15061Sgarrison             for (fp = field; *fp; )
662*15061Sgarrison                *cp++ = *fp++;
663*15061Sgarrison             }
664*15061Sgarrison          else if (c == '2')                     /* alternate alphabetic */
665*15061Sgarrison             cp = aabet(cp, ref);
666*15061Sgarrison          else if (c == '3')                     /* Astrophysical Journal style*/
667*15061Sgarrison             cp = astro(cp, ref);
668*15061Sgarrison /*       else if (c == '4')          here is how to add new styles */
669*15061Sgarrison          else if (c == '{') {                   /* other information   */
670*15061Sgarrison             while (*p != '}')
671*15061Sgarrison                if (*p == 0)
672*15061Sgarrison                   error("unexpected end of citation template");
673*15061Sgarrison                else
674*15061Sgarrison                   *cp++ = *p++;
675*15061Sgarrison             p++;
676*15061Sgarrison             }
677*15061Sgarrison          else if (c == '<') {
678*15061Sgarrison             while (*p != '>') {
679*15061Sgarrison                if (*p == 0)
680*15061Sgarrison                   error("unexpected end of citation template");
681*15061Sgarrison                else
682*15061Sgarrison                   *cp++ = *p++;
683*15061Sgarrison                }
684*15061Sgarrison             p++;
685*15061Sgarrison             }
686*15061Sgarrison          else if (c != '@')
687*15061Sgarrison             *cp++ = c;
688*15061Sgarrison          }
689*15061Sgarrison       }
690*15061Sgarrison    *cp++ = 0;
691*15061Sgarrison }
692*15061Sgarrison 
693*15061Sgarrison /* alternate alphabetic citation style -
694*15061Sgarrison         if 1 author - first three letters of last name
695*15061Sgarrison         if 2 authors - first two letters of first, followed by first letter of
696*15061Sgarrison                                 seond
697*15061Sgarrison         if 3 or more authors - first letter of first three authors */
698*15061Sgarrison    char *aabet(cp, ref)
699*15061Sgarrison    char *cp, ref[];
700*15061Sgarrison {  char field[REFSIZE], temp[100], *np, *fp;
701*15061Sgarrison    int j, getname();
702*15061Sgarrison 
703*15061Sgarrison    if (getname(1, field, temp, ref)) {
704*15061Sgarrison       np = cp;
705*15061Sgarrison       fp = field;
706*15061Sgarrison       for (j = 1; j <= 3; j++)
707*15061Sgarrison          if (*fp != 0)
708*15061Sgarrison             *cp++ = *fp++;
709*15061Sgarrison       if (getname(2, field, temp, ref))
710*15061Sgarrison          np[2] = field[0];
711*15061Sgarrison       if (getname(3, field, temp, ref)) {
712*15061Sgarrison          np[1] = np[2];
713*15061Sgarrison          np[2] = field[0];
714*15061Sgarrison          }
715*15061Sgarrison       }
716*15061Sgarrison return(cp);
717*15061Sgarrison }
718*15061Sgarrison 
719*15061Sgarrison /* Astrophysical Journal style
720*15061Sgarrison         if 1 author - last name date
721*15061Sgarrison         if 2 authors - last name and last name date
722*15061Sgarrison         if 3 authors - last name, last name and last name date
723*15061Sgarrison         if 4 or more authors - last name et al. date */
724*15061Sgarrison    char *astro(cp, ref)
725*15061Sgarrison    char *cp, ref[];
726*15061Sgarrison {  char name1[100], name2[100], name3[100], temp[100], *fp;
727*15061Sgarrison    int getname();
728*15061Sgarrison 
729*15061Sgarrison    if (getname(1, name1, temp, ref)) {
730*15061Sgarrison       for (fp = name1; *fp; )
731*15061Sgarrison          *cp++ = *fp++;
732*15061Sgarrison       if (getname(4, name3, temp, ref)) {
733*15061Sgarrison          for (fp = " et al."; *fp; )
734*15061Sgarrison             *cp++ = *fp++;
735*15061Sgarrison          }
736*15061Sgarrison       else if (getname(2, name2, temp, ref)) {
737*15061Sgarrison          if (getname(3, name3, temp, ref)) {
738*15061Sgarrison             for (fp = "\\*(c]"; *fp; )
739*15061Sgarrison                *cp++ = *fp++;
740*15061Sgarrison             for (fp = name2; *fp; )
741*15061Sgarrison                *cp++ = *fp++;
742*15061Sgarrison             for (fp = "\\*(m]"; *fp; )
743*15061Sgarrison                *cp++ = *fp++;
744*15061Sgarrison             for (fp = name3; *fp; )
745*15061Sgarrison                *cp++ = *fp++;
746*15061Sgarrison             }
747*15061Sgarrison          else {
748*15061Sgarrison             for (fp = "\\*(n]"; *fp; )
749*15061Sgarrison                *cp++ = *fp++;
750*15061Sgarrison             for (fp = name2; *fp; )
751*15061Sgarrison                *cp++ = *fp++;
752*15061Sgarrison             }
753*15061Sgarrison          }
754*15061Sgarrison     }
755*15061Sgarrison return(cp);
756*15061Sgarrison }
757*15061Sgarrison 
758*15061Sgarrison /* getfield - get a single field from reference */
759*15061Sgarrison    char *getfield(ptr, field, ref)
760*15061Sgarrison    char *ptr, field[], ref[];
761*15061Sgarrison {  char *p, *q, temp[100];
762*15061Sgarrison    int  n, len, i, getname();
763*15061Sgarrison 
764*15061Sgarrison    field[0] = 0;
765*15061Sgarrison    if (*ptr == 'A')
766*15061Sgarrison       getname(1, field, temp, ref);
767*15061Sgarrison    else
768*15061Sgarrison       for (p = ref; *p; p++)
769*15061Sgarrison          if (*p == '%' && *(p+1) == *ptr) {
770*15061Sgarrison             for (p = p + 2; *p == ' '; p++)
771*15061Sgarrison                ;
772*15061Sgarrison             for (q = field; (*p != '\n') && (*p != '\0'); )
773*15061Sgarrison                *q++ = *p++;
774*15061Sgarrison             *q = 0;
775*15061Sgarrison             break;
776*15061Sgarrison             }
777*15061Sgarrison    n = 0;
778*15061Sgarrison    len = strlen(field);
779*15061Sgarrison    if (*++ptr == '-') {
780*15061Sgarrison       for (ptr++; isdigit(*ptr); ptr++)
781*15061Sgarrison          n = 10 * n + (*ptr - '0');
782*15061Sgarrison       if (n > len)
783*15061Sgarrison          n = 0;
784*15061Sgarrison       else
785*15061Sgarrison          n = len - n;
786*15061Sgarrison       for (i = 0; field[i] = field[i+n]; i++)
787*15061Sgarrison          ;
788*15061Sgarrison       }
789*15061Sgarrison    else if (isdigit(*ptr)) {
790*15061Sgarrison       for (; isdigit(*ptr); ptr++)
791*15061Sgarrison          n = 10 * n + (*ptr - '0');
792*15061Sgarrison       if (n > len)
793*15061Sgarrison          n = len;
794*15061Sgarrison       field[n] = 0;
795*15061Sgarrison       }
796*15061Sgarrison 
797*15061Sgarrison    if (*ptr == 'u') {
798*15061Sgarrison       ptr++;
799*15061Sgarrison       for (p = field; *p; p++)
800*15061Sgarrison          if (islower(*p))
801*15061Sgarrison             *p = (*p - 'a') + 'A';
802*15061Sgarrison       }
803*15061Sgarrison    else if (*ptr == 'l') {
804*15061Sgarrison       ptr++;
805*15061Sgarrison       for (p = field; *p; p++)
806*15061Sgarrison          if (isupper(*p))
807*15061Sgarrison             *p = (*p - 'A') + 'a';
808*15061Sgarrison       }
809*15061Sgarrison    return(ptr);
810*15061Sgarrison }
811*15061Sgarrison 
812*15061Sgarrison /* getname - get the nth name field from reference, breaking into
813*15061Sgarrison              first and last names */
814*15061Sgarrison    int getname(n, last, first, ref)
815*15061Sgarrison    int  n;
816*15061Sgarrison    char last[], first[], ref[];
817*15061Sgarrison {  char *p;
818*15061Sgarrison    int  m;
819*15061Sgarrison 
820*15061Sgarrison    m = n;
821*15061Sgarrison    for (p = ref; *p; p++)
822*15061Sgarrison       if (*p == '%' & *(p+1) == 'A') {
823*15061Sgarrison          n--;
824*15061Sgarrison          if (n == 0) {
825*15061Sgarrison             for (p = p + 2; *p == ' '; p++) ;
826*15061Sgarrison             breakname(p, first, last) ;
827*15061Sgarrison             return(true);
828*15061Sgarrison             }
829*15061Sgarrison          }
830*15061Sgarrison 
831*15061Sgarrison    if (n == m)          /* no authors, try editors */
832*15061Sgarrison       for (p = ref; *p; p++)
833*15061Sgarrison          if (*p == '%' & *(p+1) == 'E') {
834*15061Sgarrison             n--;
835*15061Sgarrison             if (n == 0) {
836*15061Sgarrison                for (p = p + 2; *p == ' '; p++) ;
837*15061Sgarrison                breakname(p, first, last) ;
838*15061Sgarrison                return(true);
839*15061Sgarrison                }
840*15061Sgarrison             }
841*15061Sgarrison 
842*15061Sgarrison    if (n == m) {        /* no editors, either, try institution */
843*15061Sgarrison       first[0] = last[0] = '\0';
844*15061Sgarrison       getfield("I", last, ref);
845*15061Sgarrison       if (last[0] != '\0')
846*15061Sgarrison          return(true);
847*15061Sgarrison       }
848*15061Sgarrison 
849*15061Sgarrison    return(false);
850*15061Sgarrison }
851*15061Sgarrison 
852*15061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
853*15061Sgarrison                   single character disambiguators */
854*15061Sgarrison    disambiguate()
855*15061Sgarrison {  int i, j;
856*15061Sgarrison    char adstr[2];
857*15061Sgarrison 
858*15061Sgarrison    for (i = 0; i < numrefs; i = j) {
859*15061Sgarrison       j = i + 1;
860*15061Sgarrison       if (strcmp(citestr[i], citestr[j])==0) {
861*15061Sgarrison          adstr[0] = 'a'; adstr[1] = 0;
862*15061Sgarrison          for (j = i+1; strcmp(citestr[i],citestr[j]) == 0; j++) {
863*15061Sgarrison             adstr[0] = 'a' + (j-i);
864*15061Sgarrison             strcat(citestr[j], adstr);
865*15061Sgarrison             if (j == numrefs)
866*15061Sgarrison                break;
867*15061Sgarrison             }
868*15061Sgarrison          adstr[0] = 'a';
869*15061Sgarrison          strcat(citestr[i], adstr);
870*15061Sgarrison          }
871*15061Sgarrison      }
872*15061Sgarrison }
873*15061Sgarrison 
874*15061Sgarrison 
87512910Sgarrison /* bldname - build a name field
87612910Sgarrison              doing abbreviations, reversals, and caps/small caps
87712910Sgarrison */
87812910Sgarrison    bldname(first, last, name, reverse)
87912910Sgarrison    char *first, *last, name[];
88012910Sgarrison    int reverse;
88112910Sgarrison {
88212910Sgarrison    char newfirst[120], newlast[120], *p, *q, *f, *l, *scopy();
88312910Sgarrison    int  flag;
88412910Sgarrison 
88512910Sgarrison    if (abbrev) {
88612910Sgarrison       p = first;
88712910Sgarrison       q = newfirst;
88812910Sgarrison       flag = false;
88912910Sgarrison       while (*p) {
89012910Sgarrison          while (*p == ' ')
89112910Sgarrison             p++;
89212910Sgarrison          if (*p == 0)
89312910Sgarrison             break;
89412910Sgarrison          if (isupper(*p)) {
895*15061Sgarrison             if (flag)           /* between initial gap */
89612910Sgarrison                q = scopy(q, "\\*(a]");
89712910Sgarrison             flag = true;
89812910Sgarrison             *q++ = *p;
899*15061Sgarrison             q = scopy(q, "\\*(p]");
90012910Sgarrison             }
90112910Sgarrison          if (*++p == '.')
90212910Sgarrison             p++;
90312910Sgarrison          else while (*p != 0 && ! isspace(*p))
90412910Sgarrison             p++;
90512910Sgarrison          }
90612910Sgarrison       *q = 0;
90712910Sgarrison       f = newfirst;
90812910Sgarrison       }
90912910Sgarrison    else
91012910Sgarrison       f = first;
91112910Sgarrison 
91212910Sgarrison    if (capsmcap) {
91312910Sgarrison       p = last;
91412910Sgarrison       q = newlast;
91512910Sgarrison       flag = 0;  /* 1 - printing cap, 2 - printing small */
91612910Sgarrison       while (*p)
91712910Sgarrison          if (islower(*p)) {
91812910Sgarrison             if (flag != 2)
91912910Sgarrison                q = scopy(q, "\\s-2");
92012910Sgarrison             flag = 2;
92112910Sgarrison             *q++ = (*p++ - 'a') + 'A';
92212910Sgarrison             }
92312910Sgarrison          else {
92412910Sgarrison             if (flag == 2)
92512910Sgarrison                q = scopy(q,"\\s+2");
92612910Sgarrison             flag = 1;
92712910Sgarrison             *q++ = *p++;
92812910Sgarrison             }
92912910Sgarrison       if (flag == 2)
93012910Sgarrison          q = scopy(q, "\\s+2");
93112910Sgarrison       *q = 0;
93212910Sgarrison       l = newlast;
93312910Sgarrison       }
93412910Sgarrison    else
93512910Sgarrison       l = last;
93612910Sgarrison 
937*15061Sgarrison    if (f[0] == 0)
938*15061Sgarrison       sprintf(name, "%s\n", l);
939*15061Sgarrison    else if (reverse)
940*15061Sgarrison       sprintf(name, "%s\\*(b]%s\n", l, f);
94112910Sgarrison    else
94212910Sgarrison       sprintf(name, "%s %s\n", f, l);
94312910Sgarrison }
94412910Sgarrison 
94512910Sgarrison /* prtauth - print author or editor field */
94612910Sgarrison    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
94712910Sgarrison    char c, *line;
94812910Sgarrison    int  num, max, abbrev, capsmcap, numrev;
94912910Sgarrison    FILE *ofd;
95012910Sgarrison {  char first[LINELENGTH], last[LINELENGTH];
95112910Sgarrison 
95212910Sgarrison    if (num <= numrev || abbrev || capsmcap) {
95312910Sgarrison       breakname(line, first, last);
95412910Sgarrison       bldname(first, last, line, num <= numrev);
95512910Sgarrison       }
95612910Sgarrison    if (num == 1)
95712910Sgarrison       fprintf(ofd,".ds [%c %s", c, line);
95812910Sgarrison    else if (num < max)
95912910Sgarrison       fprintf(ofd,".as [%c \\*(c]%s", c, line);
96012910Sgarrison    else if (max == 2)
96112910Sgarrison       fprintf(ofd,".as [%c \\*(n]%s", c, line);
96212910Sgarrison    else
96312910Sgarrison       fprintf(ofd,".as [%c \\*(m]%s", c, line);
96412910Sgarrison    if (num == max && index(trailstr, c))
96512910Sgarrison       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
96612910Sgarrison }
96712910Sgarrison 
96812910Sgarrison /* doline - actually print out a line of reference information */
96912910Sgarrison    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
97012910Sgarrison    char c, *line;
97112910Sgarrison    int numauths, maxauths, numeds, maxeds;
97212910Sgarrison    FILE *ofd;
97312910Sgarrison {
97412910Sgarrison 
97512910Sgarrison    switch(c) {
97612910Sgarrison       case 'A':
97712910Sgarrison           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
97812910Sgarrison           break;
97912910Sgarrison 
98012910Sgarrison        case 'E':
98112910Sgarrison           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
98212910Sgarrison           if (numeds == maxeds)
98312910Sgarrison              fprintf(ofd,".nr [E %d\n", maxeds);
98412910Sgarrison           break;
98512910Sgarrison 
98612910Sgarrison        case 'P':
98712910Sgarrison           if (index(line, '-'))
98812910Sgarrison              fprintf(ofd,".nr [P 1\n");
98912910Sgarrison           else
99012910Sgarrison              fprintf(ofd,".nr [P 0\n");
99112910Sgarrison           fprintf(ofd,".ds [P %s",line);
99212910Sgarrison           if (index(trailstr, 'P'))
99312910Sgarrison              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
99412910Sgarrison           break;
99512910Sgarrison 
99612910Sgarrison        case 'F':
99712910Sgarrison        case 'K': break;
99812910Sgarrison 
99912910Sgarrison        default:
100012910Sgarrison           fprintf(ofd,".ds [%c %s", c, line);
100112910Sgarrison           if (index(trailstr, c))
100212910Sgarrison              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
100312910Sgarrison           }
100412910Sgarrison }
100512910Sgarrison 
1006*15061Sgarrison /* dumpref - dump reference number i */
1007*15061Sgarrison    dumpref(i, ofd)
1008*15061Sgarrison    int i;
1009*15061Sgarrison    FILE *ofd;
1010*15061Sgarrison {  char ref[REFSIZE], *p, line[REFSIZE];
1011*15061Sgarrison    int numauths, maxauths, numeds, maxeds;
1012*15061Sgarrison 
1013*15061Sgarrison    rdref(refspos[i], ref);
1014*15061Sgarrison    maxauths = maxeds = 0;
1015*15061Sgarrison    numauths = numeds = 0;
1016*15061Sgarrison    for (p = ref; *p; p++)
1017*15061Sgarrison       if (*p == '%')
1018*15061Sgarrison          if (*(p+1) == 'A') maxauths++;
1019*15061Sgarrison          else if (*(p+1) == 'E') maxeds++;
1020*15061Sgarrison    fprintf(ofd, ".[-\n");
1021*15061Sgarrison    fprintf(ofd, ".ds [F %s\n",citestr[i]);
1022*15061Sgarrison    fseek(rfd, (long) refspos[i], 0);
1023*15061Sgarrison    while (fgets(line, REFSIZE, rfd) != NULL) {
1024*15061Sgarrison       if (line[0] == 0)        break;
1025*15061Sgarrison       else if (line[0] == '.') fprintf(ofd,"%s",line);
1026*15061Sgarrison       else {
1027*15061Sgarrison          if (line[0] == '%') {
1028*15061Sgarrison             for (p = &line[2]; *p == ' '; p++);
1029*15061Sgarrison             if (line[1] == 'A')       numauths++;
1030*15061Sgarrison             else if (line[1] == 'E')  numeds++;
1031*15061Sgarrison 
1032*15061Sgarrison             doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
1033*15061Sgarrison             }
1034*15061Sgarrison          }
1035*15061Sgarrison       }
1036*15061Sgarrison    fprintf(ofd,".][\n");
1037*15061Sgarrison }
1038