Ejemplo n.º 1
0
static void
output_pages( FILE *fp, fields *info, unsigned long refnum, int format_opts )
{
    newstr pages;
    int sn, en;
    sn = fields_find( info, "PAGESTART", -1 );
    en = fields_find( info, "PAGEEND", -1 );
    if ( sn==-1 && en==-1 ) {
        output_articlenumber( fp, info, refnum, format_opts );
        return;
    }
    newstr_init( &pages );
    if ( sn!=-1 ) {
        newstr_strcat( &pages, info->data[sn].data );
        fields_setused( info, sn );
    }
    if ( sn!=-1 && en!=-1 ) {
        if ( format_opts & BIBOUT_SINGLEDASH )
            newstr_strcat( &pages, "-" );
        else
            newstr_strcat( &pages, "--" );
    }
    if ( en!=-1 ) {
        newstr_strcat( &pages, info->data[en].data );
        fields_setused( info, en );
    }
    output_element( fp, "pages", pages.data, format_opts );
    newstr_free( &pages );
}
Ejemplo n.º 2
0
static void
output_date( FILE *fp, fields *info, unsigned long refnum, int format_opts )
{
    char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
                       };
    int n, month;
    n = fields_find( info, "YEAR", -1 );
    if ( n==-1 ) n = fields_find( info, "PARTYEAR", -1 );
    if ( n!=-1 ) {
        output_element( fp, "year", info->data[n].data, format_opts );
        fields_setused( info, n );
    }
    n = fields_find( info, "MONTH", -1 );
    if ( n==-1 ) n = fields_find( info, "PARTMONTH", -1 );
    if ( n!=-1 ) {
        month = atoi( info->data[n].data );
        if ( month>0 && month<13 )
            output_element( fp, "month", months[month-1], format_opts );
        else
            output_element( fp, "month", info->data[n].data, format_opts );
        fields_setused( info, n );
    }
    n = fields_find( info, "DAY", -1 );
    if ( n==-1 ) n = fields_find( info, "PARTDAY", -1 );
    if ( n!=-1 ) {
        output_element( fp, "day", info->data[n].data, format_opts );
        fields_setused( info, n );
    }
}
Ejemplo n.º 3
0
static void
output_title( FILE *fp, fields *info, unsigned long refnum, char *bibtag, int level, int format_opts )
{
    newstr title;
    int n1 = -1, n2 = -1;
    /* Option is for short titles of journals */
    if ( ( format_opts & BIBOUT_SHORTTITLE ) && level==1 ) {
        n1 = fields_find( info, "SHORTTITLE", level );
        n2 = fields_find( info, "SHORTSUBTITLE", level );
    }
    if ( n1==-1 ) {
        n1 = fields_find( info, "TITLE", level );
        n2 = fields_find( info, "SUBTITLE", level );
    }
    if ( n1!=-1 ) {
        newstr_init( &title );
        newstr_newstrcpy( &title, &(info->data[n1]) );
        fields_setused( info, n1 );
        if ( n2!=-1 ) {
            if ( info->data[n1].data[info->data[n1].len]!='?' )
                newstr_strcat( &title, ": " );
            else newstr_addchar( &title, ' ' );
            newstr_strcat( &title, info->data[n2].data );
            fields_setused( info, n2 );
        }
        output_element( fp, bibtag, title.data, format_opts );
        newstr_free( &title );
    }
}
Ejemplo n.º 4
0
static void
bibtexin_crossref( bibl *bin, param *p )
{
	char booktitle[] = "booktitle";
	long i, j, ncross;
	char *nt, *nd, *type;
	int n, ntype, nl;
        for ( i=0; i<bin->nrefs; ++i ) {
		n = fields_find( bin->ref[i], "CROSSREF", -1 );
		if ( n==-1 ) continue;
		ncross = bibtexin_findref( bin, bin->ref[i]->data[n].data );
		if ( ncross==-1 ) {
			bibtexin_nocrossref( bin, i, n, p );
			continue;
		}
		ntype = fields_find( bin->ref[i], "TYPE", -1 );
		type = bin->ref[i]->data[ntype].data;
		fields_setused( bin->ref[i], n );
/*		bin->ref[i]->used[n] = 1; */
		for ( j=0; j<bin->ref[ncross]->nfields; ++j ) {
			nt = bin->ref[ncross]->tag[j].data;
			if ( !strcasecmp( nt, "TYPE" ) ) continue;
			if ( !strcasecmp( nt, "REFNUM" ) ) continue;
			if ( !strcasecmp( nt, "TITLE" ) ) {
				if ( !strcasecmp( type, "Inproceedings" ) ||
				     !strcasecmp( type, "Incollection" ) )
					nt = booktitle;
			}
			nd = bin->ref[ncross]->data[j].data;
			nl = bin->ref[ncross]->level[j] + 1;
			fields_add( bin->ref[i], nt, nd, nl );

		}
	}
}
Ejemplo n.º 5
0
static void
output_name_type( fields *info, FILE *outptr, int level, 
			char *map[], int nmap, char *tag )
{
	newstr ntag;
	int i, j, n=0, code, nfields;
	newstr_init( &ntag );
	nfields = fields_num( info );
	for ( j=0; j<nmap; ++j ) {
		for ( i=0; i<nfields; ++i ) {
			code = extract_name_and_info( &ntag, &(info->tag[i]) );
			if ( strcasecmp( ntag.data, map[j] ) ) continue;
			if ( n==0 )
				fprintf( outptr, "<%s><b:NameList>\n", tag );
			if ( code != NAME )
				output_name_nomangle( outptr, info->data[i].data );
			else 
				output_name( outptr, info->data[i].data );
			fields_setused( info, i );
			n++;
		}
	}
	newstr_free( &ntag );
	if ( n )
		fprintf( outptr, "</b:NameList></%s>\n", tag );
}
Ejemplo n.º 6
0
/* detail output
 *
 */
