Blame bibutils/wordout.c

Packit 89ede9
/*
Packit 89ede9
 * wordout.c
Packit 89ede9
 * 
Packit 89ede9
 * (Word 2007 format)
Packit 89ede9
 *
Packit 89ede9
 * Copyright (c) Chris Putnam 2007-2018
Packit 89ede9
 *
Packit 89ede9
 * Source code released under the GPL version 2
Packit 89ede9
 *
Packit 89ede9
 */
Packit 89ede9
#include <stdio.h>
Packit 89ede9
#include <stdlib.h>
Packit 89ede9
#include <string.h>
Packit 89ede9
#include "str.h"
Packit 89ede9
#include "fields.h"
Packit 89ede9
#include "utf8.h"
Packit 89ede9
#include "bibformats.h"
Packit 89ede9
Packit 89ede9
static void wordout_writeheader( FILE *outptr, param *p );
Packit 89ede9
static void wordout_writefooter( FILE *outptr );
Packit 89ede9
static int  wordout_write( fields *info, FILE *outptr, param *p, unsigned long numrefs );
Packit 89ede9
Packit 89ede9
void
Packit 89ede9
wordout_initparams( param *p, const char *progname )
Packit 89ede9
{
Packit 89ede9
	p->writeformat      = BIBL_WORD2007OUT;
Packit 89ede9
	p->format_opts      = 0;
Packit 89ede9
	p->charsetout       = BIBL_CHARSET_UNICODE;
Packit 89ede9
	p->charsetout_src   = BIBL_SRC_DEFAULT;
Packit 89ede9
	p->latexout         = 0;
Packit 89ede9
	p->utf8out          = BIBL_CHARSET_UTF8_DEFAULT;
Packit 89ede9
	p->utf8bom          = BIBL_CHARSET_BOM_DEFAULT;
Packit 89ede9
	if ( !p->utf8out )
Packit 89ede9
		p->xmlout   = BIBL_XMLOUT_ENTITIES;
Packit 89ede9
	else
Packit 89ede9
		p->xmlout   = BIBL_XMLOUT_TRUE;
Packit 89ede9
	p->nosplittitle     = 0;
Packit 89ede9
	p->verbose          = 0;
Packit 89ede9
	p->addcount         = 0;
Packit 89ede9
	p->singlerefperfile = 0;
Packit 89ede9
Packit 89ede9
	p->headerf = wordout_writeheader;
Packit 89ede9
	p->footerf = wordout_writefooter;
Packit 89ede9
	p->writef  = wordout_write;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
typedef struct convert {
Packit 89ede9
	char *oldtag;
Packit 89ede9
	char *newtag;
Packit 89ede9
	char *prefix;
Packit 89ede9
	int  code;
Packit 89ede9
} convert;
Packit 89ede9
Packit 89ede9
/*
Packit 89ede9
At the moment 17 unique types of sources are defined:
Packit 89ede9
Packit 89ede9
{code}
Packit 89ede9
	Art
Packit 89ede9
	ArticleInAPeriodical
Packit 89ede9
	Book
Packit 89ede9
	BookSection
Packit 89ede9
	Case
Packit 89ede9
	Conference
Packit 89ede9
	DocumentFromInternetSite
Packit 89ede9
	ElectronicSource
Packit 89ede9
	Film
Packit 89ede9
	InternetSite
Packit 89ede9
	Interview
Packit 89ede9
	JournalArticle
Packit 89ede9
	Report
Packit 89ede9
	Misc
Packit 89ede9
	Patent
Packit 89ede9
	Performance
Packit 89ede9
	Proceedings
Packit 89ede9
	SoundRecording
Packit 89ede9
{code}
Packit 89ede9
Packit 89ede9
*/
Packit 89ede9
Packit 89ede9
enum {
Packit 89ede9
	TYPE_UNKNOWN = 0,
Packit 89ede9
	TYPE_ART,
Packit 89ede9
	TYPE_ARTICLEINAPERIODICAL,
Packit 89ede9
	TYPE_BOOK,
Packit 89ede9
	TYPE_BOOKSECTION,
Packit 89ede9
	TYPE_CASE,
Packit 89ede9
	TYPE_CONFERENCE,
Packit 89ede9
	TYPE_DOCUMENTFROMINTERNETSITE,
Packit 89ede9
	TYPE_ELECTRONICSOURCE,
Packit 89ede9
	TYPE_FILM,
Packit 89ede9
	TYPE_INTERNETSITE,
Packit 89ede9
	TYPE_INTERVIEW,
Packit 89ede9
	TYPE_JOURNALARTICLE,
Packit 89ede9
	TYPE_MISC,
Packit 89ede9
	TYPE_PATENT,
Packit 89ede9
	TYPE_PERFORMANCE,
Packit 89ede9
	TYPE_PROCEEDINGS,
Packit 89ede9
	TYPE_REPORT,
Packit 89ede9
	TYPE_SOUNDRECORDING,
Packit 89ede9
Packit 89ede9
	TYPE_THESIS,
Packit 89ede9
	TYPE_MASTERSTHESIS,
Packit 89ede9
	TYPE_PHDTHESIS,
Packit 89ede9
};
Packit 89ede9
Packit 89ede9
/*
Packit 89ede9
 * fixed output
Packit 89ede9
 */
Packit 89ede9
static void
Packit 89ede9
output_fixed( FILE *outptr, char *tag, char *value, int level )
Packit 89ede9
{
Packit 89ede9
	int i;
Packit 89ede9
	for ( i=0; i
Packit 89ede9
	fprintf( outptr, "<%s>%s</%s>\n", tag, value, tag );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
/* detail output
Packit 89ede9
 *
Packit 89ede9
 */
Packit 89ede9
static void
Packit 89ede9
output_item( fields *info, FILE *outptr, char *tag, char *prefix, int item, int level )
Packit 89ede9
{
Packit 89ede9
	int i;
Packit 89ede9
	if ( item==-1 ) return;
Packit 89ede9
	for ( i=0; i
Packit 89ede9
	fprintf( outptr, "<%s>%s%s</%s>\n",
Packit 89ede9
		tag,
Packit 89ede9
		prefix,
Packit 89ede9
		(char*) fields_value( info, item, FIELDS_CHRP ),
Packit 89ede9
		tag
Packit 89ede9
	);
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_itemv( FILE *outptr, char *tag, char *item, int level )
Packit 89ede9
{
Packit 89ede9
	int i;
Packit 89ede9
	for ( i=0; i
Packit 89ede9
	fprintf( outptr, "<%s>%s</%s>\n", tag, item, tag );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
/* range output
Packit 89ede9
 *
Packit 89ede9
 * <TAG>start-end</TAG>
Packit 89ede9
 *
Packit 89ede9
 */
Packit 89ede9
static void
Packit 89ede9
output_range( FILE *outptr, char *tag, char *start, char *end, int level )
Packit 89ede9
{
Packit 89ede9
	int i;
Packit 89ede9
	if ( start==NULL && end==NULL ) return;
Packit 89ede9
	if ( start==NULL )
Packit 89ede9
		output_itemv( outptr, tag, end, 0 );
Packit 89ede9
	else if ( end==NULL )
Packit 89ede9
		output_itemv( outptr, tag, start, 0 );
Packit 89ede9
	else {
Packit 89ede9
		for ( i=0; i
Packit 89ede9
			fprintf( outptr, " " );
Packit 89ede9
		fprintf( outptr, "<%s>%s-%s</%s>\n", tag, start, end, tag );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_list( fields *info, FILE *outptr, convert *c, int nc )
Packit 89ede9
{
Packit 89ede9
        int i, n;
Packit 89ede9
        for ( i=0; i
Packit 89ede9
                n = fields_find( info, c[i].oldtag, c[i].code );
Packit 89ede9
                if ( n!=FIELDS_NOTFOUND ) output_item( info, outptr, c[i].newtag, c[i].prefix, n, 0 );
Packit 89ede9
        }
Packit 89ede9
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
typedef struct outtype {
Packit 89ede9
	int value;
Packit 89ede9
	char *out;
Packit 89ede9
} outtype;
Packit 89ede9
Packit 89ede9
static
Packit 89ede9
outtype genres[] = {
Packit 89ede9
	{ TYPE_PATENT,           "patent" },
Packit 89ede9
	{ TYPE_REPORT,           "report" },
Packit 89ede9
	{ TYPE_REPORT,           "technical report" },
Packit 89ede9
	{ TYPE_CASE,             "legal case and case notes" },
Packit 89ede9
	{ TYPE_ART,              "art original" },
Packit 89ede9
	{ TYPE_ART,              "art reproduction" },
Packit 89ede9
	{ TYPE_ART,              "comic strip" },
Packit 89ede9
	{ TYPE_ART,              "diorama" },
Packit 89ede9
	{ TYPE_ART,              "graphic" },
Packit 89ede9
	{ TYPE_ART,              "model" },
Packit 89ede9
	{ TYPE_ART,              "picture" },
Packit 89ede9
	{ TYPE_ELECTRONICSOURCE, "electronic" },
Packit 89ede9
	{ TYPE_FILM,             "videorecording" },
Packit 89ede9
	{ TYPE_FILM,             "motion picture" },
Packit 89ede9
	{ TYPE_SOUNDRECORDING,   "sound" },
Packit 89ede9
	{ TYPE_PERFORMANCE,      "rehersal" },
Packit 89ede9
	{ TYPE_INTERNETSITE,     "web site" },
Packit 89ede9
	{ TYPE_INTERVIEW,        "interview" },
Packit 89ede9
	{ TYPE_INTERVIEW,        "communication" },
Packit 89ede9
	{ TYPE_MISC,             "misc" },
Packit 89ede9
};
Packit 89ede9
int ngenres = sizeof( genres ) / sizeof( genres[0] );
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
get_type_from_genre( fields *info )
Packit 89ede9
{
Packit 89ede9
	int type = TYPE_UNKNOWN, i, j, level;
Packit 89ede9
	char *genre, *tag;
Packit 89ede9
	for ( i=0; i<info->n; ++i ) {
Packit 89ede9
		tag = (char *) fields_tag( info, i, FIELDS_CHRP );
Packit 89ede9
		if ( strcasecmp( tag, "GENRE:MARC" ) && strcasecmp( tag, "GENRE:BIBUTILS" ) && strcasecmp( tag, "GENRE:UNKNOWN" ) ) continue;
Packit 89ede9
		genre = (char *) fields_value( info, i, FIELDS_CHRP );
Packit 89ede9
		for ( j=0; j
Packit 89ede9
			if ( !strcasecmp( genres[j].out, genre ) )
Packit 89ede9
				type = genres[j].value;
Packit 89ede9
		}
Packit 89ede9
		if ( type==TYPE_UNKNOWN ) {
Packit 89ede9
			level = info->level[i];
Packit 89ede9
			if ( !strcasecmp( genre, "academic journal" ) ) {
Packit 89ede9
				type = TYPE_JOURNALARTICLE;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( genre, "periodical" ) ) {
Packit 89ede9
				if ( type == TYPE_UNKNOWN )
Packit 89ede9
					type = TYPE_ARTICLEINAPERIODICAL;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( genre, "book" ) ||
Packit 89ede9
				!strcasecmp( genre, "collection" ) ) {
Packit 89ede9
				if ( info->level[i]==0 ) type = TYPE_BOOK;
Packit 89ede9
				else type = TYPE_BOOKSECTION;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( genre, "conference publication" ) ) {
Packit 89ede9
				if ( level==0 ) type=TYPE_CONFERENCE;
Packit 89ede9
				else type = TYPE_PROCEEDINGS;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( genre, "thesis" ) ) {
Packit 89ede9
	                        if ( type==TYPE_UNKNOWN ) type=TYPE_THESIS;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( genre, "Ph.D. thesis" ) ) {
Packit 89ede9
				type = TYPE_PHDTHESIS;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( genre, "Masters thesis" ) ) {
Packit 89ede9
				type = TYPE_MASTERSTHESIS;
Packit 89ede9
			}
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
	return type;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
get_type_from_resource( fields *info )
Packit 89ede9
{
Packit 89ede9
	int type = TYPE_UNKNOWN, i;
Packit 89ede9
	char *tag, *resource;
Packit 89ede9
	for ( i=0; i<info->n; ++i ) {
Packit 89ede9
		tag = (char *) fields_tag( info, i, FIELDS_CHRP );
Packit 89ede9
		if ( strcasecmp( tag, "RESOURCE" ) ) continue;
Packit 89ede9
		resource = (char *) fields_value( info, i, FIELDS_CHRP );
Packit 89ede9
		if ( !strcasecmp( resource, "moving image" ) )
Packit 89ede9
			type = TYPE_FILM;
Packit 89ede9
	}
Packit 89ede9
	return type;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
get_type( fields *info )
Packit 89ede9
{
Packit 89ede9
	int type;
Packit 89ede9
	type = get_type_from_genre( info );
Packit 89ede9
	if ( type==TYPE_UNKNOWN )
Packit 89ede9
		type = get_type_from_resource( info );
Packit 89ede9
	return type;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_titlebits( char *mainttl, char *subttl, FILE *outptr )
Packit 89ede9
{
Packit 89ede9
	if ( mainttl ) fprintf( outptr, "%s", mainttl );
Packit 89ede9
	if ( subttl ) {
Packit 89ede9
		if ( mainttl ) {
Packit 89ede9
			if ( mainttl[ strlen( mainttl ) - 1 ] != '?' )
Packit 89ede9
				fprintf( outptr, ": " );
Packit 89ede9
			else fprintf( outptr, " " );
Packit 89ede9
		}
Packit 89ede9
		fprintf( outptr, "%s", subttl );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_titleinfo( char *mainttl, char *subttl, FILE *outptr, char *tag, int level )
Packit 89ede9
{
Packit 89ede9
	if ( mainttl || subttl ) {
Packit 89ede9
		fprintf( outptr, "<%s>", tag );
Packit 89ede9
		output_titlebits( mainttl, subttl, outptr );
Packit 89ede9
		fprintf( outptr, "</%s>\n", tag );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_generaltitle( fields *info, FILE *outptr, char *tag, int level )
Packit 89ede9
{
Packit 89ede9
	char *ttl       = fields_findv( info, level, FIELDS_CHRP, "TITLE" );
Packit 89ede9
	char *subttl    = fields_findv( info, level, FIELDS_CHRP, "SUBTITLE" );
Packit 89ede9
	char *shrttl    = fields_findv( info, level, FIELDS_CHRP, "SHORTTITLE" );
Packit 89ede9
	char *shrsubttl = fields_findv( info, level, FIELDS_CHRP, "SHORTSUBTITLE" );
Packit 89ede9
Packit 89ede9
	if ( ttl ) {
Packit 89ede9
		output_titleinfo( ttl, subttl, outptr, tag, level );
Packit 89ede9
	}
Packit 89ede9
	else if ( shrttl ) {
Packit 89ede9
		output_titleinfo( shrttl, shrsubttl, outptr, tag, level );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_maintitle( fields *info, FILE *outptr, int level )
Packit 89ede9
{
Packit 89ede9
	char *ttl       = fields_findv( info, level, FIELDS_CHRP, "TITLE" );
Packit 89ede9
	char *subttl    = fields_findv( info, level, FIELDS_CHRP, "SUBTITLE" );
Packit 89ede9
	char *shrttl    = fields_findv( info, level, FIELDS_CHRP, "SHORTTITLE" );
Packit 89ede9
	char *shrsubttl = fields_findv( info, level, FIELDS_CHRP, "SHORTSUBTITLE" );
Packit 89ede9
Packit 89ede9
	if ( ttl ) {
Packit 89ede9
		output_titleinfo( ttl, subttl, outptr, "b:Title", level );
Packit 89ede9
Packit 89ede9
		/* output shorttitle if it's different from normal title */
Packit 89ede9
		if ( shrttl ) {
Packit 89ede9
			if ( !ttl || ( strcmp( shrttl, ttl ) || subttl ) ) {
Packit 89ede9
				fprintf( outptr,  " <b:ShortTitle>" );
Packit 89ede9
				output_titlebits( shrttl, shrsubttl, outptr );
Packit 89ede9
				fprintf( outptr, "</b:ShortTitle>\n" );
Packit 89ede9
			}
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
	else if ( shrttl ) {
Packit 89ede9
		output_titleinfo( shrttl, shrsubttl, outptr, "b:Title", level );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_name_nomangle( FILE *outptr, char *p )
Packit 89ede9
{
Packit 89ede9
	fprintf( outptr, "<b:Person>" );
Packit 89ede9
	fprintf( outptr, "<b:Last>%s</b:Last>", p );
Packit 89ede9
	fprintf( outptr, "</b:Person>\n" );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_name( FILE *outptr, char *p )
Packit 89ede9
{
Packit 89ede9
	str family, part;
Packit 89ede9
	int n=0, npart=0;
Packit 89ede9
Packit 89ede9
	str_init( &family );
Packit 89ede9
	while ( *p && *p!='|' ) str_addchar( &family, *p++ );
Packit 89ede9
	if ( *p=='|' ) p++;
Packit 89ede9
	if ( str_has_value( &family ) ) {
Packit 89ede9
		fprintf( outptr, "<b:Person>" );
Packit 89ede9
		fprintf( outptr, "<b:Last>%s</b:Last>", str_cstr( &family ) );
Packit 89ede9
		n++;
Packit 89ede9
	}
Packit 89ede9
	str_free( &family );
Packit 89ede9
Packit 89ede9
	str_init( &part );
Packit 89ede9
	while ( *p ) {
Packit 89ede9
		while ( *p && *p!='|' ) str_addchar( &part, *p++ );
Packit 89ede9
		if ( str_has_value( &part ) ) {
Packit 89ede9
			if ( n==0 ) fprintf( outptr, "<b:Person>" );
Packit 89ede9
			if ( npart==0 ) 
Packit 89ede9
				fprintf( outptr, "<b:First>%s</b:First>", str_cstr( &part ) );
Packit 89ede9
			else
Packit 89ede9
				fprintf( outptr, "<b:Middle>%s</b:Middle>", str_cstr( &part ) );
Packit 89ede9
			n++;
Packit 89ede9
			npart++;
Packit 89ede9
		}
Packit 89ede9
		if ( *p=='|' ) {
Packit 89ede9
			p++;
Packit 89ede9
			str_empty( &part );
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
	if ( n ) fprintf( outptr, "</b:Person>\n" );
Packit 89ede9
Packit 89ede9
	str_free( &part );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
Packit 89ede9
#define NAME (1)
Packit 89ede9
#define NAME_ASIS (2)
Packit 89ede9
#define NAME_CORP (4)
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
extract_name_and_info( str *outtag, str *intag )
Packit 89ede9
{
Packit 89ede9
	int code = NAME;
Packit 89ede9
	str_strcpy( outtag, intag );
Packit 89ede9
	if ( str_findreplace( outtag, ":ASIS", "" ) ) code = NAME_ASIS;
Packit 89ede9
	if ( str_findreplace( outtag, ":CORP", "" ) ) code = NAME_CORP;
Packit 89ede9
	return code;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_name_type( fields *info, FILE *outptr, int level, 
Packit 89ede9
			char *map[], int nmap, char *tag )
Packit 89ede9
{
Packit 89ede9
	str ntag;
Packit 89ede9
	int i, j, n=0, code, nfields;
Packit 89ede9
	str_init( &ntag );
Packit 89ede9
	nfields = fields_num( info );
Packit 89ede9
	for ( j=0; j
Packit 89ede9
		for ( i=0; i
Packit 89ede9
			code = extract_name_and_info( &ntag, &(info->tag[i]) );
Packit 89ede9
			if ( strcasecmp( str_cstr( &ntag ), map[j] ) ) continue;
Packit 89ede9
			if ( n==0 )
Packit 89ede9
				fprintf( outptr, "<%s><b:NameList>\n", tag );
Packit 89ede9
			if ( code != NAME )
Packit 89ede9
				output_name_nomangle( outptr, (char *) fields_value( info, i, FIELDS_CHRP ) );
Packit 89ede9
			else 
Packit 89ede9
				output_name( outptr, (char *) fields_value( info, i, FIELDS_CHRP ) );
Packit 89ede9
			n++;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
	str_free( &ntag );
Packit 89ede9
	if ( n )
Packit 89ede9
		fprintf( outptr, "</b:NameList></%s>\n", tag );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_names( fields *info, FILE *outptr, int level, int type )
Packit 89ede9
{
Packit 89ede9
	char *authors[] = { "AUTHOR", "WRITER", "ASSIGNEE", "ARTIST",
Packit 89ede9
		"CARTOGRAPHER", "INVENTOR", "ORGANIZER", "DIRECTOR",
Packit 89ede9
		"PERFORMER", "REPORTER", "TRANSLATOR", "ADDRESSEE",
Packit 89ede9
		"2ND_AUTHOR", "3RD_AUTHOR", "SUB_AUTHOR", "COMMITTEE",
Packit 89ede9
		"COURT", "LEGISLATIVEBODY" };
Packit 89ede9
	int nauthors = sizeof( authors ) / sizeof( authors[0] );
Packit 89ede9
Packit 89ede9
	char *editors[] = { "EDITOR" };
Packit 89ede9
	int neditors = sizeof( editors ) / sizeof( editors[0] );
Packit 89ede9
Packit 89ede9
	char author_default[] = "b:Author", inventor[] = "b:Inventor";
Packit 89ede9
	char *author_type = author_default;
Packit 89ede9
Packit 89ede9
	if ( type == TYPE_PATENT ) author_type = inventor;
Packit 89ede9
Packit 89ede9
	fprintf( outptr, "<b:Author>\n" );
Packit 89ede9
	output_name_type( info, outptr, level, authors, nauthors, author_type );
Packit 89ede9
	output_name_type( info, outptr, level, editors, neditors, "b:Editor" );
Packit 89ede9
	fprintf( outptr, "</b:Author>\n" );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_date( fields *info, FILE *outptr, int level )
Packit 89ede9
{
Packit 89ede9
	char *year  = fields_findv_firstof( info, level, FIELDS_CHRP,
Packit 89ede9
			"PARTDATE:YEAR", "DATE:YEAR", NULL );
Packit 89ede9
	char *month = fields_findv_firstof( info, level, FIELDS_CHRP,
Packit 89ede9
			"PARTDATE:MONTH", "DATE:MONTH", NULL );
Packit 89ede9
	char *day   = fields_findv_firstof( info, level, FIELDS_CHRP,
Packit 89ede9
			"PARTDATE:DAY", "DATE:DAY", NULL );
Packit 89ede9
	if ( year )  output_itemv( outptr, "b:Year", year, 0 );
Packit 89ede9
	if ( month ) output_itemv( outptr, "b:Month", month, 0 );
Packit 89ede9
	if ( day )   output_itemv( outptr, "b:Day", day, 0 );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_pages( fields *info, FILE *outptr, int level )
Packit 89ede9
{
Packit 89ede9
	char *sn = fields_findv( info, LEVEL_ANY, FIELDS_CHRP, "PAGES:START" );
Packit 89ede9
	char *en = fields_findv( info, LEVEL_ANY, FIELDS_CHRP, "PAGES:STOP" );
Packit 89ede9
	char *ar = fields_findv( info, LEVEL_ANY, FIELDS_CHRP, "ARTICLENUMBER" );
Packit 89ede9
	if ( sn || en )
Packit 89ede9
		output_range( outptr, "b:Pages", sn, en, level );
Packit 89ede9
	else if ( ar )
Packit 89ede9
		output_range( outptr, "b:Pages", ar, NULL, level );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_includedin( fields *info, FILE *outptr, int type )
Packit 89ede9
{
Packit 89ede9
	if ( type==TYPE_JOURNALARTICLE ) {
Packit 89ede9
		output_generaltitle( info, outptr, "b:JournalName", 1 );
Packit 89ede9
	} else if ( type==TYPE_ARTICLEINAPERIODICAL ) {
Packit 89ede9
		output_generaltitle( info, outptr, "b:PeriodicalTitle", 1 );
Packit 89ede9
	} else if ( type==TYPE_BOOKSECTION ) {
Packit 89ede9
		output_generaltitle( info, outptr, "b:ConferenceName", 1 ); /*??*/
Packit 89ede9
	} else if ( type==TYPE_PROCEEDINGS ) {
Packit 89ede9
		output_generaltitle( info, outptr, "b:ConferenceName", 1 );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
type_is_thesis( int type )
Packit 89ede9
{
Packit 89ede9
	if ( type==TYPE_THESIS ||
Packit 89ede9
	     type==TYPE_PHDTHESIS ||
Packit 89ede9
	     type==TYPE_MASTERSTHESIS )
Packit 89ede9
		return 1;
Packit 89ede9
	else
Packit 89ede9
		return 0;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_thesisdetails( fields *info, FILE *outptr, int type )
Packit 89ede9
{
Packit 89ede9
	char *tag;
Packit 89ede9
	int i, n;
Packit 89ede9
Packit 89ede9
	if ( type==TYPE_PHDTHESIS )
Packit 89ede9
		output_fixed( outptr, "b:ThesisType", "Ph.D. Thesis", 0 );
Packit 89ede9
	else if ( type==TYPE_MASTERSTHESIS ) 
Packit 89ede9
		output_fixed( outptr, "b:ThesisType", "Masters Thesis", 0 );
Packit 89ede9
Packit 89ede9
	n = fields_num( info );
Packit 89ede9
	for ( i=0; i
Packit 89ede9
		tag = fields_tag( info, i, FIELDS_CHRP );
Packit 89ede9
		if ( strcasecmp( tag, "DEGREEGRANTOR" ) &&
Packit 89ede9
			strcasecmp( tag, "DEGREEGRANTOR:ASIS") &
Packit 89ede9
			strcasecmp( tag, "DEGREEGRANTOR:CORP"))
Packit 89ede9
				continue;
Packit 89ede9
		output_item( info, outptr, "b:Institution", "", i, 0 );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static
Packit 89ede9
outtype types[] = {
Packit 89ede9
	{ TYPE_UNKNOWN,                  "Misc" },
Packit 89ede9
	{ TYPE_MISC,                     "Misc" },
Packit 89ede9
	{ TYPE_BOOK,                     "Book" },
Packit 89ede9
	{ TYPE_BOOKSECTION,              "BookSection" },
Packit 89ede9
	{ TYPE_CASE,                     "Case" },
Packit 89ede9
	{ TYPE_CONFERENCE,               "Conference" },
Packit 89ede9
	{ TYPE_ELECTRONICSOURCE,         "ElectronicSource" },
Packit 89ede9
	{ TYPE_FILM,                     "Film" },
Packit 89ede9
	{ TYPE_INTERNETSITE,             "InternetSite" },
Packit 89ede9
	{ TYPE_INTERVIEW,                "Interview" },
Packit 89ede9
	{ TYPE_SOUNDRECORDING,           "SoundRecording" },
Packit 89ede9
	{ TYPE_ARTICLEINAPERIODICAL,     "ArticleInAPeriodical" },
Packit 89ede9
	{ TYPE_DOCUMENTFROMINTERNETSITE, "DocumentFromInternetSite" },
Packit 89ede9
	{ TYPE_JOURNALARTICLE,           "JournalArticle" },
Packit 89ede9
	{ TYPE_REPORT,                   "Report" },
Packit 89ede9
	{ TYPE_PATENT,                   "Patent" },
Packit 89ede9
	{ TYPE_PERFORMANCE,              "Performance" },
Packit 89ede9
	{ TYPE_PROCEEDINGS,              "Proceedings" },
Packit 89ede9
};
Packit 89ede9
static
Packit 89ede9
int ntypes = sizeof( types ) / sizeof( types[0] );
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_type( fields *info, FILE *outptr, int type )
Packit 89ede9
{
Packit 89ede9
	int i, found = 0;
Packit 89ede9
	fprintf( outptr, "<b:SourceType>" );
Packit 89ede9
	for ( i=0; i
Packit 89ede9
		if ( types[i].value!=type ) continue;
Packit 89ede9
		found = 1;
Packit 89ede9
		fprintf( outptr, "%s", types[i].out );
Packit 89ede9
	}
Packit 89ede9
	if ( !found ) {
Packit 89ede9
		if (  type_is_thesis( type ) ) fprintf( outptr, "Report" );
Packit 89ede9
		else fprintf( outptr, "Misc" );
Packit 89ede9
	}
Packit 89ede9
	fprintf( outptr, "</b:SourceType>\n" );
Packit 89ede9
Packit 89ede9
	if ( type_is_thesis( type ) )
Packit 89ede9
		output_thesisdetails( info, outptr, type );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_comments( fields *info, FILE *outptr, int level )
Packit 89ede9
{
Packit 89ede9
	vplist_index i;
Packit 89ede9
	vplist notes;
Packit 89ede9
	char *abs;
Packit 89ede9
Packit 89ede9
	vplist_init( &notes );
Packit 89ede9
Packit 89ede9
	abs = fields_findv( info, level, FIELDS_CHRP, "ABSTRACT" );
Packit 89ede9
	fields_findv_each( info, level, FIELDS_CHRP, &notes, "NOTES" );
Packit 89ede9
Packit 89ede9
	if ( abs || notes.n ) fprintf( outptr, "<b:Comments>" );
Packit 89ede9
	if ( abs ) fprintf( outptr, "%s", abs );
Packit 89ede9
	for ( i=0; i
Packit 89ede9
		fprintf( outptr, "%s", (char*)vplist_get( &notes, i ) );
Packit 89ede9
	if ( abs || notes.n ) fprintf( outptr, "</b:Comments>\n" );
Packit 89ede9
Packit 89ede9
	vplist_free( &notes );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_bibkey( fields *info, FILE *outptr )
Packit 89ede9
{
Packit 89ede9
	char *bibkey = fields_findv_firstof( info, LEVEL_ANY, FIELDS_CHRP,
Packit 89ede9
			"REFNUM", "BIBKEY", NULL );
Packit 89ede9
	if ( bibkey ) output_itemv( outptr, "b:Tag", bibkey, 0 );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_citeparts( fields *info, FILE *outptr, int level, int max, int type )
Packit 89ede9
{
Packit 89ede9
	convert origin[] = {
Packit 89ede9
		{ "ADDRESS",	"b:City",	"", LEVEL_ANY },
Packit 89ede9
		{ "PUBLISHER",	"b:Publisher",	"", LEVEL_ANY },
Packit 89ede9
		{ "EDITION",	"b:Edition",	"", LEVEL_ANY }
Packit 89ede9
	};
Packit 89ede9
	int norigin = sizeof( origin ) / sizeof ( convert );
Packit 89ede9
	
Packit 89ede9
	convert parts[] = {
Packit 89ede9
		{ "VOLUME",          "b:Volume",  "", LEVEL_ANY },
Packit 89ede9
		{ "SECTION",         "b:Section", "", LEVEL_ANY },
Packit 89ede9
		{ "ISSUE",           "b:Issue",   "", LEVEL_ANY },
Packit 89ede9
		{ "NUMBER",          "b:Issue",   "", LEVEL_ANY },
Packit 89ede9
		{ "PUBLICLAWNUMBER", "b:Volume",  "", LEVEL_ANY },
Packit 89ede9
		{ "SESSION",         "b:Issue",   "", LEVEL_ANY },
Packit 89ede9
		{ "URL",             "b:Url",     "", LEVEL_ANY },
Packit 89ede9
		{ "JSTOR",           "b:Url",     "http://www.jstor.org/stable/", LEVEL_ANY },
Packit 89ede9
		{ "ARXIV",           "b:Url",     "http://arxiv.org/abs/",        LEVEL_ANY },
Packit 89ede9
		{ "PMID",            "b:Url",     "http://www.ncbi.nlm.nih.gov/pubmed/", LEVEL_ANY },
Packit 89ede9
		{ "PMC",             "b:Url",     "http://www.ncbi.nlm.nih.gov/pmc/articles/", LEVEL_ANY },
Packit 89ede9
		{ "DOI",             "b:Url",     "https://doi.org/", LEVEL_ANY },
Packit 89ede9
		{ "MRNUMBER",        "b:Url",     "http://www.ams.org/mathscinet-getitem?mr=", LEVEL_ANY },
Packit 89ede9
	};
Packit 89ede9
	int nparts=sizeof(parts)/sizeof(convert);
Packit 89ede9
	
Packit 89ede9
	output_bibkey( info, outptr );
Packit 89ede9
	output_type( info, outptr, type );
Packit 89ede9
	output_list( info, outptr, origin, norigin );
Packit 89ede9
	output_date( info, outptr, level );
Packit 89ede9
	output_includedin( info, outptr, type );
Packit 89ede9
	output_list( info, outptr, parts, nparts );
Packit 89ede9
	output_pages( info, outptr, level );
Packit 89ede9
	output_names( info, outptr, level, type );
Packit 89ede9
	output_maintitle( info, outptr, 0 );
Packit 89ede9
	output_comments( info, outptr, level );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
wordout_write( fields *info, FILE *outptr, param *p, unsigned long numrefs )
Packit 89ede9
{
Packit 89ede9
	int max = fields_maxlevel( info );
Packit 89ede9
	int type = get_type( info );
Packit 89ede9
Packit 89ede9
	fprintf( outptr, "<b:Source>\n" );
Packit 89ede9
	output_citeparts( info, outptr, -1, max, type );
Packit 89ede9
	fprintf( outptr, "</b:Source>\n" );
Packit 89ede9
Packit 89ede9
	fflush( outptr );
Packit 89ede9
Packit 89ede9
	return BIBL_OK;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
wordout_writeheader( FILE *outptr, param *p )
Packit 89ede9
{
Packit 89ede9
	if ( p->utf8bom ) utf8_writebom( outptr );
Packit 89ede9
	fprintf(outptr,"\n");
Packit 89ede9
	fprintf(outptr,"
Packit 89ede9
		"xmlns:b=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\" "
Packit 89ede9
		" xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\" >\n");
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
wordout_writefooter( FILE *outptr )
Packit 89ede9
{
Packit 89ede9
	fprintf(outptr,"</b:Sources>\n");
Packit 89ede9
	fflush( outptr );
Packit 89ede9
}