1*12909Sgarrison /* 2*12909Sgarrison bib - bibliographic formatter 3*12909Sgarrison timothy a. budd, 1/82 4*12909Sgarrison lookup routines supplied by gary levin 2/82 5*12909Sgarrison reworked several new features added, 11/82. 6*12909Sgarrison */ 7*12909Sgarrison # include <stdio.h> 8*12909Sgarrison # include <ctype.h> 9*12909Sgarrison # include "bib.h" 10*12909Sgarrison 11*12909Sgarrison # define HUNTSIZE 512 /* maximum size of hunt string */ 12*12909Sgarrison # define MAXFIELD 250 /* maximum field length */ 13*12909Sgarrison # define MAXREFS 300 /* maximum number of references */ 14*12909Sgarrison # define MAXATONCE 35 /* maximum references at one location */ 15*12909Sgarrison 16*12909Sgarrison # define getch(c,fd) (c = getc(fd)) 17*12909Sgarrison # define echoc(c,ifd,ofd) (getch(c,ifd) == EOF ? c : putc(c,ofd)) 18*12909Sgarrison # define testc(c,d,ifd,ofd) (getch(c, ifd) == d ? putc(c, ofd) : 0) 19*12909Sgarrison 20*12909Sgarrison /* global variables */ 21*12909Sgarrison FILE *rfd; /* reference temporary file */ 22*12909Sgarrison char reffile[] = TMPREFFILE ;/* temporary file (see bib.h) */ 23*12909Sgarrison long int refspos[MAXREFS]; /* reference seek positions */ 24*12909Sgarrison long int rend = 1; /* last position in rfd (first char unused)*/ 25*12909Sgarrison int numrefs = -1; /* number of references generated so far */ 26*12909Sgarrison FILE *tfd; /* output of pass 1 of file(s) */ 27*12909Sgarrison char tmpfile[] = TMPTEXTFILE ; /* output of pass 1 */ 28*12909Sgarrison char common[] = COMFILE ; /* common word file */ 29*12909Sgarrison char *citestr[MAXREFS]; /* citation strings */ 30*12909Sgarrison int findex = false; /* can we read the file INDEX ? */ 31*12909Sgarrison 32*12909Sgarrison /* global variables in bibargs */ 33*12909Sgarrison extern int foot, sort, personal; 34*12909Sgarrison extern int hyphen, ordcite; 35*12909Sgarrison extern char sortstr[], pfile[], citetemplate[]; 36*12909Sgarrison 37*12909Sgarrison 38*12909Sgarrison main(argc, argv) 39*12909Sgarrison int argc; 40*12909Sgarrison char **argv; 41*12909Sgarrison { int rcomp(); 42*12909Sgarrison 43*12909Sgarrison /* the file INDEX in the current directory is the default index, 44*12909Sgarrison if it is present */ 45*12909Sgarrison 46*12909Sgarrison rfd = fopen( INDXFILE , "r"); 47*12909Sgarrison if (rfd != NULL) { 48*12909Sgarrison findex = true; 49*12909Sgarrison fclose(rfd); 50*12909Sgarrison } 51*12909Sgarrison 52*12909Sgarrison /* open temporaries, reffile will contain references collected in 53*12909Sgarrison pass 1, and tmpfile will contain text. 54*12909Sgarrison */ 55*12909Sgarrison mktemp(reffile); 56*12909Sgarrison rfd = fopen(reffile,"w+"); 57*12909Sgarrison if (rfd == NULL) 58*12909Sgarrison error("can't open temporary reference file"); 59*12909Sgarrison mktemp(tmpfile); 60*12909Sgarrison tfd = fopen(tmpfile,"w"); 61*12909Sgarrison if (tfd == NULL) 62*12909Sgarrison error("can't open temporary output file"); 63*12909Sgarrison 64*12909Sgarrison /* 65*12909Sgarrison pass1 - read files, looking for citations 66*12909Sgarrison arguments are read by doargs (bibargs.c) 67*12909Sgarrison */ 68*12909Sgarrison 69*12909Sgarrison if (doargs(argc, argv, DEFSTYLE ) == 0) 70*12909Sgarrison rdtext(stdin); 71*12909Sgarrison 72*12909Sgarrison /* 73*12909Sgarrison sort references, make citations, add disambiguating characters 74*12909Sgarrison */ 75*12909Sgarrison 76*12909Sgarrison if (sort) 77*12909Sgarrison qsort(refspos, numrefs+1, sizeof(long), rcomp); 78*12909Sgarrison makecites(citestr); 79*12909Sgarrison disambiguate(); 80*12909Sgarrison 81*12909Sgarrison /* 82*12909Sgarrison reopen temporaries 83*12909Sgarrison */ 84*12909Sgarrison 85*12909Sgarrison fclose(tfd); 86*12909Sgarrison tfd = fopen(tmpfile,"r"); 87*12909Sgarrison if (tfd == NULL) 88*12909Sgarrison error("can't open temporary output file for reading"); 89*12909Sgarrison 90*12909Sgarrison /* 91*12909Sgarrison pass 2 - reread files, replacing references 92*12909Sgarrison */ 93*12909Sgarrison 94*12909Sgarrison pass2(tfd, stdout); 95*12909Sgarrison 96*12909Sgarrison /* 97*12909Sgarrison clean up 98*12909Sgarrison */ 99*12909Sgarrison 100*12909Sgarrison fclose(tfd); 101*12909Sgarrison fclose(rfd); 102*12909Sgarrison unlink(tmpfile); 103*12909Sgarrison unlink(reffile); 104*12909Sgarrison exit(0); 105*12909Sgarrison } 106*12909Sgarrison 107*12909Sgarrison /* rdtext - read and process a text file, looking for [. commands */ 108*12909Sgarrison rdtext(fd) 109*12909Sgarrison FILE *fd; 110*12909Sgarrison { char lastc, c, d; 111*12909Sgarrison 112*12909Sgarrison lastc = 0; 113*12909Sgarrison while (getch(c, fd) != EOF) 114*12909Sgarrison if (c == '[' || c == '{') 115*12909Sgarrison if (getch(d, fd) == '.') { /* found a reference */ 116*12909Sgarrison if (c == '{') { if (lastc) putc(lastc, tfd);} 117*12909Sgarrison else 118*12909Sgarrison if (lastc == ' ') fputs("\\*([<", tfd); 119*12909Sgarrison else if (lastc == '.') fputs("\\*([.", tfd); 120*12909Sgarrison else if (lastc == ',') fputs("\\*([,", tfd); 121*12909Sgarrison else if (lastc) putc(lastc, tfd); 122*12909Sgarrison rdcite(fd, c); 123*12909Sgarrison if (c == '[') 124*12909Sgarrison if (lastc == ' ') fputs("\\*(>]", tfd); 125*12909Sgarrison else if (lastc == '.') fputs("\\*(.]", tfd); 126*12909Sgarrison else if (lastc == ',') fputs("\\*(,]", tfd); 127*12909Sgarrison lastc = 0; 128*12909Sgarrison } 129*12909Sgarrison else { 130*12909Sgarrison if (lastc) putc(lastc, tfd); 131*12909Sgarrison ungetc(d, fd); 132*12909Sgarrison lastc = c; 133*12909Sgarrison } 134*12909Sgarrison else { 135*12909Sgarrison if (lastc) putc(lastc, tfd); 136*12909Sgarrison lastc = c; 137*12909Sgarrison } 138*12909Sgarrison if (lastc) putc(lastc, tfd); 139*12909Sgarrison } 140*12909Sgarrison 141*12909Sgarrison /* rdcite - read citation information inside a [. command */ 142*12909Sgarrison rdcite(fd, ch) 143*12909Sgarrison FILE *fd; 144*12909Sgarrison char ch; 145*12909Sgarrison { long int n, getref(); 146*12909Sgarrison char huntstr[HUNTSIZE], c, info[HUNTSIZE]; 147*12909Sgarrison 148*12909Sgarrison if (ch == '[') 149*12909Sgarrison fputs("\\*([[", tfd); 150*12909Sgarrison else 151*12909Sgarrison fputs("\\*([{", tfd); 152*12909Sgarrison huntstr[0] = info[0] = 0; 153*12909Sgarrison while (getch(c, fd) != EOF) 154*12909Sgarrison switch (c) { 155*12909Sgarrison case ',': 156*12909Sgarrison n = getref(huntstr); 157*12909Sgarrison if (n > 0) 158*12909Sgarrison fprintf(tfd, "%c%ld%c%s%c", CITEMARK, n, CITEMARK, info, CITEEND); 159*12909Sgarrison else 160*12909Sgarrison fprintf(tfd, "%c0%c%s%s%c", CITEMARK, CITEMARK, 161*12909Sgarrison huntstr, info, CITEEND); 162*12909Sgarrison huntstr[0] = info[0] = 0; 163*12909Sgarrison break; 164*12909Sgarrison 165*12909Sgarrison case '.': 166*12909Sgarrison while (getch(c, fd) == '.') ; 167*12909Sgarrison if (c == ']') { 168*12909Sgarrison n = getref(huntstr); 169*12909Sgarrison if (n > 0) 170*12909Sgarrison fprintf(tfd, "%c%ld%c%s%c\\*(]]", CITEMARK, n, 171*12909Sgarrison CITEMARK, info, CITEEND); 172*12909Sgarrison else 173*12909Sgarrison fprintf(tfd, "%c0%c%s%s%c\\*(]]", CITEMARK, CITEMARK, 174*12909Sgarrison huntstr, info, CITEEND); 175*12909Sgarrison return; 176*12909Sgarrison } 177*12909Sgarrison else if (c == '}') { 178*12909Sgarrison n = getref(huntstr); 179*12909Sgarrison if (n > 0) 180*12909Sgarrison fprintf(tfd, "%c%ld%c%s%c\\*(}]", CITEMARK, n, 181*12909Sgarrison CITEMARK, info, CITEEND); 182*12909Sgarrison else 183*12909Sgarrison fprintf(tfd, "%c0%c%s%s%c\\*(}]", CITEMARK, CITEMARK, 184*12909Sgarrison huntstr, info, CITEEND); 185*12909Sgarrison return; 186*12909Sgarrison } 187*12909Sgarrison else 188*12909Sgarrison addc(huntstr, c); 189*12909Sgarrison break; 190*12909Sgarrison 191*12909Sgarrison case '{': 192*12909Sgarrison while (getch(c, fd) != '}') 193*12909Sgarrison if (c == EOF) { 194*12909Sgarrison fprintf(stderr, "Error: ill formed reference\n"); 195*12909Sgarrison exit(1); 196*12909Sgarrison } 197*12909Sgarrison else 198*12909Sgarrison addc(info, c); 199*12909Sgarrison break; 200*12909Sgarrison 201*12909Sgarrison case '\n': 202*12909Sgarrison case '\t': 203*12909Sgarrison c = ' '; /* fall through */ 204*12909Sgarrison 205*12909Sgarrison default: 206*12909Sgarrison addc(huntstr,c); 207*12909Sgarrison } 208*12909Sgarrison error("end of file reading citation"); 209*12909Sgarrison } 210*12909Sgarrison 211*12909Sgarrison /* addc - add a character to hunt string */ 212*12909Sgarrison addc(huntstr, c) 213*12909Sgarrison char huntstr[HUNTSIZE], c; 214*12909Sgarrison { int i; 215*12909Sgarrison 216*12909Sgarrison i = strlen(huntstr); 217*12909Sgarrison if (i > HUNTSIZE) 218*12909Sgarrison error("citation too long"); 219*12909Sgarrison huntstr[i] = c; 220*12909Sgarrison huntstr[i+1] = 0; 221*12909Sgarrison } 222*12909Sgarrison 223*12909Sgarrison /* getref - if an item was already referenced, return its pointer in 224*12909Sgarrison the reference file, otherwise create a new entry */ 225*12909Sgarrison long int getref(huntstr) 226*12909Sgarrison char huntstr[HUNTSIZE]; 227*12909Sgarrison { char rf[REFSIZE], ref[REFSIZE], *r, *hunt(); 228*12909Sgarrison int i, match(), getwrd(); 229*12909Sgarrison 230*12909Sgarrison r = hunt(huntstr); 231*12909Sgarrison if (r != NULL) { 232*12909Sgarrison /* exapand defined string */ 233*12909Sgarrison strcpy(rf, r); 234*12909Sgarrison free(r); 235*12909Sgarrison expand(rf); 236*12909Sgarrison 237*12909Sgarrison /* see if reference has already been cited */ 238*12909Sgarrison 239*12909Sgarrison if (foot == false) 240*12909Sgarrison for (i = 0; i <= numrefs; i++) { 241*12909Sgarrison rdref(refspos[i], ref); 242*12909Sgarrison if (strcmp(ref, rf) == 0) 243*12909Sgarrison return(refspos[i]); 244*12909Sgarrison } 245*12909Sgarrison 246*12909Sgarrison /* didn't match any existing reference, create new one */ 247*12909Sgarrison 248*12909Sgarrison numrefs++; 249*12909Sgarrison refspos[numrefs] = rend; 250*12909Sgarrison fseek(rfd, rend, 0); 251*12909Sgarrison i = strlen(rf) + 1; 252*12909Sgarrison fwrite(rf, 1, i, rfd); 253*12909Sgarrison rend = rend + i; 254*12909Sgarrison return(refspos[numrefs]); 255*12909Sgarrison } 256*12909Sgarrison else { 257*12909Sgarrison fprintf(stderr,"no reference matching %s\n", huntstr); 258*12909Sgarrison return( (long) -1 ); 259*12909Sgarrison } 260*12909Sgarrison } 261*12909Sgarrison 262*12909Sgarrison /* rdref - read text for an already cited reference */ 263*12909Sgarrison rdref(i, ref) 264*12909Sgarrison long int i; 265*12909Sgarrison char ref[REFSIZE]; 266*12909Sgarrison { 267*12909Sgarrison ref[0] = 0; 268*12909Sgarrison fseek(rfd, i, 0); 269*12909Sgarrison fread(ref, 1, REFSIZE, rfd); 270*12909Sgarrison } 271*12909Sgarrison 272*12909Sgarrison /* hunt - hunt for reference from either personal or system index */ 273*12909Sgarrison char *hunt(huntstr) 274*12909Sgarrison char huntstr[]; 275*12909Sgarrison { char *fhunt(), *r, *p, *q, fname[120]; 276*12909Sgarrison 277*12909Sgarrison if (personal) { 278*12909Sgarrison for (p = fname, q = pfile; ; q++) 279*12909Sgarrison if (*q == ',' || *q == 0) { 280*12909Sgarrison *p = 0; 281*12909Sgarrison if ((r = fhunt(fname, huntstr)) != NULL) 282*12909Sgarrison return(r); 283*12909Sgarrison else if (*q == 0) 284*12909Sgarrison break; 285*12909Sgarrison p = fname; 286*12909Sgarrison } 287*12909Sgarrison else *p++ = *q; 288*12909Sgarrison } 289*12909Sgarrison else if (findex) { 290*12909Sgarrison if ((r = fhunt( INDXFILE , huntstr)) != NULL) 291*12909Sgarrison return(r); 292*12909Sgarrison } 293*12909Sgarrison if ((r = fhunt(SYSINDEX , huntstr)) != NULL) 294*12909Sgarrison return(r); 295*12909Sgarrison return(NULL); 296*12909Sgarrison } 297*12909Sgarrison 298*12909Sgarrison /* fhunt - hunt from a specific file */ 299*12909Sgarrison char *fhunt(file, huntstr) 300*12909Sgarrison char file[], huntstr[]; 301*12909Sgarrison { char *p, *r, *locate(); 302*12909Sgarrison 303*12909Sgarrison r = locate(huntstr, file, 6, common); 304*12909Sgarrison 305*12909Sgarrison if (r == NULL) 306*12909Sgarrison return(NULL); /* error */ 307*12909Sgarrison if (*r == 0) 308*12909Sgarrison return(NULL); /* no match */ 309*12909Sgarrison 310*12909Sgarrison for (p = r; *p; p++) 311*12909Sgarrison if (*p == '\n') 312*12909Sgarrison if (*(p+1) == '\n') { /* end */ 313*12909Sgarrison if (*(p+2) != 0) 314*12909Sgarrison fprintf(stderr,"multiple references match %s\n",huntstr); 315*12909Sgarrison *(p+1) = 0; 316*12909Sgarrison break; 317*12909Sgarrison } 318*12909Sgarrison else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */ 319*12909Sgarrison *p = ' '; 320*12909Sgarrison return(r); 321*12909Sgarrison } 322*12909Sgarrison 323*12909Sgarrison /* rcomp - reference comparison routine for qsort utility */ 324*12909Sgarrison int rcomp(ap, bp) 325*12909Sgarrison long int *ap, *bp; 326*12909Sgarrison { char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD]; 327*12909Sgarrison char *p, *q, *getfield(); 328*12909Sgarrison int neg, res; 329*12909Sgarrison 330*12909Sgarrison rdref(*ap, ref1); 331*12909Sgarrison rdref(*bp, ref2); 332*12909Sgarrison for (p = sortstr; *p; p = q) { 333*12909Sgarrison if (*p == '-') { 334*12909Sgarrison p++; 335*12909Sgarrison neg = true; 336*12909Sgarrison } 337*12909Sgarrison else 338*12909Sgarrison neg = false; 339*12909Sgarrison q = getfield(p, field1, ref1); 340*12909Sgarrison if (q == 0) 341*12909Sgarrison res = 1; 342*12909Sgarrison else if (getfield(p, field2, ref2) == 0) 343*12909Sgarrison res = -1; 344*12909Sgarrison else { 345*12909Sgarrison if (*p == 'A') { 346*12909Sgarrison if (isupper(field1[0])) 347*12909Sgarrison field1[0] -= 'A' - 'a'; 348*12909Sgarrison if (isupper(field2[0])) 349*12909Sgarrison field2[0] -= 'A' - 'a'; 350*12909Sgarrison } 351*12909Sgarrison res = strcmp(field1, field2); 352*12909Sgarrison } 353*12909Sgarrison if (neg) 354*12909Sgarrison res = - res; 355*12909Sgarrison if (res != 0) 356*12909Sgarrison break; 357*12909Sgarrison } 358*12909Sgarrison if (res == 0) 359*12909Sgarrison if (ap < bp) 360*12909Sgarrison res = -1; 361*12909Sgarrison else 362*12909Sgarrison res = 1; 363*12909Sgarrison return(res); 364*12909Sgarrison } 365*12909Sgarrison 366*12909Sgarrison /* makecites - make citation strings */ 367*12909Sgarrison makecites(citestr) 368*12909Sgarrison char *citestr[]; 369*12909Sgarrison { char ref[REFSIZE], tempcite[100], *malloc(); 370*12909Sgarrison int i; 371*12909Sgarrison 372*12909Sgarrison for (i = 0; i <= numrefs; i++) { 373*12909Sgarrison rdref(refspos[i], ref); 374*12909Sgarrison bldcite(tempcite, i, ref); 375*12909Sgarrison citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */ 376*12909Sgarrison if (citestr[i] == NULL) 377*12909Sgarrison error("out of storage"); 378*12909Sgarrison strcpy(citestr[i], tempcite); 379*12909Sgarrison } 380*12909Sgarrison } 381*12909Sgarrison 382*12909Sgarrison /* bldcite - build a single citation string */ 383*12909Sgarrison bldcite(cp, i, ref) 384*12909Sgarrison char *cp, ref[]; 385*12909Sgarrison int i; 386*12909Sgarrison { char *p, *q, c, *fp, *np, field[REFSIZE], temp[100], *getfield(); 387*12909Sgarrison int j; 388*12909Sgarrison 389*12909Sgarrison getfield("F", field, ref); 390*12909Sgarrison if (field[0] != 0) 391*12909Sgarrison for (p = field; *p; p++) 392*12909Sgarrison *cp++ = *p; 393*12909Sgarrison else { 394*12909Sgarrison p = citetemplate; 395*12909Sgarrison field[0] = 0; 396*12909Sgarrison while (c = *p++) 397*12909Sgarrison if (isalpha(c)) { 398*12909Sgarrison q = getfield(p-1, field, ref); 399*12909Sgarrison if (q != 0) { 400*12909Sgarrison p = q; 401*12909Sgarrison for (fp = field; *fp; ) 402*12909Sgarrison *cp++ = *fp++; 403*12909Sgarrison } 404*12909Sgarrison } 405*12909Sgarrison else if (c == '1') { 406*12909Sgarrison sprintf(field,"%d",1 + i); 407*12909Sgarrison for (fp = field; *fp; ) 408*12909Sgarrison *cp++ = *fp++; 409*12909Sgarrison } 410*12909Sgarrison else if (c == '2') { 411*12909Sgarrison if (getname(1, field, temp, ref)) { 412*12909Sgarrison np = cp; 413*12909Sgarrison fp = field; 414*12909Sgarrison for (j = 1; j <= 3; j++) 415*12909Sgarrison if (*fp != 0) 416*12909Sgarrison *cp++ = *fp++; 417*12909Sgarrison if (getname(2, field, temp, ref)) 418*12909Sgarrison np[2] = field[0]; 419*12909Sgarrison if (getname(3, field, temp, ref)) { 420*12909Sgarrison np[1] = np[2]; 421*12909Sgarrison np[2] = field[0]; 422*12909Sgarrison } 423*12909Sgarrison } 424*12909Sgarrison } 425*12909Sgarrison else if (c == '{') { 426*12909Sgarrison while (*p ^= '}') 427*12909Sgarrison if (*p == 0) 428*12909Sgarrison error("unexpected end of citation template"); 429*12909Sgarrison else 430*12909Sgarrison *cp++ = *p++; 431*12909Sgarrison p++; 432*12909Sgarrison } 433*12909Sgarrison else if (c == '<') { 434*12909Sgarrison while (*p ^= '>') 435*12909Sgarrison if (*p == 0) 436*12909Sgarrison error("unexpected end of citation template"); 437*12909Sgarrison else 438*12909Sgarrison *cp++ = *p++; 439*12909Sgarrison p++; 440*12909Sgarrison } 441*12909Sgarrison else if (c != '@') 442*12909Sgarrison *cp++ = c; 443*12909Sgarrison } 444*12909Sgarrison *cp++ = 0; 445*12909Sgarrison } 446*12909Sgarrison 447*12909Sgarrison /* getfield - get a single field from reference */ 448*12909Sgarrison char *getfield(ptr, field, ref) 449*12909Sgarrison char *ptr, field[], ref[]; 450*12909Sgarrison { char *p, *q, temp[100]; 451*12909Sgarrison int n, len, i, getname(); 452*12909Sgarrison 453*12909Sgarrison field[0] = 0; 454*12909Sgarrison if (*ptr == 'A') 455*12909Sgarrison getname(1, field, temp, ref); 456*12909Sgarrison else 457*12909Sgarrison for (p = ref; *p; p++) 458*12909Sgarrison if (*p == '%' && *(p+1) == *ptr) { 459*12909Sgarrison for (p = p + 2; *p == ' '; p++) 460*12909Sgarrison ; 461*12909Sgarrison for (q = field; *p != '\n'; ) 462*12909Sgarrison *q++ = *p++; 463*12909Sgarrison *q = 0; 464*12909Sgarrison break; 465*12909Sgarrison } 466*12909Sgarrison n = 0; 467*12909Sgarrison len = strlen(field); 468*12909Sgarrison if (*++ptr == '-') { 469*12909Sgarrison for (ptr++; isdigit(*ptr); ptr++) 470*12909Sgarrison n = 10 * n + (*ptr - '0'); 471*12909Sgarrison if (n > len) 472*12909Sgarrison n = 0; 473*12909Sgarrison else 474*12909Sgarrison n = len - n; 475*12909Sgarrison for (i = 0; field[i] = field[i+n]; i++) 476*12909Sgarrison ; 477*12909Sgarrison } 478*12909Sgarrison else if (isdigit(*ptr)) { 479*12909Sgarrison for (; isdigit(*ptr); ptr++) 480*12909Sgarrison n = 10 * n + (*ptr - '0'); 481*12909Sgarrison if (n > len) 482*12909Sgarrison n = len; 483*12909Sgarrison field[n] = 0; 484*12909Sgarrison } 485*12909Sgarrison 486*12909Sgarrison if (*ptr == 'u') { 487*12909Sgarrison ptr++; 488*12909Sgarrison for (p = field; *p; p++) 489*12909Sgarrison if (islower(*p)) 490*12909Sgarrison *p = (*p - 'a') + 'A'; 491*12909Sgarrison } 492*12909Sgarrison else if (*ptr == 'l') { 493*12909Sgarrison ptr++; 494*12909Sgarrison for (p = field; *p; p++) 495*12909Sgarrison if (isupper(*p)) 496*12909Sgarrison *p = (*p - 'A') + 'a'; 497*12909Sgarrison } 498*12909Sgarrison return(ptr); 499*12909Sgarrison } 500*12909Sgarrison 501*12909Sgarrison /* getname - get the nth name field from reference, breaking into 502*12909Sgarrison first and last names */ 503*12909Sgarrison int getname(n, last, first, ref) 504*12909Sgarrison int n; 505*12909Sgarrison char last[], first[], ref[]; 506*12909Sgarrison { char *p; 507*12909Sgarrison 508*12909Sgarrison for (p = ref; *p; p++) 509*12909Sgarrison if (*p == '%' & *(p+1) == 'A') { 510*12909Sgarrison n--; 511*12909Sgarrison if (n == 0) { 512*12909Sgarrison for (p = p + 2; *p == ' '; p++) ; 513*12909Sgarrison breakname(p, first, last) ; 514*12909Sgarrison return(true); 515*12909Sgarrison } 516*12909Sgarrison } 517*12909Sgarrison return(false); 518*12909Sgarrison } 519*12909Sgarrison 520*12909Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add 521*12909Sgarrison single character disambiguators */ 522*12909Sgarrison disambiguate() 523*12909Sgarrison { int i, j; 524*12909Sgarrison char adstr[2]; 525*12909Sgarrison 526*12909Sgarrison for (i = 0; i < numrefs; i = j) { 527*12909Sgarrison j = i + 1; 528*12909Sgarrison if (strcmp(citestr[i], citestr[j])==0) { 529*12909Sgarrison adstr[0] = 'a'; adstr[1] = 0; 530*12909Sgarrison for (j = i+1; strcmp(citestr[i],citestr[j]) == 0; j++) { 531*12909Sgarrison adstr[0] = 'a' + (j-i); 532*12909Sgarrison strcat(citestr[j], adstr); 533*12909Sgarrison if (j == numrefs) 534*12909Sgarrison break; 535*12909Sgarrison } 536*12909Sgarrison adstr[0] = 'a'; 537*12909Sgarrison strcat(citestr[i], adstr); 538*12909Sgarrison } 539*12909Sgarrison } 540*12909Sgarrison } 541*12909Sgarrison 542*12909Sgarrison /* putrefs - gather contiguous references together, sort them if called 543*12909Sgarrison for, hyphenate if necessary, and dump them out */ 544*12909Sgarrison int putrefs(ifd, ofd, footrefs, fn) 545*12909Sgarrison FILE *ifd, *ofd; 546*12909Sgarrison int fn, footrefs[]; 547*12909Sgarrison { int citenums[MAXATONCE]; /* reference numbers */ 548*12909Sgarrison char *citeinfo[MAXATONCE]; /* reference information */ 549*12909Sgarrison char infoword[HUNTSIZE]; /* information line */ 550*12909Sgarrison int rtop, n, i, j; /* number of citations being dumped */ 551*12909Sgarrison char c, *p, *walloc(); 552*12909Sgarrison 553*12909Sgarrison /* first gather contiguous references together, and order them if 554*12909Sgarrison required */ 555*12909Sgarrison 556*12909Sgarrison rtop = -1; 557*12909Sgarrison do { 558*12909Sgarrison n = 0; 559*12909Sgarrison while (isdigit(getch(c, ifd))) 560*12909Sgarrison n = 10 * n + (c - '0'); 561*12909Sgarrison if (c ^= CITEMARK) 562*12909Sgarrison error("inconsistant citation found in pass two"); 563*12909Sgarrison if (n == 0) { /* reference not found */ 564*12909Sgarrison rtop++; 565*12909Sgarrison j = rtop; 566*12909Sgarrison citenums[j] = -1; 567*12909Sgarrison citeinfo[j] = 0; 568*12909Sgarrison } 569*12909Sgarrison else { 570*12909Sgarrison for (i = 0; i <= numrefs; i++) 571*12909Sgarrison if (refspos[i] == n) { /* its the ith item in reference list */ 572*12909Sgarrison rtop++; 573*12909Sgarrison j = rtop; 574*12909Sgarrison if (ordcite) 575*12909Sgarrison for ( ; j > 0 && citenums[j-1] > i; j--) { 576*12909Sgarrison citenums[j] = citenums[j-1]; 577*12909Sgarrison citeinfo[j] = citeinfo[j-1]; 578*12909Sgarrison } 579*12909Sgarrison citenums[j] = i; 580*12909Sgarrison citeinfo[j] = 0; 581*12909Sgarrison break; 582*12909Sgarrison } 583*12909Sgarrison if (i > numrefs) 584*12909Sgarrison error("citation not found in pass two"); 585*12909Sgarrison } 586*12909Sgarrison if (getch(c, ifd) != CITEEND) { 587*12909Sgarrison for (p = infoword; c != CITEEND ; ) { 588*12909Sgarrison *p++ = c; 589*12909Sgarrison getch(c, ifd); 590*12909Sgarrison } 591*12909Sgarrison *p = 0; 592*12909Sgarrison citeinfo[j] = walloc(infoword); 593*12909Sgarrison } 594*12909Sgarrison getch(c, ifd); 595*12909Sgarrison } while (c == CITEMARK); 596*12909Sgarrison ungetc(c, ifd); 597*12909Sgarrison 598*12909Sgarrison /* now dump out values */ 599*12909Sgarrison for (i = 0; i <= rtop; i++) { 600*12909Sgarrison if (citenums[i] >= 0) 601*12909Sgarrison fputs(citestr[citenums[i]], ofd); 602*12909Sgarrison if (citeinfo[i]) { 603*12909Sgarrison fputs(citeinfo[i], ofd); 604*12909Sgarrison free(citeinfo[i]); 605*12909Sgarrison } 606*12909Sgarrison if (hyphen) { 607*12909Sgarrison for (j = 1; j + i <= rtop && citenums[i+j] == citenums[i] + j; j++); 608*12909Sgarrison if (j + i > rtop) j = rtop; 609*12909Sgarrison else j = j + i - 1; 610*12909Sgarrison } 611*12909Sgarrison else 612*12909Sgarrison j = i; 613*12909Sgarrison if (j > i + 1) { 614*12909Sgarrison fputs("\\*(]-", ofd); 615*12909Sgarrison i = j - 1; 616*12909Sgarrison } 617*12909Sgarrison else if (i != rtop) 618*12909Sgarrison fputs("\\*(],", ofd); 619*12909Sgarrison if (foot) { 620*12909Sgarrison fn++; 621*12909Sgarrison footrefs[fn] = citenums[i]; 622*12909Sgarrison } 623*12909Sgarrison } 624*12909Sgarrison return(fn); 625*12909Sgarrison } 626*12909Sgarrison 627*12909Sgarrison /* pass2 - read pass 1 files entering citation */ 628*12909Sgarrison pass2(ifd, ofd) 629*12909Sgarrison FILE *ifd, *ofd; 630*12909Sgarrison { 631*12909Sgarrison char c; 632*12909Sgarrison int i, fn, footrefs[25], dumped; 633*12909Sgarrison 634*12909Sgarrison fn = -1; 635*12909Sgarrison dumped = foot; 636*12909Sgarrison while (getch(c, ifd) != EOF) { 637*12909Sgarrison while (c == '\n') { 638*12909Sgarrison putc(c, ofd); 639*12909Sgarrison if (foot && fn >= 0) { 640*12909Sgarrison for (i = 0; i <= fn; i++) 641*12909Sgarrison dumpref(footrefs[i], ofd); 642*12909Sgarrison fn = -1; 643*12909Sgarrison } 644*12909Sgarrison if (testc(c, '.', ifd, ofd)) 645*12909Sgarrison if (testc(c, '[', ifd, ofd)) 646*12909Sgarrison if (testc(c, ']', ifd, ofd)) { 647*12909Sgarrison while (echoc(c, ifd, ofd) != '\n') 648*12909Sgarrison ; 649*12909Sgarrison dumped = true; 650*12909Sgarrison for (i = 0; i <= numrefs; i++) 651*12909Sgarrison dumpref(i, ofd); 652*12909Sgarrison getch(c, ifd); 653*12909Sgarrison } 654*12909Sgarrison } 655*12909Sgarrison if (c == CITEMARK) 656*12909Sgarrison fn = putrefs(ifd, ofd, footrefs, fn); 657*12909Sgarrison else if (c != EOF) 658*12909Sgarrison putc(c, ofd); 659*12909Sgarrison } 660*12909Sgarrison if (dumped == false) 661*12909Sgarrison fprintf(stderr,"Warning: references never dumped\n"); 662*12909Sgarrison } 663*12909Sgarrison 664*12909Sgarrison 665*12909Sgarrison /* dumpref - dump reference number i */ 666*12909Sgarrison dumpref(i, ofd) 667*12909Sgarrison int i; 668*12909Sgarrison FILE *ofd; 669*12909Sgarrison { char ref[REFSIZE], *p, line[REFSIZE]; 670*12909Sgarrison int numauths, maxauths, numeds, maxeds; 671*12909Sgarrison 672*12909Sgarrison rdref(refspos[i], ref); 673*12909Sgarrison maxauths = maxeds = 0; 674*12909Sgarrison numauths = numeds = 0; 675*12909Sgarrison for (p = ref; *p; p++) 676*12909Sgarrison if (*p == '%') 677*12909Sgarrison if (*(p+1) == 'A') maxauths++; 678*12909Sgarrison else if (*(p+1) == 'E') maxeds++; 679*12909Sgarrison fprintf(ofd, ".[-\n"); 680*12909Sgarrison fprintf(ofd, ".ds [F %s\n",citestr[i]); 681*12909Sgarrison fseek(rfd, (long) refspos[i], 0); 682*12909Sgarrison while (fgets(line, REFSIZE, rfd) != NULL) { 683*12909Sgarrison if (line[0] == 0) break; 684*12909Sgarrison else if (line[0] == '.') fprintf(ofd,"%s",line); 685*12909Sgarrison else { 686*12909Sgarrison if (line[0] == '%') { 687*12909Sgarrison for (p = &line[2]; *p == ' '; p++); 688*12909Sgarrison if (line[1] == 'A') numauths++; 689*12909Sgarrison else if (line[1] == 'E') numeds++; 690*12909Sgarrison 691*12909Sgarrison doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd); 692*12909Sgarrison } 693*12909Sgarrison } 694*12909Sgarrison } 695*12909Sgarrison fprintf(ofd,".][\n"); 696*12909Sgarrison } 697