/***************************************************************************\ * B B L 2 H T M L * * * * AUTHOR: Jim Arvo, California Institute of Technology * * * * DESCRIPTION: This program reads a ".bbl" file (generated by bibtex) * * through standard input, and generates corresponding html statements * * on standard output. This makes it easy to put a bibliography * * generated by LaTeX and bibtex on the web. It's still rather crude, * * but it seems to work reasonably well. * * * * Changes: * * * * 10/31/96 arvo Initial implementation. * * * \***************************************************************************/ #include #include #include #define NullChar '\0' #define NewLine '\n' #define TAB '\t' #define TILDE '~' #define DASH '-' #define PERIOD '.' #define BSLASH '\\' #define ATSIGN '@' #define LBRACK '{' #define RBRACK '}' #define COMMA ',' #define BLANK ' ' #define GETC( c ) ( c = getc( fp ) ) #define PUSH( c ) ungetc( c, fp ) #define WHITE( c ) ( c == BLANK || c == NewLine || c == TAB ) #define DELIM( c ) ( c == COMMA || c == LBRACK || c == RBRACK ) #define DIGIT( c ) ( '0' <= c && c <= '9' ) #define MATCH(s,t) ( strcmp(s,t) == 0 ) #define UPPER( c ) ( ( 'a' <= c && c <= 'z' ) ? c + 'A' - 'a' : c ) FILE *fp; static void print_how_to_use() { fprintf( stderr, "Usage: bbl2html file1.bbl file2.bbl ... fileN.bbl >file.html \n" ); exit(1); } static void skip_white( ) { char c; do { GETC(c); } while( WHITE(c) ); PUSH(c); } static void skip_to( char target ) { int c; do { GETC(c); } while( c != EOF && c != target ); if( c == EOF ) PUSH(c); } static void Put( char *buff, int &k, char *str ) { for( int i = 0; str[i] != NullChar; i++ ) buff[ k++ ] = str[i]; } static void grab_to_period( char *buff ) { int c; int k = 0; int period = 0; int lbrack = 0; int bslash = 0; int e = 0; int r = 0; int em = 0; int rm = 0; int unem = 0; int unrm = 0; int dash = 0; int blank = 0; for( GETC(c); c != EOF; GETC(c) ) { if( c == NewLine && period ) break; period = ( c == PERIOD ); if( c == LBRACK ) { lbrack = 1; } else if( c == BSLASH && lbrack ) { lbrack = 0; bslash = 1; } else if( c == BSLASH ) { bslash = 1; } else if( c == 'r' && bslash ) { bslash = 0; r = 1; } else if( c == 'm' && r ) { r = 0; rm = 1; } else if( c == ' ' && rm ) { rm = 0; unrm = 1; } else if( c == 'e' && bslash ) { bslash = 0; e = 1; } else if( c == 'm' && e ) { e = 0; em = 1; } else if( c == ' ' && em ) { em = 0; Put( buff, k, "" ); unem = 1; } else if( c == RBRACK ) { if( unrm ) { unrm = 0; } else if( unem ) { unem = 0; Put( buff, k, "" ); unem = 1; } } else if( c == '&' && bslash ) { bslash = 0; buff[ k++ ] = c; } else if( c == '-' && dash ) { dash = 0; buff[ k++ ] = c; } else if( c == '-' ) dash = 1; else if( c == '$' ) {} // Skip it. else { if( dash ) buff[ k++ ] = '-'; if( c == NewLine ) c = ' '; if( c == TILDE ) c = ' '; lbrack = 0; bslash = 0; dash = 0; if( c != ' ' || k != blank ) buff[ k++ ] = c; if( c == ' ' ) blank = k; } } buff[ k - 1 ] = NullChar; } static void get_token_ucase( char *s ) { int c; skip_white(); while( GETC(c) != EOF ) { if( WHITE(c) || DELIM(c) ) break; *s++ = UPPER( c ); } PUSH(c); *s = NullChar; } static void get_token( char *s ) { int c; skip_white(); while( GETC(c) != EOF ) { if( WHITE(c) || DELIM(c) ) break; *s++ = c; } PUSH(c); *s = NullChar; } static void skip_to_newblock() { char temp[128]; for(;;) { skip_to( BSLASH ); get_token_ucase( temp ); if( MATCH( temp, "NEWBLOCK" ) ) break; } } void main( int argc, char *argv[] ) { int c; char name [128]; char tok [128]; char fname[128]; char buff [512]; if( argc < 2 ) print_how_to_use(); printf( "\n" ); for( int i = 1; i < argc; i++ ) { char *arg = argv[i]; // First try opening file as it appears on the command line. If that // fails, try appending ".bib". Once open, strip off the suffix if // it has one -- this is for printing later. strcpy( fname, arg ); fp = fopen( fname, "r" ); if( fp == NULL ) { strcat( fname, ".bbl" ); // Try appending ".bbl" to the name. fp = fopen( fname, "r" ); if( fp == NULL ) { fprintf( stderr, "(bbl2html): Could not access %s or %s.\n", arg, fname ); exit(1); } } // Now parse the file, picking out the abbreviations associated with // each of the entries. while( GETC(c) != EOF ) { if( c == BSLASH ) { name[0] = NullChar; get_token_ucase( tok ); if( MATCH( tok, "BIBITEM" ) ) { skip_to( LBRACK ); get_token( name ); skip_to( RBRACK ); printf( "\n

[%s]:\n", name ); grab_to_period( buff ); printf( " %s,\n", buff ); skip_to_newblock(); // Get the paper title. skip_white(); grab_to_period( buff ); printf( " \"%s\",\n", buff ); skip_to_newblock(); // Get journal or publisher skip_white(); grab_to_period( buff ); printf( " %s.\n", buff ); } } } fclose( fp ); } exit(0); }