/***************************************************************************\
*  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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#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, "<i>" );
            unem = 1;
            }
        else if( c == RBRACK )
            {
            if( unrm ) 
                {
                unrm = 0;
                }
            else if( unem )
                {
                unem = 0;
                Put( buff, k, "</i>" );
                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<p><b>[%s]:</b>\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);
    }





