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