static void
output_item( fields *info, FILE *outptr, char *tag, char *prefix, int item, int level )
{
	int i;
	if ( item==-1 ) return;
	for ( i=0; i<level; ++i ) fprintf( outptr, " " );
	fprintf( outptr, "<%s>%s%s</%s>\n", tag, prefix, info->data[item].data, tag );
	fields_setused( info, item );
}
Ejemplo n.º 7
0
static void
output_type( fields *f, FILE *outptr, int level )
{
	int n;

	/* silence warnings about INTERNAL_TYPE being unused */
	n = fields_find( f, "INTERNAL_TYPE", 0 );
	if ( n!=-1 ) fields_setused( f, n );

	output_resource( f, outptr, level );
	output_genre( f, outptr, level );
}
Ejemplo n.º 8
0
/* output article number as pages if true pages aren't found */
static void
output_articlenumber( FILE *fp, fields *info, unsigned long refnum,
                      int format_opts )
{
    int ar = fields_find( info, "ARTICLENUMBER", -1 );
    if ( ar!=-1 ) {
        newstr pages;
        newstr_init( &pages );
        newstr_strcat( &pages, info->data[ar].data );
        output_element( fp, "pages", pages.data, format_opts );
        fields_setused( info, ar );
        newstr_free( &pages );
    }
}
Ejemplo n.º 9
0
static void
output_fileattach( FILE *fp, fields *info, int format_opts )
{
    newstr data;
    int i;
    newstr_init( &data );
    for ( i=0; i<info->nfields; ++i ) {
        if ( strcasecmp( info->tag[i].data, "FILEATTACH" ) ) continue;
        newstr_strcpy( &data, ":" );
        newstr_newstrcat( &data, &(info->data[i]) );
        if ( strsearch( info->data[i].data, ".pdf" ) )
            newstr_strcat( &data, ":PDF" );
        else if ( strsearch( info->data[i].data, ".html" ) )
            newstr_strcat( &data, ":HTML" );
        else newstr_strcat( &data, ":TYPE" );
        output_element( fp, "file", data.data, format_opts );
        fields_setused( info, i );
        newstr_empty( &data );
    }
    newstr_free( &data );
}
Ejemplo n.º 10
0
static void
output_people( FILE *fp, fields *info, unsigned long refnum, char *tag,
               char *ctag, char *atag, char *bibtag, int level,
               int format_opts )
{
    newstr allpeople;
    int i, npeople, person, corp, asis;

    /* primary citation authors */
    npeople = 0;
    for ( i=0; i<info->nfields; ++i ) {
        if ( level!=-1 && info->level[i]!=level ) continue;
        person = ( strcasecmp( info->tag[i].data, tag ) == 0 );
        corp   = ( strcasecmp( info->tag[i].data, ctag ) == 0 );
        asis   = ( strcasecmp( info->tag[i].data, atag ) == 0 );
        if ( person || corp || asis ) {
            if ( npeople==0 ) newstr_init( &allpeople );
            else {
                if ( format_opts & BIBOUT_WHITESPACE )
                    newstr_strcat(&allpeople,"\n\t\tand ");
                else newstr_strcat( &allpeople, "\nand " );
            }
            if ( corp ) {
                newstr_addchar( &allpeople, '{' );
                newstr_strcat( &allpeople, info->data[i].data );
                newstr_addchar( &allpeople, '}' );
            } else if ( asis ) {
                newstr_addchar( &allpeople, '{' );
                newstr_strcat( &allpeople, info->data[i].data );
                newstr_addchar( &allpeople, '}' );
            } else add_person( &allpeople, info->data[i].data );
            fields_setused( info, i );
            npeople++;
        }
    }
    if ( npeople ) {
        output_element( fp, bibtag, allpeople.data, format_opts );
        newstr_free( &allpeople );
    }
}
Ejemplo n.º 11
0
static int
bibtexin_crossref( bibl *bin, param *p )
{
	int i, n, ncross, status = BIBL_OK;
	fields *bibref, *bibcross;

	for ( i=0; i<bin->nrefs; ++i ) {
		bibref = bin->ref[i];
		n = fields_find( bibref, "CROSSREF", -1 );
		if ( n==-1 ) continue;
		fields_setused( bibref, n );
		ncross = bibtexin_findref( bin, (char*) fields_value( bibref, n, FIELDS_CHRP ) );
		if ( ncross==-1 ) {
			bibtexin_nocrossref( bin, i, n, p );
			continue;
		}
		bibcross = bin->ref[ncross];
		status = bibtexin_crossref_oneref( bibref, bibcross );
		if ( status!=BIBL_OK ) goto out;
	}
out:
	return status;
}
Ejemplo n.º 12
0
static void
output_names( fields *f, FILE *outptr, int level )
{
	convert   names[] = {
	  { "author",                              "AUTHOR",          0, MARC_AUTHORITY },
	  { "editor",                              "EDITOR",          0, MARC_AUTHORITY },
	  { "annotator",                           "ANNOTATOR",       0, MARC_AUTHORITY },
	  { "artist",                              "ARTIST",          0, MARC_AUTHORITY },
	  { "author",                              "2ND_AUTHOR",      0, MARC_AUTHORITY },
	  { "author",                              "3RD_AUTHOR",      0, MARC_AUTHORITY },
	  { "author",                              "SUB_AUTHOR",      0, MARC_AUTHORITY },
	  { "author",                              "COMMITTEE",       0, MARC_AUTHORITY },
	  { "author",                              "COURT",           0, MARC_AUTHORITY },
	  { "author",                              "LEGISLATIVEBODY", 0, MARC_AUTHORITY },
	  { "author of afterword, colophon, etc.", "AFTERAUTHOR",     0, MARC_AUTHORITY },
	  { "author of introduction, etc.",        "INTROAUTHOR",     0, MARC_AUTHORITY },
	  { "cartographer",                        "CARTOGRAPHER",    0, MARC_AUTHORITY },
	  { "collaborator",                        "COLLABORATOR",    0, MARC_AUTHORITY },
	  { "commentator",                         "COMMENTATOR",     0, MARC_AUTHORITY },
	  { "compiler",                            "COMPILER",        0, MARC_AUTHORITY },
	  { "degree grantor",                      "DEGREEGRANTOR",   0, MARC_AUTHORITY },
	  { "director",                            "DIRECTOR",        0, MARC_AUTHORITY },
	  { "event",                               "EVENT",           0, NO_AUTHORITY   },
	  { "inventor",                            "INVENTOR",        0, MARC_AUTHORITY },
	  { "organizer of meeting",                "ORGANIZER",       0, MARC_AUTHORITY },
	  { "patent holder",                       "ASSIGNEE",        0, MARC_AUTHORITY },
	  { "performer",                           "PERFORMER",       0, MARC_AUTHORITY },
	  { "producer",                            "PRODUCER",        0, MARC_AUTHORITY },
	  { "recipient",                           "RECIPIENT",       0, MARC_AUTHORITY },
	  { "redactor",                            "REDACTOR",        0, MARC_AUTHORITY },
	  { "reporter",                            "REPORTER",        0, MARC_AUTHORITY },
	  { "sponsor",                             "SPONSOR",         0, MARC_AUTHORITY },
	  { "translator",                          "TRANSLATOR",      0, MARC_AUTHORITY },
	  { "writer",                              "WRITER",          0, MARC_AUTHORITY },
	};
	int i, n, nfields, ntypes = sizeof( names ) / sizeof( convert );
	int f_asis, f_corp, f_conf;
	newstr role;

	newstr_init( &role );
	nfields = fields_num( f );
	for ( n=0; n<ntypes; ++n ) {
		for ( i=0; i<nfields; ++i ) {
			if ( fields_level( f, i )!=level ) continue;
			if ( f->data[i].len==0 ) continue;
			f_asis = f_corp = f_conf = 0;
			newstr_strcpy( &role, f->tag[i].data );
			if ( newstr_findreplace( &role, ":ASIS", "" )) f_asis=1;
			if ( newstr_findreplace( &role, ":CORP", "" )) f_corp=1;
			if ( newstr_findreplace( &role, ":CONF", "" )) f_conf=1;
			if ( strcasecmp( role.data, names[n].internal ) )
				continue;
			if ( f_asis ) {
				output_tag( outptr, lvl2indent(level),               "name",     NULL, TAG_OPEN,      TAG_NEWLINE, NULL );
				output_fil( outptr, lvl2indent(incr_level(level,1)), "namePart", f, i, TAG_OPENCLOSE, TAG_NEWLINE, NULL );
			} else if ( f_corp ) {
				output_tag( outptr, lvl2indent(level),               "name",     NULL, TAG_OPEN,      TAG_NEWLINE, "type", "corporate", NULL );
				output_fil( outptr, lvl2indent(incr_level(level,1)), "namePart", f, i, TAG_OPENCLOSE, TAG_NEWLINE, NULL );
			} else if ( f_conf ) {
				output_tag( outptr, lvl2indent(level),               "name",     NULL, TAG_OPEN,      TAG_NEWLINE, "type", "conference", NULL );
				output_fil( outptr, lvl2indent(incr_level(level,1)), "namePart", f, i, TAG_OPENCLOSE, TAG_NEWLINE, NULL );
			} else {
				output_name(outptr, f->data[i].data, level);
			}
			output_tag( outptr, lvl2indent(incr_level(level,1)), "role", NULL, TAG_OPEN, TAG_NEWLINE, NULL );
			if ( names[n].code & MARC_AUTHORITY )
				output_tag( outptr, lvl2indent(incr_level(level,2)), "roleTerm", names[n].mods, TAG_OPENCLOSE, TAG_NEWLINE, "authority", "marcrelator", "type", "text", NULL );
			else
				output_tag( outptr, lvl2indent(incr_level(level,2)), "roleTerm", names[n].mods, TAG_OPENCLOSE, TAG_NEWLINE, "type", "text", NULL );
			output_tag( outptr, lvl2indent(incr_level(level,1)), "role", NULL, TAG_CLOSE, TAG_NEWLINE, NULL );
			output_tag( outptr, lvl2indent(level),               "name", NULL, TAG_CLOSE, TAG_NEWLINE, NULL );
			fields_setused( f, i );
		}
	}
	newstr_free( &role );
}
Ejemplo n.º 13
0
static int
get_type( fields *info )
{
	match_type match_genres[] = {
		{ "academic journal",          TYPE_ARTICLE },
		{ "magazine",                  TYPE_MAGARTICLE },
		{ "conference publication",    TYPE_INPROCEEDINGS },
		{ "hearing",                   TYPE_HEARING },
		{ "Ph.D. thesis",              TYPE_PHDTHESIS },
		{ "Masters thesis",            TYPE_MASTERSTHESIS },
		{ "Diploma thesis",            TYPE_DIPLOMATHESIS },
		{ "Doctoral thesis",           TYPE_DOCTORALTHESIS },
		{ "Habilitation thesis",       TYPE_HABILITATIONTHESIS },
		{ "legislation",               TYPE_BILL },
		{ "newspaper",                 TYPE_NEWSPAPER },
		{ "communication",             TYPE_COMMUNICATION },
		{ "manuscript",                TYPE_MANUSCRIPT },
		{ "report",                    TYPE_REPORT },
		{ "legal case and case notes", TYPE_CASE },
		{ "patent",                    TYPE_PATENT },
	};
	int nmatch_genres = sizeof( match_genres ) / sizeof( match_genres[0] );

	char *tag, *data;
	int i, j, type = TYPE_UNKNOWN;

	for ( i=0; i<info->n; ++i ) {
		tag = info->tag[i].data;
		if ( strcasecmp( tag, "GENRE" )!=0 &&
		     strcasecmp( tag, "NGENRE" )!=0 ) continue;
		data = info->data[i].data;
		for ( j=0; j<nmatch_genres; ++j ) {
			if ( !strcasecmp( data, match_genres[j].name ) ) {
				type = match_genres[j].type;
				fields_setused( info, i );
			}
		}
		if ( type==TYPE_UNKNOWN ) {
			if ( !strcasecmp( data, "periodical" ) )
				type = TYPE_ARTICLE;
			else if ( !strcasecmp( data, "thesis" ) )
				type = TYPE_THESIS;
			else if ( !strcasecmp( data, "book" ) ) {
				if ( info->level[i]==0 ) type = TYPE_BOOK;
				else type = TYPE_INBOOK;
			}
			else if ( !strcasecmp( data, "collection" ) ) {
				if ( info->level[i]==0 ) type = TYPE_BOOK;
				else type = TYPE_INBOOK;
			}
			if ( type!=TYPE_UNKNOWN ) fields_setused( info, i );
		}
	}
	if ( type==TYPE_UNKNOWN ) {
		for ( i=0; i<info->n; ++i ) {
			if ( strcasecmp( info->tag[i].data, "RESOURCE" ) )
				continue;
			data = info->data[i].data;
			if ( !strcasecmp( data, "moving image" ) )
				type = TYPE_BROADCAST;
			else if ( !strcasecmp( data, "software, multimedia" ) )
				type = TYPE_PROGRAM;
			if ( type!=TYPE_UNKNOWN ) fields_setused( info, i );
		}
	}

	/* default to generic */
	if ( type==TYPE_UNKNOWN ) type = TYPE_GENERIC;
	
	return type;
}
Ejemplo n.º 14
0
static void
output_and_use( FILE *fp, fields *info, int n, char *outtag, int format_opts )
{
    output_element( fp, outtag, info->data[n].data, format_opts );
    fields_setused( info, n );
}
Ejemplo n.º 15
0
int
endin_convertf( fields *endin, fields *info, int reftype, param *p, variants *all, int nall )
{
	int i, level, n, process, nfields, ok;
	char *newtag, *t;
	newstr *d;

	nfields = fields_num( endin );
	for ( i=0; i<nfields; ++i ) {
		/* Ensure that data exists */
		d = fields_value( endin, i, FIELDS_STRP_NOUSE );
		if ( d->len == 0 ) {
			fields_setused( endin, i );
			continue;
		}
		/*
		 * All refer format tags start with '%'.  If we have one
		 * that doesn't, assume that it comes from endx2xml
		 * and just copy and paste to output
		 */
		t = fields_tag( endin, i, FIELDS_CHRP );
		if ( t[0]!='%' ) {
			fields_add( info, t, d->data, endin->level[i] );
			continue;
		}

		n = translate_oldtag( t, reftype, all, nall, &process, &level, &newtag );
		if ( n==-1 ) {
			endin_notag( p, t, d->data );
			continue;
		}
		if ( process == ALWAYS ) continue; /* add these later */

		fields_setused( endin, i );

		switch ( process ) {

		case SIMPLE:
			ok = fields_add( info, newtag, d->data, level );
			break;

		case TYPE:
			ok = endin_addtype( info, d->data, level );
			break;

		case TITLE:
			ok = title_process( info, newtag, d->data, level, p->nosplittitle );
			break;

		case PERSON:
			ok = name_add( info, newtag, d->data, level, &(p->asis), &(p->corps) );
			break;

		case DATE:
			ok = endin_adddate( info, t, newtag,d->data,level);
			break;

		case PAGES:
			ok = endin_addpage( info, d->data, level );
			break;

		case SERIALNO:
			ok = addsn( info, d->data, level );
			break;

		case NOTES:
			ok = endin_addnotes( info, newtag, d->data, level );
			break;

		default:
			fprintf(stderr,"%s: internal error -- illegal process number %d\n", p->progname, process );
			ok = 1;
			break;
		}

		if ( !ok ) return BIBL_ERR_MEMERR;

	}

	return BIBL_OK;
}
Ejemplo n.º 16
0
static int
get_type( fields *info, param *p, unsigned long refnum )
{
	/* Comment out TYPE_GENERIC entries as that is default, but
         * keep in source as record of mapping decision. */
	match_type match_genres[] = {
		/* MARC Authority elements */
		{ "art original",              TYPE_ARTWORK },
		{ "art reproduction",          TYPE_ARTWORK },
		{ "article",                   TYPE_ARTICLE },
		{ "atlas",                     TYPE_MAP },
		{ "autobiography",             TYPE_BOOK },
/*		{ "bibliography",              TYPE_GENERIC },*/
		{ "biography",                 TYPE_BOOK },
		{ "book",                      TYPE_BOOK },
/*		{ "calendar",                  TYPE_GENERIC },*/
/*		{ "catalog",                   TYPE_GENERIC },*/
		{ "chart",                     TYPE_CHARTTABLE },
/*		{ "comic or graphic novel",    TYPE_GENERIC },*/
/*		{ "comic strip",               TYPE_GENERIC },*/
		{ "conference publication",    TYPE_PROCEEDINGS },
		{ "database",                  TYPE_ONLINEDATABASE },
/*		{ "dictionary",                TYPE_GENERIC },*/
		{ "diorama",                   TYPE_ARTWORK },
/*		{ "directory",                 TYPE_GENERIC },*/
		{ "discography",               TYPE_AUDIOVISUAL },
/*		{ "drama",                     TYPE_GENERIC },*/
		{ "encyclopedia",              TYPE_BOOK },
/*		{ "essay",                     TYPE_GENERIC }, */
/*		{ "festschrift",               TYPE_GENERIC },*/
		{ "fiction",                   TYPE_BOOK },
		{ "filmography",               TYPE_FILMBROADCAST },
		{ "filmstrip",                 TYPE_FILMBROADCAST },
/*		{ "finding aid",               TYPE_GENERIC },*/
/*		{ "flash card",                TYPE_GENERIC },*/
		{ "folktale",                  TYPE_CLASSICALWORK },
		{ "font",                      TYPE_ELECTRONIC },
/*		{ "game",                      TYPE_GENERIC },*/
		{ "government publication",    TYPE_GOVERNMENT },
		{ "graphic",                   TYPE_FIGURE },
		{ "globe",                     TYPE_MAP },
/*		{ "handbook",                  TYPE_GENERIC },*/
		{ "history",                   TYPE_BOOK },
		{ "hymnal",                    TYPE_BOOK },
/*		{ "humor, satire",             TYPE_GENERIC },*/
/*		{ "index",                     TYPE_GENERIC },*/
/*		{ "instruction",               TYPE_GENERIC },*/
/*		{ "interview",                 TYPE_GENERIC },*/
		{ "issue",                     TYPE_ARTICLE },
		{ "journal",                   TYPE_ARTICLE },
/*		{ "kit",                       TYPE_GENERIC },*/
/*		{ "language instruction",      TYPE_GENERIC },*/
/*		{ "law report or digest",      TYPE_GENERIC },*/
/*		{ "legal article",             TYPE_GENERIC },*/
		{ "legal case and case notes", TYPE_CASE },
		{ "legislation",               TYPE_BILL },
		{ "letter",                    TYPE_COMMUNICATION },
		{ "loose-leaf",                TYPE_GENERIC },
		{ "map",                       TYPE_MAP },
/*		{ "memoir",                    TYPE_GENERIC },*/
/*		{ "microscope slide",          TYPE_GENERIC },*/
/*		{ "model",                     TYPE_GENERIC },*/
		{ "motion picture",            TYPE_AUDIOVISUAL },
		{ "multivolume monograph",     TYPE_BOOK },
		{ "newspaper",                 TYPE_NEWSARTICLE },
		{ "novel",                     TYPE_BOOK },
/*		{ "numeric data",              TYPE_GENERIC },*/
/*		{ "offprint",                  TYPE_GENERIC },*/
		{ "online system or service",  TYPE_ELECTRONIC },
		{ "patent",                    TYPE_PATENT },
		{ "periodical",                TYPE_MAGARTICLE },
		{ "picture",                   TYPE_ARTWORK },
/*		{ "poetry",                    TYPE_GENERIC },*/
		{ "programmed text",           TYPE_PROGRAM },
/*		{ "realia",                    TYPE_GENERIC },*/
		{ "rehearsal",                 TYPE_AUDIOVISUAL },
/*		{ "remote sensing image",      TYPE_GENERIC },*/
/*		{ "reporting",                 TYPE_GENERIC },*/
/*		{ "review",                    TYPE_GENERIC },*/
/*		{ "script",                    TYPE_GENERIC },*/
/*		{ "series",                    TYPE_GENERIC },*/
/*		{ "short story",               TYPE_GENERIC },*/
/*		{ "slide",                     TYPE_GENERIC },*/
		{ "sound",                     TYPE_AUDIOVISUAL },
/*		{ "speech",                    TYPE_GENERIC },*/
/*		{ "standard or specification", TYPE_GENERIC },*/
/*		{ "statistics",                TYPE_GENERIC },*/
/*		{ "survey of literature",      TYPE_GENERIC },*/
		{ "technical drawing",         TYPE_ARTWORK },
		{ "techincal report",          TYPE_REPORT },
		{ "thesis",                    TYPE_THESIS },
/*		{ "toy",                       TYPE_GENERIC },*/
/*		{ "transparency",              TYPE_GENERIC },*/
/*		{ "treaty",                    TYPE_GENERIC },*/
		{ "videorecording",            TYPE_AUDIOVISUAL },
		{ "web site",                  TYPE_ELECTRONIC },
		/* Non-MARC Authority elements */
		{ "academic journal",          TYPE_ARTICLE },
		{ "magazine",                  TYPE_MAGARTICLE },
		{ "hearing",                   TYPE_HEARING },
		{ "Ph.D. thesis",              TYPE_PHDTHESIS },
		{ "Masters thesis",            TYPE_MASTERSTHESIS },
		{ "Diploma thesis",            TYPE_DIPLOMATHESIS },
		{ "Doctoral thesis",           TYPE_DOCTORALTHESIS },
		{ "Habilitation thesis",       TYPE_HABILITATIONTHESIS },
		{ "communication",             TYPE_COMMUNICATION },
		{ "manuscript",                TYPE_MANUSCRIPT },
		{ "report",                    TYPE_REPORT },
		{ "unpublished",               TYPE_UNPUBLISHED },
	};
	int nmatch_genres = sizeof( match_genres ) / sizeof( match_genres[0] );

	int i, j, n, maxlevel, type = TYPE_UNKNOWN;
	char *tag, *data;

	/* Determine type from genre information */
	for ( i=0; i<info->n; ++i ) {
		tag = info->tag[i].data;
		if ( strcasecmp( tag, "GENRE" )!=0 &&
		     strcasecmp( tag, "NGENRE" )!=0 ) continue;
		data = info->data[i].data;
		for ( j=0; j<nmatch_genres; ++j ) {
			if ( !strcasecmp( data, match_genres[j].name ) ) {
				type = match_genres[j].type;
				fields_setused( info, i );
			}
		}
		if ( p->verbose ) {
			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
			fprintf( stderr, "Type from tag '%s' data '%s': ", info->tag[i].data, info->data[i].data );
			write_type( stderr, type );
			fprintf( stderr, "\n" );
		}
		if ( type==TYPE_UNKNOWN ) {
			if ( !strcasecmp( data, "periodical" ) )
				type = TYPE_ARTICLE;
			else if ( !strcasecmp( data, "thesis" ) )
				type = TYPE_THESIS;
			else if ( !strcasecmp( data, "book" ) ) {
				if ( info->level[i]==0 ) type = TYPE_BOOK;
				else type = TYPE_INBOOK;
			}
			else if ( !strcasecmp( data, "collection" ) ) {
				if ( info->level[i]==0 ) type = TYPE_BOOK;
				else type = TYPE_INBOOK;
			}
			if ( type!=TYPE_UNKNOWN ) fields_setused( info, i );
		}
		/* the inbook type should be defined if 'book' in host */
		if ( type==TYPE_BOOK && info->level[i]>0 ) type = TYPE_INBOOK;
	}
	if ( p->verbose ) {
		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
		fprintf( stderr, "Type from genre element: " );
		write_type( stderr, type );
		fprintf( stderr, "\n" );
	}

	/* Determine from resource information */
	if ( type==TYPE_UNKNOWN ) {
		for ( i=0; i<info->n; ++i ) {
			if ( strcasecmp( info->tag[i].data, "RESOURCE" ) )
				continue;
			data = info->data[i].data;
			if ( !strcasecmp( data, "moving image" ) )
				type = TYPE_FILMBROADCAST;
			else if ( !strcasecmp( data, "software, multimedia" ) )
				type = TYPE_PROGRAM;
			if ( type!=TYPE_UNKNOWN ) fields_setused( info, i );
		}
		if ( p->verbose ) {
			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
			fprintf( stderr, "Type from resource element: " );
			write_type( stderr, type );
			fprintf( stderr, "\n" );
		}
	}

	/* Determine from issuance information */
	if ( type==TYPE_UNKNOWN ) {
		for ( i=0; i<info->n; ++i ) {
			if ( strcasecmp( info->tag[i].data, "ISSUANCE" ) )
				continue;
			data = info->data[i].data;
			if ( !strcasecmp( data, "monographic" ) ) {
				if ( info->level[i]==0 ) type = TYPE_BOOK;
				else type = TYPE_INBOOK;
			}
		}
		if ( p->verbose ) {
			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
			fprintf( stderr, "Type from issuance element: " );
			write_type( stderr, type );
			fprintf( stderr, "\n" );
		}
	}

	/* default to generic or book chapter, depending on maxlevel */
	if ( type==TYPE_UNKNOWN ) {
		maxlevel = fields_maxlevel( info );
		if ( maxlevel > 0 ) type = TYPE_INBOOK;
		else {
			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
			fprintf( stderr, "Cannot identify TYPE in reference %lu ", refnum+1 );
			n = fields_find( info, "REFNUM", -1 );
			if ( n!=-1 )
				fprintf( stderr, " %s", info->data[n].data );
			fprintf( stderr, " (defaulting to generic)\n" );
			type = TYPE_GENERIC;
		}
	}

	if ( p->verbose ) {
		if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
		fprintf( stderr, "Final type: " );
		write_type( stderr, type );
		fprintf( stderr, "\n" );
	}
	
	return type;
}