xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 13108)
112910Sgarrison /*
212910Sgarrison         read argument strings for bib and listrefs
312910Sgarrison         do name formatting, printing lines, other actions common to both
412910Sgarrison                                                         */
512910Sgarrison # include <stdio.h>
612910Sgarrison # include <ctype.h>
712910Sgarrison # include "bib.h"
812910Sgarrison # define LINELENGTH 1024
912910Sgarrison # define MAXDEFS     500             /* maximum number of defined words */
1012910Sgarrison 
1112910Sgarrison /* global variables */
1212910Sgarrison    int  abbrev       = false;   /* automatically abbreviate names            */
1312910Sgarrison    int  capsmcap     = false;   /* print names in caps small caps (CACM form)*/
1412910Sgarrison    int  numrev       = 0;       /* number of authors names to reverse        */
1512910Sgarrison    int  edabbrev     = false;   /* abbreviate editors names ?                */
1612910Sgarrison    int  edcapsmcap   = false;   /* print editors in cap small caps           */
1712910Sgarrison    int  ednumrev     = 0;       /* number of editors to reverse              */
1812910Sgarrison    int  sort         = false;   /* sort references ? (default no)            */
1912910Sgarrison    int  foot         = false;   /* footnoted references ? (default endnotes) */
2012910Sgarrison    int  hyphen       = false;   /* hypenate contiguous references            */
2112910Sgarrison    int  ordcite      = true;    /* order multiple citations                  */
2212910Sgarrison    char sortstr[80]  = "1";     /* sorting template                          */
2312910Sgarrison    char trailstr[80] = "";      /* trailing characters to output             */
2412910Sgarrison    char pfile[120];             /* private file name                         */
2512910Sgarrison    int  personal = false;       /* personal file given ? (default no)        */
2612910Sgarrison    char citetemplate[80] = "1"; /* citation template                         */
2712910Sgarrison    char *words[MAXDEFS];        /* defined words                             */
2812910Sgarrison    char *defs[MAXDEFS];         /* defined word definitions                  */
2912910Sgarrison    int  wordtop = -1;           /* top of defined words array                */
30*13108Srrh    char *bibfname;
31*13108Srrh    char *biblineno;
3212910Sgarrison 
3312910Sgarrison /* where output goes */
3412910Sgarrison    extern FILE *tfd;
3512910Sgarrison 
3612910Sgarrison /* doargs - read command argument line for both bib and listrefs
3712910Sgarrison             set switch values
3812910Sgarrison             call rdtext on file arguments, after dumping
3912910Sgarrison             default style file if no alternative style is given
4012910Sgarrison */
4112910Sgarrison    int doargs(argc, argv, defstyle)
4212910Sgarrison    int argc;
4312910Sgarrison    char **argv, defstyle[];
4412910Sgarrison {  int numfiles, i, style;
4512910Sgarrison    char *p, *q, *walloc();
4612910Sgarrison    FILE *fd;
4712910Sgarrison 
4812910Sgarrison    numfiles = 0;
4912910Sgarrison    style = true;
5012910Sgarrison    words[0] = walloc("BMACLIB");
5112910Sgarrison    defs[0]  = walloc(BMACLIB);
5212910Sgarrison    wordtop++;
5312910Sgarrison    fputs(".ds l] ",tfd);
5412910Sgarrison    fputs(BMACLIB, tfd);
5512910Sgarrison    fputs("\n", tfd);
5612910Sgarrison 
5712910Sgarrison    for (i = 1; i < argc; i++)
5812910Sgarrison       if (argv[i][0] == '-')
5912910Sgarrison          switch(argv[i][1]) {
6012910Sgarrison 
6112961Sgarrison             case 'a':  for (p = &argv[i][2]; *p; p++) /* author */
6212961Sgarrison                           if (*p == 'a')
6312961Sgarrison                              abbrev = true;
6412961Sgarrison                            else if (*p == 'x')
6512961Sgarrison                              capsmcap = true;
6612961Sgarrison                            else if (*p == 'r') {
6712961Sgarrison                              if (*(p+1))
6812961Sgarrison                                 numrev = atoi(p+1);
6912961Sgarrison                               else
7012961Sgarrison                                 numrev = 1000;
7112961Sgarrison                               break;
7212961Sgarrison                               }
7312910Sgarrison                        break;
7412910Sgarrison 
7512910Sgarrison             case 'c':  if (argv[i][2] == 0)
7612910Sgarrison                           error("citation string expected");
7712910Sgarrison                        else
7812910Sgarrison                           for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
7912910Sgarrison                        break;
8012910Sgarrison 
8112910Sgarrison             case 'e':  for (p = &argv[i][2]; *p; p++)
8212910Sgarrison                           if (*p == 'a')
8312910Sgarrison                              edabbrev = true;
8412910Sgarrison                            else if (*p == 'x')
8512910Sgarrison                              edcapsmcap = true;
8612910Sgarrison                            else if (*p == 'r') {
8712910Sgarrison                              if (*(p+1))
8812910Sgarrison                                 ednumrev = atoi(p+1);
8912910Sgarrison                               else
9012910Sgarrison                                 ednumrev = 1000;
9112910Sgarrison                               break;
9212910Sgarrison                               }
9312910Sgarrison                        break;
9412910Sgarrison 
9512910Sgarrison             case 'f':  foot = true;
9612910Sgarrison                        hyphen = false;
9712910Sgarrison                        break;
9812910Sgarrison 
9912910Sgarrison             case 'h':  hyphen = ordcite = true;
10012910Sgarrison                        break;
10112910Sgarrison 
10212910Sgarrison             case 'n':  for (p = &argv[i][2]; *p; p++)
10312910Sgarrison                           if (*p == 'a')
10412910Sgarrison                              abbrev = false;
10512910Sgarrison                           else if (*p == 'f')
10612910Sgarrison                              foot = false;
10712910Sgarrison                           else if (*p == 'h')
10812910Sgarrison                              hyphen = false;
10912910Sgarrison                           else if (*p == 'o')
11012910Sgarrison                              ordcite = false;
11112910Sgarrison                           else if (*p == 'r')
11212910Sgarrison                              numrev = 0;
11312910Sgarrison                           else if (*p == 's')
11412910Sgarrison                              sort = false;
11512910Sgarrison                           else if (*p == 'x')
11612910Sgarrison                              capsmcap = false;
11712910Sgarrison                        break;
11812910Sgarrison 
11912910Sgarrison             case 'o':  ordcite = true;
12012910Sgarrison                        break;
12112910Sgarrison 
12212910Sgarrison             case 'p':  if (argv[i][2])
12312910Sgarrison                           p = &argv[i][2];
12412910Sgarrison                        else {  /* take next arg */
12512910Sgarrison                           i++;
12612910Sgarrison                           p = argv[i];
12712910Sgarrison                           }
12812910Sgarrison                        strcpy(pfile, p);
12912910Sgarrison                        personal = true;
13012910Sgarrison                        break;
13112910Sgarrison 
13212910Sgarrison             case 'r':  if (argv[i][2] == 0)
13312910Sgarrison                           numrev = 1000;
13412910Sgarrison                        else
13512910Sgarrison                           numrev = atoi(&argv[i][2]);
13612910Sgarrison                        break;
13712910Sgarrison 
13812910Sgarrison             case 's':  sort = true;
13912910Sgarrison                        if (argv[i][2])
14012910Sgarrison                           for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
14112910Sgarrison                        break;
14212910Sgarrison 
14312910Sgarrison             case 'i':
14412910Sgarrison             case 't':  if (argv[i][1] == 't')
14512910Sgarrison                           style = false;
14612910Sgarrison                        if (argv[i][2])
14712910Sgarrison                           p = &argv[i][2];
14812910Sgarrison                        else { /* take next arg */
14912910Sgarrison                           i++;
15012910Sgarrison                           p = argv[i];
15112910Sgarrison                           }
15212910Sgarrison                        incfile(p);
15312910Sgarrison                        break;
15412910Sgarrison 
15512910Sgarrison             case 'x':  capsmcap = true;
15612910Sgarrison                        break;
15712910Sgarrison 
15812910Sgarrison             case 0:    if (style) {  /* no style command given, take default */
15912910Sgarrison                           style = false;
16012910Sgarrison                           incfile( defstyle );
16112910Sgarrison                           }
162*13108Srrh 		       bibfname = "<stdin>";
16312910Sgarrison                        rdtext(stdin);
16412910Sgarrison                        numfiles++;
16512910Sgarrison                        break;
16612910Sgarrison 
16712910Sgarrison             default:   fputs(argv[i], stderr);
16812910Sgarrison                        error(": invalid switch");
16912910Sgarrison             }
17012910Sgarrison       else { /* file name */
17112910Sgarrison          numfiles++;
17212910Sgarrison          if (style) {
17312910Sgarrison             style = false;
17412910Sgarrison             incfile( defstyle );
17512910Sgarrison             }
17612910Sgarrison          fd = fopen(argv[i], "r");
17712910Sgarrison          if (fd == NULL) {
17812910Sgarrison             fputs(argv[i], stderr);
17912910Sgarrison             error(": can't open");
18012910Sgarrison             }
18112910Sgarrison          else {
182*13108Srrh             bibfname = argv[i];
18312910Sgarrison             rdtext(fd);
18412910Sgarrison             fclose(fd);
18512910Sgarrison             }
18612910Sgarrison          }
18712910Sgarrison 
18812910Sgarrison    if (style) incfile( defstyle );
18912910Sgarrison    return(numfiles);
19012910Sgarrison 
19112910Sgarrison }
19212910Sgarrison 
19312910Sgarrison /* incfile - read in an included file  */
19412910Sgarrison incfile(np)
19512910Sgarrison    char *np;
19612910Sgarrison {  char name[120];
19712910Sgarrison    FILE *fd;
19812910Sgarrison 
19912910Sgarrison    fd = fopen(np, "r");
20012910Sgarrison    if (fd == NULL && *np != '/') {
20112910Sgarrison       strcpy(name, "bib.");
20212910Sgarrison       strcat(name, np);
20312910Sgarrison       fd = fopen(name, "r");
20412910Sgarrison       }
20512910Sgarrison    if (fd == NULL && *np != '/') {
20612910Sgarrison       strcpy(name,BMACLIB);
20712910Sgarrison       strcat(name, "/bib.");
20812910Sgarrison       strcat(name, np);
20912910Sgarrison       fd = fopen(name, "r");
21012910Sgarrison       }
21112910Sgarrison    if (fd == NULL) {
21212910Sgarrison       fprintf(stderr,"%s", np);
21312910Sgarrison       error(": can't open");
21412910Sgarrison       }
21512910Sgarrison    setswitch(fd);
21612910Sgarrison    fclose(fd);
21712910Sgarrison }
21812910Sgarrison 
21912910Sgarrison /* error - report unrecoverable error message */
22012910Sgarrison   error(str)
22112910Sgarrison   char str[];
22212910Sgarrison {
22312910Sgarrison   fputs(str, stderr);
22412910Sgarrison   putc('\n', stderr);
22512910Sgarrison   exit(1);
22612910Sgarrison }
22712910Sgarrison 
22812910Sgarrison /* tfgets - fgets which trims off newline */
22912910Sgarrison    char *tfgets(line, n, ptr)
23012910Sgarrison    char line[];
23112910Sgarrison    int  n;
23212910Sgarrison    FILE *ptr;
23312910Sgarrison {  char *p;
23412910Sgarrison 
23512910Sgarrison    p = fgets(line, n, ptr);
23612910Sgarrison    if (p == NULL)
23712910Sgarrison       return(NULL);
23812910Sgarrison    else
23912910Sgarrison       for (p = line; *p; p++)
24012910Sgarrison          if (*p == '\n')
24112910Sgarrison             *p = 0;
24212910Sgarrison    return(line);
24312910Sgarrison }
24412910Sgarrison 
24512910Sgarrison /* getwrd - place next word from in[i] into out */
24612910Sgarrison int getwrd(in, i, out)
24712910Sgarrison    char in[], out[];
24812910Sgarrison    int i;
24912910Sgarrison {  int j;
25012910Sgarrison 
25112910Sgarrison    j = 0;
25212910Sgarrison    while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
25312910Sgarrison       i++;
25412910Sgarrison    if (in[i])
25512910Sgarrison       while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
25612910Sgarrison          out[j++] = in[i++];
25712910Sgarrison    else
25812910Sgarrison       i = 0;    /* signals end of in[i..]   */
25912910Sgarrison    out[j] = 0;
26012910Sgarrison    return (i);
26112910Sgarrison }
26212910Sgarrison 
26312910Sgarrison /* walloc - allocate enough space for a word */
26412910Sgarrison char *walloc(word)
26512910Sgarrison    char *word;
26612910Sgarrison {  char *i, *malloc();
26712910Sgarrison    i = malloc(1 + strlen(word));
26812910Sgarrison    if (i == NULL)
26912910Sgarrison       error("out of storage");
27012910Sgarrison    strcpy(i, word);
27112910Sgarrison    return(i);
27212910Sgarrison }
27312910Sgarrison 
27412910Sgarrison /* setswitch - set document switch settings from format file */
27512910Sgarrison    setswitch(fp)
27612910Sgarrison    FILE *fp;
27712910Sgarrison {  char *p, line[LINELENGTH], dline[LINELENGTH], word[80];
27812910Sgarrison    int  i, j, getwrd();
27912910Sgarrison 
28012910Sgarrison    while (tfgets(line, LINELENGTH, fp) != NULL)
28112910Sgarrison       switch(line[0]) {
28212910Sgarrison 
28312910Sgarrison          case '#': break;
28412910Sgarrison 
28512961Sgarrison          case 'A': for (p = &line[1]; *p; p++)
28612961Sgarrison                       if (*p == 'A')
28712961Sgarrison                          abbrev = true;
28812961Sgarrison                       else if (*p == 'X')
28912961Sgarrison                          capsmcap = true;
29012961Sgarrison                       else if (*p == 'R') {
29112961Sgarrison                          if (*(p+1))
29212961Sgarrison                             numrev = atoi(p+1);
29312961Sgarrison                          else
29412961Sgarrison                             numrev = 1000;
29512961Sgarrison                          break;
29612961Sgarrison                          }
29712910Sgarrison                    break;
29812910Sgarrison 
29912910Sgarrison          case 'C': for (p = &line[1]; *p == ' '; p++) ;
30012910Sgarrison                    strcpy(citetemplate, p);
30112910Sgarrison                    break;
30212910Sgarrison 
30312910Sgarrison          case 'D': if ((i = getwrd(line, 1, word)) == 0)
30412910Sgarrison                       error("word expected in definition");
30512910Sgarrison                    for (j = 0; j <= wordtop; j++)
30612910Sgarrison                       if (strcmp(word, words[j]) == 0)
30712910Sgarrison                          break;
30812910Sgarrison                    if (j > wordtop) {
30912910Sgarrison                       if ((j = ++wordtop) > MAXDEFS)
31012910Sgarrison                          error("too many defintions");
31112910Sgarrison                       words[wordtop] = walloc(word);
31212910Sgarrison                       }
31312910Sgarrison                    for (p = &line[i]; *p == ' '; p++) ;
31412910Sgarrison                    for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
31512910Sgarrison                        dline[strlen(dline)-1] = '\n';
31612910Sgarrison                        if (tfgets(line, LINELENGTH, fp) == NULL) break;
31712910Sgarrison                        strcat(dline, line);
31812910Sgarrison                        }
31912910Sgarrison                    defs[j] = walloc(dline);
32012910Sgarrison                    break;
32112910Sgarrison 
32212910Sgarrison          case 'E': for (p = &line[1]; *p; p++)
32312910Sgarrison                       if (*p == 'A')
32412910Sgarrison                          edabbrev = true;
32512910Sgarrison                       else if (*p == 'X')
32612910Sgarrison                          edcapsmcap = true;
32712910Sgarrison                       else if (*p == 'R') {
32812910Sgarrison                          if (*(p+1))
32912910Sgarrison                             ednumrev = atoi(p+1);
33012910Sgarrison                          else
33112910Sgarrison                             ednumrev = 1000;
33212910Sgarrison                          break;
33312910Sgarrison                          }
33412910Sgarrison                    break;
33512910Sgarrison 
33612910Sgarrison          case 'F': foot = true;
33712910Sgarrison                    hyphen = false;
33812910Sgarrison                    break;
33912910Sgarrison 
34012910Sgarrison          case 'I': for (p = &line[1]; *p == ' '; p++);
34112910Sgarrison                    expand(p);
34212910Sgarrison                    incfile(p);
34312910Sgarrison                    break;
34412910Sgarrison 
34512910Sgarrison          case 'H': hyphen = ordcite = true;
34612910Sgarrison                    break;
34712910Sgarrison 
34812910Sgarrison          case 'O': ordcite = true;
34912910Sgarrison                    break;
35012910Sgarrison 
35112910Sgarrison          case 'R': if (line[1] == 0)
35212910Sgarrison                       numrev = 1000;
35312910Sgarrison                    else
35412910Sgarrison                       numrev = atoi(&line[1]);
35512910Sgarrison                    break;
35612910Sgarrison 
35712910Sgarrison          case 'S': sort = true;
35812910Sgarrison                    for (p = &line[1]; *p == ' '; p++) ;
35912910Sgarrison                    strcpy(sortstr, p);
36012910Sgarrison                    break;
36112910Sgarrison 
36212910Sgarrison          case 'T': for (p = &line[1]; *p == ' '; p++) ;
36312910Sgarrison                    strcpy(trailstr, p);
36412910Sgarrison                    break;
36512910Sgarrison 
36612910Sgarrison          case 'X': capsmcap = true;
36712910Sgarrison                    break;
36812910Sgarrison 
36912910Sgarrison          default:  fprintf(tfd,"%s\n",line);
37012910Sgarrison                    while (fgets(line, LINELENGTH, fp) != NULL)
37112910Sgarrison                       fputs(line, tfd);
37212910Sgarrison                    return;
37312910Sgarrison          }
37412910Sgarrison    return;
37512910Sgarrison }
37612910Sgarrison 
37712910Sgarrison /* isword - see if character is legit word char */
37812910Sgarrison int iswordc(c)
37912910Sgarrison char c;
38012910Sgarrison {
38112910Sgarrison    if (isalnum(c) || c == '&' || c == '_')
38212910Sgarrison       return(true);
38312910Sgarrison    return(false);
38412910Sgarrison }
38512910Sgarrison 
38612910Sgarrison /* expand - expand reference, replacing defined words */
38712910Sgarrison    expand(line)
38812910Sgarrison    char *line;
38912910Sgarrison {  char line2[REFSIZE], word[LINELENGTH], *p, *q, *w;
39012910Sgarrison    int  replaced, i;
39112910Sgarrison 
39212910Sgarrison    replaced  = true;
39312910Sgarrison    while (replaced) {
39412910Sgarrison       replaced = false;
39512910Sgarrison       p = line;
39612910Sgarrison       q = line2;
39712910Sgarrison       while (*p) {
39812910Sgarrison          if (isalnum(*p)) {
39912910Sgarrison             for (w = word; *p && iswordc(*p); )
40012910Sgarrison                *w++ = *p++;
40112910Sgarrison             *w = 0;
40212910Sgarrison             for (i = 0; i <= wordtop; i++)
40312910Sgarrison                if (strcmp(word, words[i]) == 0) {
40412910Sgarrison                   strcpy(word, defs[i]);
40512910Sgarrison                   replaced = true;
40612910Sgarrison                   break;
40712910Sgarrison                   }
40812910Sgarrison             for (w = word; *w; )
40912910Sgarrison                *q++ = *w++;
41012910Sgarrison             }
41112910Sgarrison          else
41212910Sgarrison             *q++ = *p++;
41312910Sgarrison          }
41412910Sgarrison       *q = 0;
41512910Sgarrison       p = line;
41612910Sgarrison       q = line2;
41712910Sgarrison       while (*p++ = *q++);
41812910Sgarrison       }
41912910Sgarrison }
42012910Sgarrison 
42112910Sgarrison /* breakname - break a name into first and last name */
42212910Sgarrison    breakname(line, first, last)
42312910Sgarrison    char line[], first[], last[];
42412910Sgarrison {  char *p, *q, *r, *t, *f;
42512910Sgarrison 
42612910Sgarrison    for (t = line; *t != '\n'; t++);
42712910Sgarrison    for (t--; isspace(*t); t--);
42812910Sgarrison 
42912910Sgarrison    /* now strip off last name */
43012910Sgarrison    for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
43112910Sgarrison       if (q == line)
43212910Sgarrison          break;
43312910Sgarrison    f = q;
43412910Sgarrison    if (q != line)
43512910Sgarrison       q++;
43612910Sgarrison 
43712910Sgarrison    for (; isspace(*f); f--);
43812910Sgarrison 
43912910Sgarrison    /* first name is start to f, last name is q to t */
44012910Sgarrison 
44112910Sgarrison    for (r = first, p = line, f++; p != f; )
44212910Sgarrison       *r++ = *p++;
44312910Sgarrison    *r = 0;
44412910Sgarrison    for (r = last, p = q, t++; q != t; )
44512910Sgarrison       *r++ = *q++;
44612910Sgarrison    *r = 0;
44712910Sgarrison }
44812910Sgarrison 
44912910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
45012910Sgarrison    int match(str1, str2)
45112910Sgarrison    char str1[], str2[];
45212910Sgarrison {  int  i, j;
45312910Sgarrison    char a, b;
45412910Sgarrison 
45512910Sgarrison    for (i = 0; str2[i]; i++) {
45612910Sgarrison       for (j = 0; str1[j]; j++) {
45712910Sgarrison          if (isupper(a = str2[i+j]))
45812910Sgarrison             a = (a - 'A') + 'a';
45912910Sgarrison          if (isupper(b = str1[j]))
46012910Sgarrison             b = (b - 'A') + 'a';
46112910Sgarrison          if (a != b)
46212910Sgarrison             break;
46312910Sgarrison          }
46412910Sgarrison       if (str1[j] == 0)
46512910Sgarrison          return(true);
46612910Sgarrison       }
46712910Sgarrison    return(false);
46812910Sgarrison }
46912910Sgarrison 
47012910Sgarrison /* scopy - append a copy of one string to another */
47112910Sgarrison    char *scopy(p, q)
47212910Sgarrison    char *p, *q;
47312910Sgarrison {
47412910Sgarrison    while (*p++ = *q++)
47512910Sgarrison       ;
47612910Sgarrison    return(--p);
47712910Sgarrison }
47812910Sgarrison 
47912910Sgarrison /* bldname - build a name field
48012910Sgarrison              doing abbreviations, reversals, and caps/small caps
48112910Sgarrison */
48212910Sgarrison    bldname(first, last, name, reverse)
48312910Sgarrison    char *first, *last, name[];
48412910Sgarrison    int reverse;
48512910Sgarrison {
48612910Sgarrison    char newfirst[120], newlast[120], *p, *q, *f, *l, *scopy();
48712910Sgarrison    int  flag;
48812910Sgarrison 
48912910Sgarrison    if (abbrev) {
49012910Sgarrison       p = first;
49112910Sgarrison       q = newfirst;
49212910Sgarrison       flag = false;
49312910Sgarrison       while (*p) {
49412910Sgarrison          while (*p == ' ')
49512910Sgarrison             p++;
49612910Sgarrison          if (*p == 0)
49712910Sgarrison             break;
49812910Sgarrison          if (isupper(*p)) {
49912910Sgarrison             if (flag)
50012910Sgarrison                q = scopy(q, "\\*(a]");
50112910Sgarrison             flag = true;
50212910Sgarrison             *q++ = *p;
50312910Sgarrison             *q++ = '.';
50412910Sgarrison             }
50512910Sgarrison          if (*++p == '.')
50612910Sgarrison             p++;
50712910Sgarrison          else while (*p != 0 && ! isspace(*p))
50812910Sgarrison             p++;
50912910Sgarrison          }
51012910Sgarrison       *q = 0;
51112910Sgarrison       f = newfirst;
51212910Sgarrison       }
51312910Sgarrison    else
51412910Sgarrison       f = first;
51512910Sgarrison 
51612910Sgarrison    if (capsmcap) {
51712910Sgarrison       p = last;
51812910Sgarrison       q = newlast;
51912910Sgarrison       flag = 0;  /* 1 - printing cap, 2 - printing small */
52012910Sgarrison       while (*p)
52112910Sgarrison          if (islower(*p)) {
52212910Sgarrison             if (flag != 2)
52312910Sgarrison                q = scopy(q, "\\s-2");
52412910Sgarrison             flag = 2;
52512910Sgarrison             *q++ = (*p++ - 'a') + 'A';
52612910Sgarrison             }
52712910Sgarrison          else {
52812910Sgarrison             if (flag == 2)
52912910Sgarrison                q = scopy(q,"\\s+2");
53012910Sgarrison             flag = 1;
53112910Sgarrison             *q++ = *p++;
53212910Sgarrison             }
53312910Sgarrison       if (flag == 2)
53412910Sgarrison          q = scopy(q, "\\s+2");
53512910Sgarrison       *q = 0;
53612910Sgarrison       l = newlast;
53712910Sgarrison       }
53812910Sgarrison    else
53912910Sgarrison       l = last;
54012910Sgarrison 
54112910Sgarrison    if (reverse)
54212910Sgarrison       sprintf(name, "%s, %s\n", l, f);
54312910Sgarrison    else
54412910Sgarrison       sprintf(name, "%s %s\n", f, l);
54512910Sgarrison }
54612910Sgarrison 
54712910Sgarrison /* prtauth - print author or editor field */
54812910Sgarrison    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
54912910Sgarrison    char c, *line;
55012910Sgarrison    int  num, max, abbrev, capsmcap, numrev;
55112910Sgarrison    FILE *ofd;
55212910Sgarrison {  char first[LINELENGTH], last[LINELENGTH];
55312910Sgarrison 
55412910Sgarrison    if (num <= numrev || abbrev || capsmcap) {
55512910Sgarrison       breakname(line, first, last);
55612910Sgarrison       bldname(first, last, line, num <= numrev);
55712910Sgarrison       }
55812910Sgarrison    if (num == 1)
55912910Sgarrison       fprintf(ofd,".ds [%c %s", c, line);
56012910Sgarrison    else if (num < max)
56112910Sgarrison       fprintf(ofd,".as [%c \\*(c]%s", c, line);
56212910Sgarrison    else if (max == 2)
56312910Sgarrison       fprintf(ofd,".as [%c \\*(n]%s", c, line);
56412910Sgarrison    else
56512910Sgarrison       fprintf(ofd,".as [%c \\*(m]%s", c, line);
56612910Sgarrison    if (num == max && index(trailstr, c))
56712910Sgarrison       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
56812910Sgarrison }
56912910Sgarrison 
57012910Sgarrison /* doline - actually print out a line of reference information */
57112910Sgarrison    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
57212910Sgarrison    char c, *line;
57312910Sgarrison    int numauths, maxauths, numeds, maxeds;
57412910Sgarrison    FILE *ofd;
57512910Sgarrison {
57612910Sgarrison 
57712910Sgarrison    switch(c) {
57812910Sgarrison       case 'A':
57912910Sgarrison           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
58012910Sgarrison           break;
58112910Sgarrison 
58212910Sgarrison        case 'E':
58312910Sgarrison           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
58412910Sgarrison           if (numeds == maxeds)
58512910Sgarrison              fprintf(ofd,".nr [E %d\n", maxeds);
58612910Sgarrison           break;
58712910Sgarrison 
58812910Sgarrison        case 'P':
58912910Sgarrison           if (index(line, '-'))
59012910Sgarrison              fprintf(ofd,".nr [P 1\n");
59112910Sgarrison           else
59212910Sgarrison              fprintf(ofd,".nr [P 0\n");
59312910Sgarrison           fprintf(ofd,".ds [P %s",line);
59412910Sgarrison           if (index(trailstr, 'P'))
59512910Sgarrison              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
59612910Sgarrison           break;
59712910Sgarrison 
59812910Sgarrison        case 'F':
59912910Sgarrison        case 'K': break;
60012910Sgarrison 
60112910Sgarrison        default:
60212910Sgarrison           fprintf(ofd,".ds [%c %s", c, line);
60312910Sgarrison           if (index(trailstr, c))
60412910Sgarrison              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
60512910Sgarrison           }
60612910Sgarrison }
60712910Sgarrison 
608