#define about "tibtobib 0.3, 1989 by uf" #include <stdio.h> #include <ctype.h> #define maxlines 50 #define linelen 256 #define ntypes 8 #define ntags 18 #define article 0 #define conference 1 #define inbook 2 #define mastersthesis 3 #define phdthesis 4 #define techreport 5 #define book 6 #define misc 7 #define HELP 0 #define NOREF 10 #define NOBIB 11 #define BIGITEM 12 #define NOCONT1 13 #define NOCONT2 14 #define BIGLINE 15 #define BADTAG 16 #define MEMFULL 17 char RCSHeader[]="$Header: /home/tex/local/ttb.c,v 1.3 90/02/15 14:55:30 sk Rel $"; static char *inputtype[]={"ARTICLE","CONFERENCE","INBOOK","MASTERSTHESIS", "PHDTHESIS","TECHREPORT","BOOK","MISC"}, *recordtype[]={"AUTHOR","BOOKTITLE","ADDRESS","YEAR","EDITOR", "PUBLISHER","JOURNAL","KEY","NUMBER","NOTE","PAGES", "TYPE","SERIES","TITLE","VOLUME","COMMENT","ANNOTE", "ABSTRACT"}, allowedtag[]={'A','B','C','D','E','I','J','K','N','O','P','R','S','T','V', '%','x','X'}, organization[]="ORGANIZATION"; char *item[maxlines],buffer[maxlines*linelen], reffile[linelen],bibfile[linelen]; int curline=0,type,ilines; FILE *ref,*bib,*fopen(); main(argc,argv) int argc; char **argv; { int notready; if (argc != 2) { fprintf(stderr,"%s, usage: ttb <filename>\n",about); exit(HELP); } strcpy(reffile,argv[1]); if ((ref=fopen(reffile,"r")) == NULL) { sprintf(reffile,"%s.ref",argv[1]); if ((ref=fopen(reffile,"r")) == NULL) { fprintf(stderr,"ttb: can open neither %s nor %s\n",argv[1],reffile); exit(NOREF); } } if (!strcmp(argv[1]+strlen(argv[1])-4,".ref")) argv[1][strlen(argv[1])-4]='\0'; sprintf(bibfile,"%s.bib",argv[1]); if ((bib=fopen(bibfile,"w")) == NULL) { fprintf(stderr,"ttb: can't open %s\n",bibfile); exit(NOBIB); } /* main loop */ do { notready=getitem(); type=classifyitem(); /* printitem(); */ putitem(); } while(notready); /* exit */ fclose(ref); fclose(bib); } getitem() { char firstchar,secondchar; int i,j,k,ok,ilm1,space,used,ignored=0; ilines = 0; space = maxlines*linelen-1; *item = buffer; while(!feof(ref)) { if (space<=0) { fprintf(stderr,"ttb: %s, %d: buffer space exhausted\n",reffile,curline); exit(MEMFULL); } fgets(item[ilines++],space,ref); ilm1 = ilines-1; for (k=strlen(item[ilm1])-1; k>-1 && isspace(item[ilm1][k]); item[ilm1][k--]=0) ; /* printf("%s\n",item[ilm1]); */ curline++; if (ilines>maxlines) { fprintf(stderr,"ttb: %s, line %d: too many lines for this item, line ignored\n",reffile,curline); ilines--; continue; } if (strlen(item[ilm1]) == 0) { /* blank line */ ilines--; ignored=0; break; } if ((firstchar=item[ilm1][0]) != '%') { /* continuation line */ if (ilines == 1) { fprintf(stderr,"ttb: %s, line %d: leading continuation line ignored\n",reffile,curline); ilines--; continue; } if (ignored) { fprintf(stderr,"ttb: %s, line %d: continuation line ignored\n",reffile,curline); ilines--; continue; } ilines--; *(item[ilines]-1) = '\n'; used = strlen(item[ilines])+1; item[ilines] += used; continue; } secondchar = item[ilm1][1]; ok = 0; for (i=0; i<ntags; i++) if (secondchar == allowedtag[i]) { ok = -1; break; } if (!ok) { fprintf(stderr,"ttb: %s, line %d: field tag %c not allowed, line ignored\n",reffile,curline,secondchar); ignored = -1; ilines--; continue; } ignored = 0; space -= (used = strlen(item[ilm1])+1); item[ilines] = item[ilm1]+used; } return(!feof(ref)); } int classifyitem() { int p,type; if (test('J') && test('V')) type = article; else if (test('B')) type = inbook; else if (p=test('R')) if (index(item[p-1],"thesis")) if (index(item[p-1],"master")) type = mastersthesis; else type = phdthesis; else type = techreport; else if (test('I')) type = book; else type = conference; return(type); } index(s,t) char s[],t[]; { int i,j,k; for (i=0; s[i]; i++) { for (j=i,k=0; t[k] && tolower(s[j])==tolower(t[k]); j++,k++) ; if (t[k] == 0) return(i+1); } return(0); } int test(c) char c; { int i; for (i=0; i<ilines; i++) if (item[i][1] == c) return(i+1); return(0); } putitem() { char author[linelen],year[linelen],page[linelen],record[linelen], editor[linelen],secondchar; int i,j,k,p,first; if (p=test('A')) { if ((i = index(item[p-1],",")) > 4) { strcpy(author,item[p-1]+3); author[i-4]=0; } else { for (k=strlen(item[p-1]); k>2 && item[p-1][k] != ' ' && item[p-1][k] != '.'; k--) ; strcpy(author,item[p-1]+k+1); } } else strcpy(author,"Mr.X"); if (p=test('D')) strcpy(year,item[p-1]+strlen(item[p-1])-2); else strcpy(year,"??"); if (p=test('P')) { for (i=3; i<strlen(item[p-1]) && (isalpha(item[p-1][i]) && i==3 || isdigit(item[p-1][i])); page[i-3]=item[p-1][i], i++) ; page[i-3]=0; } else strcpy(page,"0"); if (p=test('K')) /* user provides keyword */ fprintf(bib,"@%s{%s%c\n",inputtype[type],item[p-1]+3,ilines>0 ? ',' : ' '); else fprintf(bib,"@%s{%s%s:%s%c\n",inputtype[type],author,year,page,ilines>0 ? ',' : ' '); /* special cases: several authors, editors */ first = !0; strcpy(author,""); if (test('A')) { for (i=0; i<ilines; i++) { if (item[i][1] == 'A') { if (first) first = 0; else strcat(author," and "); strcat(author,item[i]+3); } } fprintf(bib," %s = {%s}%c\n",recordtype[0],author,item[ilines-1][1] != 'A' ? ',' : ' '); } first = !0; strcpy(editor,""); if (test('E')) { for (i=0; i<ilines; i++) { if (item[i][1] == 'E') { if (first) first = 0; else strcat(editor," and "); strcat(editor,item[i]+3); } } fprintf(bib," %s = {%s}%c\n",recordtype[4],editor,item[ilines-1][1] != 'E' ? ',' : ' '); } /* all other fields */ for (i=0; i<ilines; i++) { secondchar = item[i][1]; if (secondchar == 'A' || secondchar == 'E') continue; /* special case: %J in a conference */ if (secondchar == 'J' && type == conference) strcpy(record,organization); /* all other cases */ else for (j=0; j<ntags; j++) if (secondchar == allowedtag[j]) { strcpy(record,recordtype[j]); break; } fprintf(bib," %s = {%s}%c\n",record,item[i]+3,i<ilines-1 ? ',' : ' '); } fprintf(bib,"}\n\n"); } option(argc,argv,c) char **argv,c; int argc; { int i,j; for (i=1; i<argc; i++) if (argv[i][0] == '-') for (j=1; j<strlen(argv[i]); j++) if (argv[i][j] == c) return(i); return(0); } printitem() { int i; for (i=0; i<ilines; i++) printf("%s\n",item[i]); printf("\nitem consisting of %d lines, type = %d\n\n",ilines,type); }