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