/************************************************************* wos2bib reads a Web of Science savedrecs.txt file and converts it to the BibTeX file format. Copyright (C) 2003 Ethan Gutmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. **************************************************************/ #include "wos2bib.h" // read in a potentially multi line entry (Author or Title) void readMulti(FILE* unit, char* output, char* joiner, int toLower) { char line[HUGE_STR], cur[HUGE_STR]; int pos, done; fpos_t curPos; char next; line[0]='\0'; cur[0]='\0'; output[0]='\0'; fgets(line, HUGE_STR, unit); stripnewline(line); substr(output, line, 1, strlen(line)); if (toLower == 1) {lowerAuthor(output);} // find >2 letter words within the current line and stringToLower them pos=fgetpos(unit, &curPos); next=getc(unit); if (next != ' ') {fsetpos(unit, &curPos); return;} done=FALSE; while (!done && !feof(unit)){ fgets(line, HUGE_STR, unit); stripnewline(line); substr(cur, line, 2, strlen(line)); if (toLower == 1) {lowerAuthor(cur);} // add code to find >2 letter words within the current line and stringToLower them sprintf(output, "%s%s%s", output, joiner, cur); //strcat(output, joiner); //strcat(output, cur); pos=fgetpos(unit, &curPos); next=getc(unit); if (next != ' ') done=TRUE; } // return the file pointer to where it was BEFORE we read the last character fsetpos(unit, &curPos); } // similar to stringToLower, but only act on words longer than two letters void lowerAuthor(char* s) { long i, len, curlen=0; len = strlen(s); curlen=(long)((strchr(s, ' ') 2) s[1]=tolower(s[1]); for( i = 2; i < len; i++ ){ s[i] = tolower(s[i]); if ((s[i]=='-') || (s[i] == ' ')) { i++; // skip 2 letters following spaces and "-" curlen=(long)((strchr(s, ' ') 0 && strlen(epage) > 0 ) sprintf((*curRecord).pages, "%s--%s", bpage, epage) ; else if( strlen(bpage) > 0 ) sprintf((*curRecord).pages, "%s", bpage ) ; } sscanf((*curRecord).author, "%s", line); stripnewline(line); // actually using this to strip off the comma stringToLower(line); // make name lowercase, before creating the key. smartToLower(&((curRecord->keywords)[1])); smartToLower(&((curRecord->pub)[1])); // this is now done within readMulti, though it should still be done here! // stringToLower(&((curRecord->author)[1])); smartToLower(&((curRecord->title)[1])); smartToLower(&((curRecord->month)[1])); // print the key sprintf((*curRecord).key, "%s%s", line, (*curRecord).year); } // initializes the file pointer for the input file // reads the first two lines and verifies that the first line // is "FN ISI Export Format" void initRead(FILE* unit) { char line[LARGE_STR]; // int line_size; // read the first line fgets(line, LARGE_STR, unit); // check to make sure the first line is what is should be printf("%s",line); if (strcmp(line, "FN ISI Export Format\n")) { printf("ERROR reading input file\n %s\n", line); return; } // read the second line, should be "VR 1.0" fgets(line, LARGE_STR, unit); printf("%s\n",line); } // writes each record to disk void writeRecord(FILE* unit, bibRec* curRecord) { char line[LARGE_STR]; line[0]='\0'; if (strlen((*curRecord).author) < 1) return; /* Maarten Sneep: * a field is only printed when it isn't empty. * To prevent spurious commas in the bib file, the comma is printed by the next entry * so that at any time the item is ready to be closed. */ // print the key fprintf(unit, "@article { %s", (*curRecord).key); if ((*curRecord).pub && strlen((*curRecord).pub) > 0 ) fprintf(unit, ",\n Journal = {%s}", (*curRecord).pub ); if ((*curRecord).year && strlen((*curRecord).year) > 0 ) fprintf(unit, ",\n Year = {%s}", (*curRecord).year ); if ((*curRecord).title && strlen((*curRecord).title) > 0 ) fprintf(unit, ",\n Title = {%s}", (*curRecord).title ); if ((*curRecord).author && strlen((*curRecord).author) > 0 ) fprintf(unit, ",\n Author = {%s}", (*curRecord).author ); if ((*curRecord).keywords && strlen((*curRecord).keywords) > 0 ) fprintf(unit, ",\n Keywords = {%s}", (*curRecord).keywords ); if ((*curRecord).abstract && strlen((*curRecord).abstract) > 0 ) fprintf(unit, ",\n Abstract = {%s}", (*curRecord).abstract ); if ((*curRecord).pages && strlen((*curRecord).pages) > 0 ) fprintf(unit, ",\n Pages = {%s}", (*curRecord).pages ); if ((*curRecord).volume && strlen((*curRecord).volume) > 0 ) fprintf(unit, ",\n Volume = {%s}", (*curRecord).volume ); if ((*curRecord).issue && strlen((*curRecord).issue) > 0 ) fprintf(unit, ",\n Issue = {%s}", (*curRecord).issue); if ((*curRecord).month && strlen((*curRecord).month) > 0 ) fprintf(unit, ",\n Month = {%s}", (*curRecord).month ); fprintf(unit, "\n}\n\n"); } // print usage information. This is called if the user // did not pass any command line arguements to wos2bib void usage( void ) { printf("\n"); printf("------------wos2bib version 0.5.4-------------\n"); printf("\n"); printf(" use : wos2bib [outputfile]\n"); printf("\n"); printf(" If the output file is not specified then \n"); printf(" output file will be .bib\n"); printf("\n"); printf(" Data will be appended to the end of the output\n"); printf(" file if it already exists. \n"); printf("\n"); } void fixKeys(bibRec *curRecord) { char* thisKey=curRecord->key; char addition='b'; int len=strlen(thisKey); curRecord=(bibRec*) curRecord->nextRec; while (curRecord != NULL){ if (!strcmp(curRecord->key, thisKey)){ curRecord->key[len]=addition++; curRecord->key[len+1]='\0'; } curRecord=(bibRec*) curRecord->nextRec; } if (addition !='b'){ thisKey[len]='a'; thisKey[len+1]='\0'; } } // main program int main(int argc, char* argv[]) { char infile[LARGE_STR]; char outfile[LARGE_STR]; FILE *un; FILE *oun; bibRec *curRecord; bibRec *tmpRecord; bibRec *firstRecord; // check input information if ((argc < 2)){// || (!ftest(argv[1]))) { usage(); return(2); } // setup file names strcpy(infile, argv[1]); // input filename if (argc == 3) { //IF we were given an output filename strcpy(outfile, argv[2]); // then save that name } else //ELSE create an output filename by appending .bib sprintf(outfile, "%s.bib", infile); // to the input filename // open input and output files un=fopen(infile, "r"); //open for reading oun=fopen(outfile, "a"); //open for writing, append to end of file //read past the header and make sure the format appears correct initRead(un); firstRecord=(bibRec*)malloc(sizeof(struct bibTeX_Rec)); tmpRecord=firstRecord; curRecord=firstRecord; // loop through the input file reading a new record while (!feof(un)) { tmpRecord=curRecord; GetNextRecord(un, curRecord); //reads an input file curRecord=(bibRec*)malloc(sizeof(struct bibTeX_Rec)); tmpRecord->nextRec=curRecord; } free(curRecord); tmpRecord->nextRec=NULL; // Loop through the records we just read writing them to disk in BibTeX format // and freeing up the memory. curRecord=firstRecord; while (curRecord->nextRec != NULL) { fixKeys(curRecord); printf("%s\n", curRecord->key); tmpRecord=(bibRec*) curRecord->nextRec; writeRecord(oun, curRecord); //writes to the output file free(curRecord); curRecord=tmpRecord; } fclose(un); fclose(oun); return(0); }