/* tibargs read argument strings for tib and tiblist do name formatting, printing lines, other actions common to both */ #include #include #include #include #include "tib.h" /* global variables */ char bibfname[120]; /* file name currently being read */ int biblineno; /* line number currently being referenced */ int abbrev = false; /* automatically abbreviate names */ int capsmcap = false; /* print names in caps small caps (CACM form)*/ int numrev = 0; /* number of authors names to reverse */ int edabbrev = false; /* abbreviate editors names ? */ int edcapsmcap = false; /* print editors in cap small caps */ int ednumrev = 0; /* number of editors to reverse */ int sort = false; /* sort references ? (default no) */ int foot = false; /* footnoted references ? (default endnotes) */ int c0 = false; /* references in text ? (default no) */ int hyphen = false; /* hypenate contiguous references */ int ordcite = true; /* order multiple citations */ int specflag = false; /* use special flags */ int loccit = false; /* use ibid and loccit in footnotes */ int onepage = false; /* print only first page of reference */ int underline = false; /* underline multiple references */ int silent = false; /* run silently */ int stndout = false; /* output on stdout */ int inputflag = false; /* process input/include files */ char sortstr[80] = "1"; /* sorting template */ char trailstr[80] = ""; /* trailing characters to output */ char pfile[120]; /* private file name */ char dirname[120] =""; /* private directory name */ int personal = false; /* personal file given ? (default no) */ char citetemplate[80] = "1"; /* citation template */ char *words[MAXDEFS]; /* defined words */ char *defs[MAXDEFS]; /* defined word definitions */ long int defpos[MAXDEFS]; /* position of defined words */ long int link[MAXDEFS]; /* link for linking defined words on input */ long int jtop = 0; /* entry for linked list */ long int wordtop = -1; /* top of defined words array */ int locflag[MAXREFS]; /* loc cit ? */ int ibidflag[MAXREFS]; /* ibid ? */ char dirsp2[]=DIRSEP; /* directory separator character */ char optch2[]=OPTCH; /* option character on program calls */ char suffix[5] = ".tex"; /* for appending to file names */ int startflag = 1; /* starting count of Flags */ /* where output goes */ extern FILE *tfd; /* reference file information */ extern long int refspos[]; extern int unlmark[]; extern char reffile[]; extern FILE *rfd; extern char *citestr[]; extern int numrefs; /* doargs - read command argument line for both tib and tiblist set switch values call rdtext on file arguments, after dumping default style file if no alternative style is given */ int doargs(argc, argv, defstyle) int argc; char **argv, defstyle[]; { int numfiles, i, style; char bibfnamet[120]; int pipeflag = false; int fileflag = false; char *p, *q, *walloc(); FILE *fd, *np; char headerline[240], fname[240]; char *tfgets(), *ptmac, *getenv(); if (silent == false) fprintf(stderr, "Processing format commands ...\n"); numfiles = 0; style = true; ptmac = getenv("TMACLIB"); if (ptmac == NULL) ptmac = TMACLIB; words[0] = walloc("TMACLIB"); strcpy(headerline,ptmac); strcat(headerline,dirsp2); defs[0] = walloc(headerline); wordtop++; link[0] = -1; fprintf(tfd, "%cmessage {REFERENCE FORMATTING FILES:}\n", '\\'); fprintf(tfd, "%cdef%cTMACLIB{%s%c}\n", '\\', '\\', ptmac, dirsp2[0]); fprintf(tfd, "%cinput %cTMACLIB Macros.ttx\n", '\\', '\\'); for (i = 1; i < argc; i++) if (argv[i][0] == optch2[0] && argv[i][1] == 'd') { if (argv[i][2]) p = &argv[i][2]; else { /* take next arg */ i++; if (i == argc) { fprintf(stderr,"command line: illegal switch %s\n", argv[i-1]); clnup(); exit(1); } p = argv[i]; } strcpy(dirname,p); break; } for (i = 1; i < argc; i++) if (argv[i][0] == optch2[0]) { switch(argv[i][1]) { case 'd': if (argv[i][2]) p = &argv[i][2]; else { /* take next arg */ i++; if (i == argc) { fprintf(stderr, "command line: illegal switch %s\n", argv[i-1]); clnup(); exit(1); } p = argv[i]; } strcpy(dirname,p); break; case 'j': inputflag = true; break; case 'n': if (argv[i][2]) startflag = atoi(&argv[i][2]); else { /* take next arg */ i++; if (i == argc) { fprintf(stderr, "command line: illegal switch %s\n", argv[i-1]); clnup(); exit(1); } startflag = atoi(argv[i]); } break; case 'p': if (argv[i][2]) p = &argv[i][2]; else { /* take next arg */ i++; if (i == argc) { fprintf(stderr, "command line: illegal switch %s\n", argv[i-1]); clnup(); exit(1); } p = argv[i]; } strcpy(pfile, p); personal = true; for (p = fname, q = pfile; ; q++) if (*q == ',' || *q == 0) { *p = 0; np = fopen( fname, "r"); if (np == NULL) { fprintf(stderr, "Can't open index %s\n",fname); clnup(); exit(1); } else { tfgets(headerline,240,np); fclose(np); chkindex(fname, headerline, true); } if (*q == 0) break; p = fname; } else *p++ = *q; break; case 's': style = false; /*fall through*/ case 'i': if (argv[i][2]) p = &argv[i][2]; else { /* take next arg */ i++; if (i == argc) { fprintf(stderr, "command line: illegal switch %s\n", argv[i-1]); clnup(); exit(1); } p = argv[i]; } incfile(p); break; case 'x': stndout = true; break; case 'z': silent = true; break; case '|': pipeflag = true; stndout = true; break; default: fprintf(stderr, "command line: invalid switch %s\n", argv[i]); clnup(); exit(1); } } else { /* file name */ numfiles++; fileflag = true; if (style) { style = false; incfile( defstyle ); } strcpy(bibfname, argv[i]); fd = fopen(argv[i], "r"); if (fd == NULL) { strcat(bibfname,suffix); fd=fopen(bibfname, "r"); if (fd == NULL) { fprintf(stderr, "can't open %s or %s\n", argv[i], bibfname); clnup(); exit(1); } } if (stndout == false && silent == false) { fprintf(stderr, "Reading input document file %s and looking up references ...\n", bibfname); } rdtext(fd); fclose(fd); } if (style) incfile( defstyle ); if (fileflag == false) /* no input file on command line */ if (pipeflag == true) { strcpy(bibfname, ""); rdtext(stdin); numfiles++; } else { fprintf(stderr, "Enter input file: "); scanf("%s", bibfnamet); numfiles++; strcpy(bibfname, bibfnamet); fd = fopen(bibfnamet, "r"); if (fd == NULL) { strcat(bibfname, ".tex"); fd=fopen(bibfname, "r"); if (fd == NULL) { fprintf(stderr, "can't open %s or %s\n", bibfnamet, bibfname); clnup(); exit(1); } } if (stndout == false && silent == false) { fprintf(stderr, "Reading input document file %s and looking up references ...\n", bibfname); } rdtext(fd); fclose(fd); } return(numfiles); } /* chkindex - check if index is up to date */ int chkindex(indx, header, pflag) char *indx; char header[240]; int pflag; { char *c, *q, *p; char indx0[240], indx00[80], *indx1, indx11[240]; char *rindex(); struct stat buf; FILE *np; int i, j, qflag; time_t timefile, timeindx; stat(indx, &buf); timeindx = buf.st_mtime; strcpy (indx0,indx); c = rindex(indx0, dirsp2[0]); if (c == NULL) indx00[0] = '\0'; else { *++c = '\0'; strcpy (indx00, indx0); } strcpy (indx0,indx00); qflag = true; for (q = header ; *q;) { for (;*q == ' ';q++); if (*q == '\0') break; for (indx1 = q; *q && *q != ' '; q++); if (*q) *q = '\0'; else qflag = false; if (*indx1 != dirsp2[0]) { strcat (indx0,indx1); strcpy (indx11,indx0); } np = fopen(indx11,"r"); if (np == NULL) { fprintf(stderr,"Cannot locate reference file %s\n", indx11); clnup(); exit(1); } strcpy (indx0, indx00); stat(indx11, &buf); timefile = buf.st_mtime; if (qflag == true) *q = ' '; if (timeindx < timefile) { fprintf(stderr,"Index %s not up to date\n", indx); if (pflag) fprintf(stderr,"Use tibdex (in appropriate directory) with reference file(s)%s\n",header); else fprintf(stderr," Use: tibdex%s\n",header); clnup(); exit(1); } } } /* outfname - make output file name */ char *outfname(mp) char *mp; { char *q; for (q=mp; *q; q++); if (*--q == 'x') if (*--q == 'e') if (*--q == 't') if (*--q == '.') *q='\0'; strcat (mp, "-t.tex"); return (mp); } /* incfile - read in an included file */ incfile(np) char *np; { char name[120]; FILE *fd; char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets(); int i, j, k, getwrd(); int located, j1; char *ptmac, *getenv(); ptmac = getenv("TMACLIB"); if (ptmac == NULL) ptmac = TMACLIB; strcpy(bibfname, np); fd = fopen(np, "r"); if (fd == NULL && *np != dirsp2[0]) { strcpy(name, np); strcat(name, ".tib"); strcpy(bibfname, name); fd = fopen(name, "r"); } if (fd == NULL && *np != dirsp2[0]) if (dirname[0] != '\0') { strcpy(name, dirname); strcat(name, dirsp2); strcat(name, np); strcpy(bibfname, name); fd = fopen(name, "r"); } if (fd == NULL && *np != dirsp2[0]) if (dirname[0] != '\0') { strcpy(name, dirname); strcat(name, dirsp2); strcat(name, np); strcat(name, ".tib"); strcpy(bibfname, name); fd = fopen(name, "r"); } if (fd == NULL && *np != dirsp2[0]) { strcpy(name, ptmac); strcat(name, dirsp2); strcat(name, np); strcpy(bibfname, name); fd = fopen(name, "r"); } if (fd == NULL && *np != dirsp2[0]) { strcpy(name, ptmac); strcat(name, dirsp2); strcat(name, np); strcat(name, ".tib"); strcpy(bibfname, name); fd = fopen(name, "r"); } if (fd == NULL) { bibwarning("%s: can't open\n", np); clnup(); exit(1); } /* now go off and process file */ fprintf(tfd, "%cmessage {(%s}\n", '\\', np); biblineno = 1; while (tfgets(line, LINELENGTH, fd) != NULL) { biblineno++; switch(line[0]) { case '#': break; case 'A': for (p = &line[1]; *p && *p != ' '; p++) { if (*p == 'A') abbrev = true; else if (*p == 'X') capsmcap = true; else if (*p == 'R') { if (isdigit(*(p+1))) numrev = atoi(p+1); else numrev = 1000; } } break; case 'C': for (p = &line[1]; *p == ' '; p++) ; strcpy(citetemplate, p); for (p=citetemplate; *p && *p != ' '; p++); *p=0; if (citetemplate[0] == '0') c0 = true; break; case 'D': if ((k = getwrd(line, 1, word)) == 0) error("word expected in definition"); /* this creates a linked list for use in sortdefs and expnd2 but it is fortran style, not good c style -- fix later */ j=jtop; for (located = false; located == false; ) { i=strcmp(word, words[jtop]); if (i == 0) { located = true; break; } if (i > 0) { wordtop++; if (wordtop > MAXDEFS) error("too many definitions:"); link[wordtop] = jtop; jtop = wordtop; j = jtop; words[wordtop] = walloc(word); located = true; break; } while (link[j] >= 0) { j1 = link[j]; i = strcmp(word, words[j1]); if (i == 0) { j = j1; located = true; break; } if (i > 0) { wordtop++; if (wordtop > MAXDEFS) error("too many definitions:"); link[wordtop] = j1; link[j] = wordtop; j = wordtop; words[wordtop] = walloc(word); located = true; break; } j = j1; } if (located == false) { wordtop++; if (wordtop > MAXDEFS) error("too many definitions:"); link[wordtop] = -1; link[j] = wordtop; j = wordtop; words[wordtop] = walloc(word); located = true; break; } } for (p = &line[k]; *p == ' '; p++) ; for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){ dline[strlen(dline)-1] = '\n'; if (tfgets(line, LINELENGTH, fd) == NULL) break; strcat(dline, line); } defs[j] = walloc(dline); break; case 'E': for (p = &line[1]; *p && *p != ' '; p++) { if (*p == 'A') edabbrev = true; else if (*p == 'X') edcapsmcap = true; else if (*p == 'R') { if (isdigit(*(p+1))) ednumrev = atoi(p+1); else ednumrev = 1000; } } break; case 'f': foot = true; hyphen = false; break; case 'F': specflag = true; break; case 'H': hyphen = ordcite = true; break; case 'I': for (p = &line[1]; *p == ' '; p++); expnd1(p); incfile(p); break; case 'L': loccit = true; break; case 'N': for (p = &line[1]; *p == ' '; p++); if (*p == 'A') abbrev = false; else if (*p == 'F') specflag = false; else if (*p == 'H') hyphen = false; else if (*p == 'O') ordcite = false; else if (*p == 'R') numrev = 0; else if (*p == 'S') sort = false; else if (*p == 'X') capsmcap = false; break; case 'O': ordcite = true; break; case 'P': onepage = true; break; case 'S': sort = true; for (p = &line[1]; *p == ' '; p++) ; strcpy(sortstr, p); for (p=sortstr; *p && *p != ' '; p++); *p=0; break; case 'T': for (p = &line[1]; *p == ' '; p++) ; strcpy(trailstr, p); for (p=trailstr; *p && *p != ' '; p++); *p=0; break; case 'U': underline = true; break; default: fprintf(tfd, "%s\n", line); while (fgets(line, LINELENGTH, fd) != NULL) fputs(line, tfd); fprintf(tfd, "%cmessage {)}", '\\'); return; } } /* close up */ fprintf(tfd, "%cmessage{)}", '\\'); fclose(fd); } /* bibwarning - print out a warning message */ bibwarning(msg, arg) char *msg, *arg; { fprintf(stderr, "`%s', line %d: ", bibfname, biblineno); fprintf(stderr, msg, arg); } /* error - report unrecoverable error message */ error(str) char str[]; { bibwarning("%s\n", str); clnup(); exit(1); } #ifdef READWRITE /* ** fixrfd( mode ) -- re-opens the rfd file to be read or write, ** depending on the mode. Uses a static int to save the current mode ** and avoid unnecessary re-openings. */ fixrfd( mode ) register int mode; { static int cur_mode = WRITE; /* rfd open for writing initially */ if (mode != cur_mode) { rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd); cur_mode = mode; if (rfd == NULL) error("Hell! Couldn't re-open reference file"); } } #endif /* tfgets - fgets which trims off newline */ char *tfgets(line, n, ptr) char line[]; int n; FILE *ptr; { char *p; p = fgets(line, n, ptr); if (p == NULL) return(NULL); else for (p = line; *p; p++) if (*p == '\n') *p = 0; return(line); } /* getwrd - place next word from in[i] into out */ int getwrd(in, i, out) char in[], out[]; int i; { int j; j = 0; while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t') i++; if (in[i]) while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n') out[j++] = in[i++]; else i = 0; /* signals end of in[i..] */ out[j] = 0; return (i); } /* walloc - allocate enough space for a word */ char *walloc(word) char *word; { char *i, *malloc(); i = malloc(1 + strlen(word)); if (i == NULL) error("out of storage"); strcpy(i, word); return(i); } /* isword - see if character is legit word char */ int iswordc(c) char c; { if (isalnum(c) || c == '&' || c == '_') return(true); return(false); } /* expnd1 - expand reference, replacing defined words, scrunching spaces */ expnd1(line) char *line; { char line2[REFSIZE], word[LINELENGTH], *p, *q, *w; int replaced, i; replaced = true; while (replaced) { replaced = false; p = line; q = line2; while (*p) { if (isalnum(*p)) { for (w = word; *p && iswordc(*p); ) *w++ = *p++; *w = 0; for (i = 0; i <= wordtop; i++) if (strcmp(word, words[i]) == 0) { strcpy(word, defs[i]); replaced = true; break; } for (w = word; *w; ) *q++ = *w++; } else *q++ = *p++; } *q = 0; p = line; q = line2; while (*q != 0) { if (*q != ' ') *p++ = *q++; else q++; } *p = 0; } } /* expnd2 - expand reference, replacing defined words */ expnd2(line) char *line; { char line2[REFSIZE], word[LINELENGTH], *p, *q, *w; int replaced, toolong, i; toolong = false; /* flag to indicate reference is too long */ replaced = true; while (replaced) { replaced = false; p = line; q = line2; while (*p) { if (*p != '|') if (q - line2 >= REFSIZE-1){ toolong = true; /* reference entry is too long */ *(q-1) = '\n'; /* make entry end with \n\0 */ break; } else *q++ = *p++; else { *p++; for (w = word; *p && *p != '|'; *w++ = *p++); *w = 0; if (locdef(word) == false) fprintf(stderr,"word %s not defined in definition list\n", word); else replaced = true; if (*p == '|') p++; for (w = word; *w; *q++ = *w++) if (q - line2 >= REFSIZE-1){ toolong = true; /* reference entry is too long */ *(q-1) = '\n'; /* make entry end with \n\0 */ break; } } } *q = 0; p = line; q = line2; while (*p++ = *q++); } if(toolong && silent == false) { /* print truncation warning */ fprintf(stderr, "Truncated following reference after expanding defined words: \n"); fprintf(stderr,"-------------\n%s\n-------------\n",line); } } /* locdef - locate a definition */ int locdef(word) char *word; { long int lower, upper, mid, i; int strcmp(); char *w, *w1; lower = 0; upper = wordtop; if (strcmp(word, words[defpos[lower]]) == 0) { for (w = word, w1 = defs[defpos[lower]]; *w1; *w++ = *w1++); *w = 0; return(true); } if (strcmp(word, words[defpos[upper]]) == 0) { for (w = word, w1 = defs[defpos[upper]]; *w1; *w++ = *w1++); *w = 0; return(true); } while (lower+1 < upper) { mid = (lower + upper)/2; i = strcmp(word, words[defpos[mid]]); if (i == 0) { for (w = word, w1 = defs[defpos[mid]]; *w1; *w++ = *w1++); *w = 0; return(true); } if (i > 0) lower = mid; else upper = mid; } return (false); } /* rdref - read text for an already cited reference */ rdref(i, ref) long int i; char ref[REFSIZE]; { ref[0] = 0; #ifdef READWRITE fixrfd( READ ); /* fix access mode of rfd, if nec. */ #endif fseek(rfd, i, 0); fread(ref, 1, REFSIZE, rfd); } /* breakname - break a name into first and last name */ breakname(line, first, last) char line[], first[], last[]; { char *p, *q, *r, *t, *f; for (t = line; *t != '\n'; t++); for (t--; isspace(*t); t--); /* now strip off last name */ for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--) { if (*q == '}') { while (*q != '{') { q--; if (q == line) { fprintf (stderr, "bad brackets in string %s in references\n", line); clnup(); exit(1); } } } if (q == line) break; } f = q; if (q != line) { q++; for (; isspace(*f); f--); f++; } /* first name is start to f, last name is q to t */ for (r = first, p = line; p != f; ) *r++ = *p++; *r = 0; for (r = last, p = q, t++; q != t; ) *r++ = *q++; *r = 0; } /* match - see if string1 is a substring of string2 (case independent)*/ int match(str1, str2) char str1[], str2[]; { int i, j; char a, b; for (i = 0; str2[i]; i++) { for (j = 0; str1[j]; j++) { if (isupper(a = str2[i+j])) a = (a - 'A') + 'a'; if (isupper(b = str1[j])) b = (b - 'A') + 'a'; if (a != b) break; } if (str1[j] == 0) return(true); } return(false); } /* scopy - append a copy of one string to another */ char *scopy(p, q) char *p, *q; { while (*p++ = *q++) ; return(--p); } /* makecites - make citation strings */ makecites(citestr) char *citestr[]; { char ref[REFSIZE], tempcite[100], *malloc(); int i; for (i = 0; i <= numrefs; i++) { rdref(refspos[i], ref); bldcite(tempcite, i, ref); citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */ if (citestr[i] == NULL) error("out of storage"); strcpy(citestr[i], tempcite); } } /* sortdefs - make array of pointers to defined words */ sortdefs() { long int i, j; i = wordtop; for (j = jtop; j >= 0; j = link[j]) { defpos[i] = j; i--; } } /* rcomp1 - revised reference comparison routine for qsort utility */ int rcomp1(ap, bp) long int *ap, *bp; { char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD]; char alpha1[REFSIZE], alpha2[REFSIZE]; char *p, *q, *getfield(); int neg, res; int n, m1, m2, num; int getname(); char last1[MAXFIELD], last2[MAXFIELD], first1[MAXFIELD], first2[MAXFIELD]; int alphabits(); char *fstcap(); rdref(*ap, ref1); rdref(*bp, ref2); for (p = sortstr, q=p; *p ; p=q) { if (*p == '-') { p++; neg = true; } else neg = false; res=0; if (*p == 'A') { p++; if (isdigit(*p)) for (num=0; isdigit(*p); p++) num=10*num+(*p-'0'); else num=100; q=p; for (n=1; n <= num; n++) { m1=getname (n, last1, first1, ref1); m2=getname (n, last2, first2, ref2); if (m1 == 0 && m2 == 0) break; alphabits(alpha1, last1); alphabits(alpha2, last2); /* res = strcmp (fstcap(alphabits(last1)), fstcap(alphabits(last2))); alpha11 = fstcap(alphastring1); alpha21 = fstcap(alphastring2);*/ res = strcmp (fstcap(alpha1), fstcap(alpha2)); if (res) break; alphabits(alpha1, first1); alphabits(alpha2, first2); res = strcmp (fstcap(alpha1), fstcap(alpha2)); if (res != 0) break; } } else { q++; getfield(p, field1, ref1); getfield(p, field2, ref2); res = strcmp (field1, field2); } if (neg) res = - res; if (res != 0) break; } if (res == 0) { if (ap < bp) res = -1; else res = 1; } return(res); } /* alphabits - reduce string to alpha characters */ alphabits(stringout, stringin) char *stringin, *stringout; { char *p, *q; q = stringout; p = stringin; while (*p) { if (isalpha(*p) || isspace(*p)) *q++ = *p++; else if (*p == '{') { for (; *p && *p != '}'; p++); if (*p == 0) { fprintf(stderr, "bad brackets in string %s in references\n", stringin); clnup(); exit(1); } else { for (p--; isalpha(*p); p--); for (p++; isalpha(*p); *q++ = *p++); } } else p++; } *q = 0; } /* fstcap - find first capital letter in string */ char *fstcap(string) char *string; { char *ptr; for(ptr=string; *ptr && (isupper(*ptr) == 0); ptr++); return (ptr); } /* capbrackets - find if string in brackets is capital, also capitalize it */ capbrackets(stringout, stringin) char *stringout, *stringin; { char *p, *q; int cap; cap = false; q = stringout; p = stringin; for (; *p && *p != '}'; *q++ = *p++); if (*p == 0) { fprintf(stderr, "bad brackets in string %s in references\n", stringin); clnup(); exit(1); } *q++ = '}'; *q = 0; q--; for (q--; isalpha(*q); q--) { if (isupper (*q)) cap = true; else { cap = false; *q = (*q - 'a') + 'A'; } } return (cap); } /* undrline - underline successive identical authors */ undrline() { char line[REFSIZE], line1[REFSIZE], last[REFSIZE], first[REFSIZE]; char ref[REFSIZE]; int m, i; line1[0] = 0; for (m=numrefs; m >= 0; m--) { rdref(refspos[m], ref); line[0] = 0; for (i=1; getname(i, last, first, ref); i++) { strcat(line, last); strcat(line, first); } if (strcmp(line, line1) == 0) unlmark[m] = true; else unlmark[m] = false; strcpy(line1, line); } } /* bldcite - build a single citation string */ bldcite(cp, i, ref) char *cp, ref[]; int i; { char *p, *q, c, *fp, field[REFSIZE], *getfield(), *aabet(), *nmdt(); getfield("F", field, ref); if (field[0] != 0 && specflag) for (p = field; *p; p++) *cp++ = *p; else { p = citetemplate; field[0] = 0; while (c = *p++) { if (isalpha(c)) { /* field name */ q = getfield(p-1, field, ref); if (q != 0) { p = q; cp=scopy(cp, "\\Citebreak "); for (fp = field; *fp; ) *cp++ = *fp++; } } else if (c == '0') { /* empty citation */ *cp = '\0'; } else if (c == '1') { /* numeric order */ sprintf(field, "%d", startflag + i); for (fp = field; *fp; ) *cp++ = *fp++; } else if (c == '2') /* alternate alphabetic */ cp = aabet(cp, ref); else if (c == '3') /* names */ cp = nmdt(cp, ref); /* else if (c == '4') here is how to add new styles */ /* else if (c == '{') { while (*p != '}') if (*p == 0) error("unexpected end of citation template"); else *cp++ = *p++; p++; } */ else if (c == '<') { while (*p != '>') { if (*p == 0) error("unexpected end of citation template"); else *cp++ = *p++; } p++; } else if (c != '@') *cp++ = c; } } *cp++ = 0; } /* alternate alphabetic citation style */ char *aabet(cp, ref) char *cp, ref[]; { char field[REFSIZE], temp[100], *np, *fp; char string11[80], string12[80], string13[80], string2[80], string3[80]; char bracketstring[80]; int getname(), i; if (getname(1, field, temp, ref)) { fp = field; for (np = string11; *fp; fp++) { if (isupper(*fp)) { *np++ = *fp; break; } else if (*fp == '{') { if (capbrackets(bracketstring, fp) == 0) for (; *fp != '}'; fp++); else { for (; *fp != '}'; *np++ = *fp++); *np++ = '}'; break; } } } if (*fp) fp++; *np = 0; for (np = string12; *fp && isalpha(*fp) == 0 && *fp != '{'; *np++ = *fp++); if (*fp != '{') *np++ = *fp; else { capbrackets(bracketstring, fp); for (; *fp != '}'; *np++ = *fp++); *np++ = '}'; } if (*fp) fp++; *np = 0; for (np = string13; *fp && isalpha(*fp) == 0 && *fp != '{'; *np++ = *fp++); if (*fp != '{') *np++ = *fp; else { capbrackets(bracketstring, fp); for (; *fp != '}'; *np++ = *fp++); *np++ = '}'; } *np = 0; } if (getname(2, field, temp, ref) == 0) { strcpy (field, string11); strcat (field, string12); strcat (field, string13); } else { fp = field; for (np = string2; *fp; fp++) { if (isupper(*fp)) { *np++ = *fp; break; } if (*fp == '{') { if (capbrackets(bracketstring, fp) == 0) for (; *fp != '}'; fp++); else { for (; *fp != '}'; *np++ = *fp++); *np++ = '}'; break; } } } *np = 0; if (getname(3, field, temp, ref) == 0) { strcpy (field, string11); strcat (field, string12); strcat (field, string2); } else { fp = field; for (np = string3; *fp; fp++) { if (isupper(*fp)) { *np++ = *fp; break; } if (*fp == '{') { if (capbrackets(bracketstring, fp) == 0) for (; *fp != '}'; fp++); else { for (; *fp != '}'; *np++ = *fp++); *np++ = '}'; break; } } } *np = 0; strcpy (field, string11); strcat (field, string2); strcat (field, string3); } } for (i=0; field[i]; i++) *cp++ = field[i]; return (cp); } /* names style if 1 author - last name date if 2 authors - last name and last name date if 3 authors - last name, last name and last name date if 4 or more authors - last name et al. date */ char *nmdt(cp, ref) char *cp, ref[]; { char name1[100], name2[100], name3[100], temp[100], *fp; int getname(); if (getname(1, name1, temp, ref)) { for (fp = name1; *fp; ) *cp++ = *fp++; if (getname(4, name3, temp, ref)) { for (fp = " et al."; *fp; ) *cp++ = *fp++; } else if (getname(2, name2, temp, ref)) { if (getname(3, name3, temp, ref)) { for (fp = "\\Namecomma "; *fp; ) *cp++ = *fp++; for (fp = name2; *fp; ) *cp++ = *fp++; for (fp = "\\Nameandd "; *fp; ) *cp++ = *fp++; for (fp = name3; *fp; ) *cp++ = *fp++; } else { for (fp = "\\Nameand "; *fp; ) *cp++ = *fp++; for (fp = name2; *fp; ) *cp++ = *fp++; } } } return(cp); } /* getfield - get a single field from reference */ char *getfield(ptr, field, ref) char *ptr, field[], ref[]; { char *p, *q, temp[100]; int n, len, i, getname(); field[0] = 0; if (*ptr == 'A') getname(1, field, temp, ref); else for (p = ref; *p; p++) if (*p == '%' && *(p+1) == *ptr) { for (p = p + 2; *p == ' '; p++) ; for (q = field; (*p != '\n') && (*p != '\0'); ) *q++ = *p++; *q = 0; break; } n = 0; len = strlen(field); if (*++ptr == '-') { for (ptr++; isdigit(*ptr); ptr++) n = 10 * n + (*ptr - '0'); if (n > len) n = 0; else n = len - n; for (i = 0; field[i] = field[i+n]; i++) ; } else if (isdigit(*ptr)) { for (; isdigit(*ptr); ptr++) n = 10 * n + (*ptr - '0'); if (n > len) n = len; field[n] = 0; } if (*ptr == 'u') { ptr++; for (p = field; *p; p++) if (islower(*p)) *p = (*p - 'a') + 'A'; } else if (*ptr == 'l') { ptr++; for (p = field; *p; p++) if (isupper(*p)) *p = (*p - 'A') + 'a'; } return(ptr); } /* getname - get the nth name field from reference, breaking into first and last names */ int getname(n, last, first, ref) int n; char last[], first[], ref[]; { char *p; int m; last[0]='\0'; first[0]='\0'; m = n; for (p = ref; *p; p++) if (*p == '%' & *(p+1) == 'A') { n--; if (n == 0) { for (p = p + 2; *p == ' '; p++) ; breakname(p, first, last) ; return(true); } } if (n == m) /* no authors, try editors */ for (p = ref; *p; p++) if (*p == '%' & *(p+1) == 'E') { n--; if (n == 0) { for (p = p + 2; *p == ' '; p++) ; breakname(p, first, last) ; return(true); } } if (n == m && n == 1) { /* no editors, either, try institution */ first[0] = last[0] = '\0'; getfield("I", last, ref); if (last[0] != '\0') return(true); } return(false); } /* disambiguate - compare adjacent citation strings, and if equal, add single character disambiguators */ disambiguate() { int i, j; char adstr[2]; for (i = 0; i < numrefs; i = j) { j = i + 1; if (strcmp(citestr[i], citestr[j])==0) { adstr[0] = 'a'; adstr[1] = 0; for (j = i+1; strcmp(citestr[i], citestr[j]) == 0; j++) { adstr[0] = 'a' + (j-i); strcat(citestr[j], adstr); if (j == numrefs) break; } adstr[0] = 'a'; strcat(citestr[i], adstr); } } } /* bldname - build a name field doing abbreviations, reversals, and caps/small caps */ bldnm1(first, last, name, reverse) char *first, *last, name[]; int reverse; { char newfirst[120], newlast[120], *p, *q, *f, *l, *scopy(); int flag; if (abbrev) { p = first; q = newfirst; flag = false; while (*p) { while (*p == ' ') p++; if (*p == 0) break; if (isupper(*p)) { if (flag) /* between initial gap */ q = scopy(q, "\\Initgap "); flag = true; *q++ = *p; q = scopy(q, "\\Initper "); } if (*++p == '.') p++; else while (*p != 0 && ! isspace(*p)) p++; } *q = 0; f = newfirst; } else f = first; if (capsmcap) { p = last; q = newlast; flag = 0; /* 1 - printing cap, 2 - printing small */ while (*p) if (islower(*p)) { if (flag != 2) q = scopy(q, "\\bgroup\\Smallcapsfont "); flag = 2; *q++ = (*p++ - 'a') + 'A'; } else { if (flag == 2) q = scopy(q, "\\egroup "); flag = 1; *q++ = *p++; } if (flag == 2) q = scopy(q, "\\egroup "); *q = 0; l = newlast; } else l = last; if (f[0] == 0) sprintf(name, "%s\n", l); else if (reverse) sprintf(name, "%s%cRevcomma %s\n", l, '\\', f); else sprintf(name, "%s %s\n", f, l); } /* capssmallcaps - put field in capssmallcaps */ capssmallcaps(stringout, stringin) char *stringout, *stringin; { char *p, *q, *scopy(); int flag, bflag; char bracketfield[REFSIZE]; p = stringin; q = stringout; *q = 0; flag = 0; /* 1 - printing cap, 2 - printing small */ while (*p) { if (*p == '\\') *p++; if (*p == ' ') { if (flag == 2) q = scopy(q, "\\egroup{}"); flag = 1; /* *q++ = '\\';*/ *q++ = ' '; p++; } if (*p == '~') { if (flag == 2) q = scopy(q, "\\egroup{}"); flag = 1; *q++ = *p++; } if (*p == '{') bflag = capbrackets(bracketfield, p); else bflag = 1; if (islower(*p) || bflag == 0) { if (flag != 2) q = scopy(q, "\\bgroup\\Smallcapsfont "); flag = 2; if (*p == '{') { q = scopy(q, bracketfield); for (; *p != '}'; p++); p++; } else *q++ = (*p++ - 'a') + 'A'; } else { if (flag == 2) q = scopy(q, "\\egroup{}"); flag = 1; if (*p == '{') { q = scopy(q, bracketfield); for (; *p != '}'; p++); p++; } else *q++ = *p++; } } if (flag == 2) q = scopy(q, "\\egroup{}"); *q = 0; } bldname(first, last, name, reverse, capsmcap) char *first, *last, name[]; int reverse, capsmcap; { char newfirst[120], newlast[120], *p, *q, *f, *f1, *l, *scopy(); char newnewfirst[120]; char bracketfield[20]; int flag; int hflag, bflag; if (abbrev) { p = first; q = newfirst; flag = false; hflag = false; bflag = false; while (*p) { while (*p == ' ') p++; if (*p == '{') bflag = capbrackets(bracketfield, p); if (isupper(*p) || bflag) { if (flag && hflag) /* between initial gap */ q = scopy(q, "\\Initgap "); flag = true; if (bflag) { for (; *p != '}'; *q++ = *p++); bflag = false; } *q++ = *p; for (p++;; p++) { if (isupper(*p)) { hflag = true; break; } else if (*p == '-' || *p == '\'') { hflag = false; *q++ = *p++; break; } else if (*p == '.' ) { hflag = true; q = scopy(q, "\\Initper "); p++; break; } else if (*p == ' ' ) { hflag = true; q = scopy(q, "\\Initper "); p++; break; } else if (*p == '~') { hflag = true; q = scopy(q, "\\Initper "); p++; break; } else if (*p == 0) { q = scopy(q, "\\Initper "); break; } else if (*p == '{') { bflag = capbrackets(bracketfield, p); if (bflag) break; else for (; *p != '}'; p++); } } } else *q++ = *p++; } *q = 0; f1 = newfirst; } else f1 = first; if (capsmcap) { capssmallcaps(newlast,last); l = newlast; if (abbrev == 0) { capssmallcaps(newnewfirst,f1); f = newnewfirst; } else f = f1; } else { f = f1; l = last; } if (f[0] == 0) sprintf(name, "%s\n", l); else if (reverse) sprintf(name, "%s%cRevcomma %s\n", l, '\\', f); else sprintf(name, "%s %s\n", f, l); } /* prtauth - print author or editor field */ prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev) char c, *line; int num, max, abbrev, capsmcap, numrev; FILE *ofd; { char first[LINELENGTH], last[LINELENGTH]; char *s1; if (num <= numrev || abbrev || capsmcap) { breakname(line, first, last); bldname(first, last, line, num <= numrev, capsmcap); } for (s1=line;*s1!='\0';s1++) if (*s1=='\n') *s1='\0'; if (num == 1) { fprintf(ofd, "}%c\n%cdef%c%ctest{ }", '\%', '\\', '\\', c); if (index(trailstr, c)) fprintf(ofd, "%cdef%c%ctrail{%c}", '\\', '\\', c, line[strlen(line)-2]); fprintf(ofd, "%cdef%c%cstr{%s", '\\', '\\', c, line); } else if (num < max) fprintf(ofd, "%c\n %c%ccomma %s", '\%', '\\', c, line); else if (max == 2) fprintf(ofd, "%c\n %c%cand %s", '\%', '\\', c, line); else fprintf(ofd, "%c\n %c%candd %s", '\%', '\\', c, line); } /* doline - actually print out a line of reference information */ doline(c, line, numauths, maxauths, numeds, maxeds, numrevs, maxrevs, numtrans, maxtrans, ofd) char c, *line; int numauths, maxauths, numeds, maxeds; int numrevs, maxrevs, numtrans, maxtrans; FILE *ofd; { char *s1; char *dbldash(); char line1[REFSIZE]; switch(c) { case '\\': case '\%': for (s1=line;*s1!='\0';s1++) if (*s1=='\n') *s1='\0'; fprintf(ofd, "}%c\n%c%s{", '\%', c , line); break; case 'A': prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev); break; case 'E': if (maxauths) prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev); else prtauth(c, line, numeds, maxeds, ofd, abbrev, capsmcap, numrev); break; case 'a': prtauth(c, line, numtrans, maxtrans, ofd, edabbrev, edcapsmcap, ednumrev); break; case 'e': prtauth(c, line, numrevs, maxrevs, ofd, edabbrev, edcapsmcap, ednumrev); break; case 'P': case 'p': fprintf(ofd, "}%c\n%cdef%c%ctest{ }", '\%', '\\', '\\', c); if (onepage) { opage(line); fprintf(ofd, "%cdef%c%ccnt{}", '\\', '\\', c); } else { if (index (line, '-')) { line = dbldash(line); fprintf(ofd, "%cdef%c%ccnt{ }", '\\', '\\', c); } else fprintf(ofd, "%cdef%c%ccnt{}", '\\', '\\', c); } if (index(trailstr, c)) fprintf(ofd, "%cdef%c%ctrail{%c}%c\n", '\\', '\\', c, line[strlen(line)-2], '\%'); for (s1 = line; *s1 != '\0'; s1++) if (*s1=='\n') *s1='\0'; fprintf(ofd, "%cdef%c%cstr{%s", '\\', '\\', c, line); break; case 'F': case 'K': break; case 'I': if (numauths == 0 && numeds == 0 && capsmcap) { capssmallcaps(line1, line); strcpy(line, line1); } default: fprintf(ofd, "}%c\n%cdef%c%ctest{ }", '\%', '\\', '\\', c); if (index(trailstr, c)) fprintf(ofd, "%cdef%c%ctrail{%c}", '\\', '\\', c, line[strlen(line)-2]); for (s1=line;*s1!='\0';s1++) if (*s1=='\n') *s1='\0'; fprintf(ofd, "%cdef%c%cstr{%s", '\\', '\\', c, line); } } /* dbldash - double the hyphen in the P field (see below)*/ char *dbldash(line) char *line; { char *p; char newline[120]; for (p = newline; *line && *line != '-'; *p++ = *line++); if (*line == 0) return (line); if (*++line != '-') *p++ = '-'; *p++ = '-'; for (*p = *line; *line; *p++ = *line++); *p='\0'; return (newline); } /* following works on some machines where above fails char *dbldash(line) char *line; { char *p; static char newline[120]; for (p = newline; *p = *line; ++p, ++line) if (line[0] == '-' && line[1] != '-') *++p = '-'; return(newline); } */ /* opage - print only first page number */ int opage(line) char *line; { char *p; for (p = line; *p && *p != '-'; *p++); *p=0; } /* dumpref - dump reference number i */ dumpref(i, ofd) int i; FILE *ofd; { char ref[REFSIZE], *p, line[REFSIZE]; int numauths, maxauths, numeds, maxeds; int numrevs, maxrevs, numtrans, maxtrans; fprintf(ofd, "%cbgroup%cResetstrings%c\n", '\\', '\\' , '\%'); rdref(refspos[i], ref); maxauths = maxeds = maxrevs = maxtrans = 0; numauths = numeds = numrevs = numtrans = 0; for (p = ref; *p; p++) if (*p == '%') if (*(p+1) == 'A') maxauths++; else if (*(p+1) == 'E') maxeds++; else if (*(p+1) == 'a') maxtrans++; else if (*(p+1) == 'e') maxrevs++; if (loccit) { if (locflag[i]) fprintf(ofd, "%cdef%cLoccittest{ }", '\\', '\\'); else fprintf(ofd, "%cdef%cLoccittest{}", '\\', '\\'); if (ibidflag[i]) fprintf(ofd, "%cdef%cIbidtest{ }", '\\', '\\'); else fprintf(ofd, "%cdef%cIbidtest{}", '\\', '\\'); } else fprintf(ofd, "%cdef%cLoccittest{}", '\\', '\\'); if (abbrev) fprintf(ofd, "%cdef%cAbbtest{ }", '\\', '\\'); else fprintf(ofd, "%cdef%cAbbtest{}", '\\', '\\'); if (capsmcap) fprintf(ofd, "%cdef%cCapssmallcapstest{ }", '\\', '\\'); else fprintf(ofd, "%cdef%cCapssmallcapstest{}", '\\', '\\'); if (edabbrev) fprintf(ofd, "%cdef%cEdabbtest{ }", '\\', '\\'); else fprintf(ofd, "%cdef%cEdabbtest{}", '\\', '\\'); if (edcapsmcap) fprintf(ofd, "%cdef%cEdcapsmallcapstest{ }", '\\', '\\'); else fprintf(ofd, "%cdef%cEdcapsmallcapstest{}", '\\', '\\'); if (underline) fprintf(ofd, "%cdef%cUnderlinetest{ }%c\n", '\\', '\\', '\%'); else fprintf(ofd, "%cdef%cUnderlinetest{}%c\n", '\\', '\\', '\%'); fprintf(ofd, "%cdef%cNoArev{%d}%cdef%cNoErev{%d}%cdef%cAcnt{%d}", '\\', '\\', numrev, '\\', '\\', ednumrev, '\\', '\\', maxauths); fprintf(ofd, "%cdef%cEcnt{%d}%cdef%cacnt{%d}%cdef%cecnt{%d}%c\n", '\\', '\\', maxeds, '\\', '\\', maxtrans, '\\', '\\', maxrevs, '\%'); fprintf(ofd, "%cdef%cFtest{ }", '\\', '\\'); if (index(trailstr, 'F')) fprintf(ofd, "%cdef%c%ctrail{%c}", '\\', '\\', 'F', citestr[i][strlen(citestr[i])-1]); fprintf(ofd, "%cdef%cFstr{%s", '\\', '\\', citestr[i]); fseek(rfd, (long) refspos[i], 0); while (fgets(line, REFSIZE, rfd) != NULL) { if (line[0] == 0) break; else if (line[0] == '%') { for (p = &line[2]; *p == ' '; p++); if (line[1] == 'A') numauths++; else if (line[1] == 'E') numeds++; else if (line[1] == 'a') numtrans++; else if (line[1] == 'e') numrevs++; doline(line[1], p, numauths, maxauths, numeds, maxeds, numrevs, maxrevs, numtrans, maxtrans, ofd); } else if (line[0] == '\\') fprintf(ofd, "}%c\n%s{", '\%', line); else fprintf(ofd, "%s", line); } if (underline && unlmark[i-1]) { if (maxauths) fprintf (ofd, "}%c\n%cdef%cAstr{%cUnderlinemark", '\%', '\\', '\\', '\\'); else if (maxeds) fprintf (ofd, "}%c\n%cdef%cEstr{%cUnderlinemark", '\%', '\\', '\\', '\\'); else fprintf (ofd, "}%c\n%cdef%cIstr{%cUnderlinemark", '\%', '\\', '\\', '\\'); } fprintf(ofd, "}%c\n%cRefformat%cegroup%c\n", '\%', '\\', '\\', '\%'); if ((!foot) && (!c0)) fprintf(ofd, "\n"); }