Blame bibutils/adsout.c

Packit 89ede9
/*
Packit 89ede9
 * adsout.c
Packit 89ede9
 *
Packit 89ede9
 * Copyright (c) Richard Mathar 2007-2018
Packit 89ede9
 * Copyright (c) Chris Putnam 2007-2018
Packit 89ede9
 *
Packit 89ede9
 * Program and 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 <stdint.h>
Packit 89ede9
#include <string.h>
Packit 89ede9
#include <ctype.h>
Packit 89ede9
#include "utf8.h"
Packit 89ede9
#include "str.h"
Packit 89ede9
#include "strsearch.h"
Packit 89ede9
#include "fields.h"
Packit 89ede9
#include "name.h"
Packit 89ede9
#include "title.h"
Packit 89ede9
#include "url.h"
Packit 89ede9
#include "bibformats.h"
Packit 89ede9
Packit 89ede9
static int  adsout_write( fields *in, FILE *fp, param *p, unsigned long refnum );
Packit 89ede9
static void adsout_writeheader( FILE *outptr, param *p );
Packit 89ede9
Packit 89ede9
void
Packit 89ede9
adsout_initparams( param *p, const char *progname )
Packit 89ede9
{
Packit 89ede9
	p->writeformat      = BIBL_ADSABSOUT;
Packit 89ede9
	p->format_opts      = 0;
Packit 89ede9
	p->charsetout       = BIBL_CHARSET_DEFAULT;
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
	p->xmlout           = BIBL_XMLOUT_FALSE;
Packit 89ede9
	p->nosplittitle     = 0;
Packit 89ede9
	p->verbose          = 0;
Packit 89ede9
	p->addcount         = 0;
Packit 89ede9
	p->singlerefperfile = 0;
Packit 89ede9
Packit 89ede9
	if ( p->charsetout == BIBL_CHARSET_UNICODE ) {
Packit 89ede9
		p->utf8out = p->utf8bom = 1;
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	p->headerf = adsout_writeheader;
Packit 89ede9
	p->footerf = NULL;
Packit 89ede9
	p->writef  = adsout_write;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
enum {
Packit 89ede9
	TYPE_UNKNOWN = 0,
Packit 89ede9
	TYPE_GENERIC,
Packit 89ede9
	TYPE_ARTICLE,
Packit 89ede9
	TYPE_MAGARTICLE,
Packit 89ede9
	TYPE_BOOK,
Packit 89ede9
	TYPE_INBOOK,
Packit 89ede9
	TYPE_INPROCEEDINGS,
Packit 89ede9
	TYPE_HEARING,
Packit 89ede9
	TYPE_BILL,
Packit 89ede9
	TYPE_CASE,
Packit 89ede9
	TYPE_NEWSPAPER,
Packit 89ede9
	TYPE_COMMUNICATION,
Packit 89ede9
	TYPE_BROADCAST,
Packit 89ede9
	TYPE_MANUSCRIPT,
Packit 89ede9
	TYPE_REPORT,
Packit 89ede9
	TYPE_THESIS,
Packit 89ede9
	TYPE_MASTERSTHESIS,
Packit 89ede9
	TYPE_PHDTHESIS,
Packit 89ede9
	TYPE_DIPLOMATHESIS,
Packit 89ede9
	TYPE_DOCTORALTHESIS,
Packit 89ede9
	TYPE_HABILITATIONTHESIS,
Packit 89ede9
	TYPE_LICENTIATETHESIS,
Packit 89ede9
	TYPE_PATENT,
Packit 89ede9
	TYPE_PROGRAM
Packit 89ede9
};
Packit 89ede9
Packit 89ede9
typedef struct match_type {
Packit 89ede9
	char *name;
Packit 89ede9
	int type;
Packit 89ede9
} match_type;
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
get_type( fields *in )
Packit 89ede9
{
Packit 89ede9
	match_type match_genres[] = {
Packit 89ede9
		{ "academic journal",          TYPE_ARTICLE },
Packit 89ede9
		{ "magazine",                  TYPE_MAGARTICLE },
Packit 89ede9
		{ "conference publication",    TYPE_INPROCEEDINGS },
Packit 89ede9
		{ "hearing",                   TYPE_HEARING },
Packit 89ede9
		{ "Ph.D. thesis",              TYPE_PHDTHESIS },
Packit 89ede9
		{ "Masters thesis",            TYPE_MASTERSTHESIS },
Packit 89ede9
		{ "Diploma thesis",            TYPE_DIPLOMATHESIS },
Packit 89ede9
		{ "Doctoral thesis",           TYPE_DOCTORALTHESIS },
Packit 89ede9
		{ "Habilitation thesis",       TYPE_HABILITATIONTHESIS },
Packit 89ede9
		{ "Licentiate thesis",         TYPE_LICENTIATETHESIS },
Packit 89ede9
		{ "legislation",               TYPE_BILL },
Packit 89ede9
		{ "newspaper",                 TYPE_NEWSPAPER },
Packit 89ede9
		{ "communication",             TYPE_COMMUNICATION },
Packit 89ede9
		{ "manuscript",                TYPE_MANUSCRIPT },
Packit 89ede9
		{ "unpublished",               TYPE_MANUSCRIPT },
Packit 89ede9
		{ "report",                    TYPE_REPORT },
Packit 89ede9
		{ "technical report",          TYPE_REPORT },
Packit 89ede9
		{ "legal case and case notes", TYPE_CASE },
Packit 89ede9
		{ "patent",                    TYPE_PATENT },
Packit 89ede9
	};
Packit 89ede9
	int nmatch_genres = sizeof( match_genres ) / sizeof( match_genres[0] );
Packit 89ede9
Packit 89ede9
	char *tag, *data;
Packit 89ede9
	int i, j, type = TYPE_UNKNOWN;
Packit 89ede9
Packit 89ede9
	for ( i=0; i<in->n; ++i ) {
Packit 89ede9
		tag = in->tag[i].data;
Packit 89ede9
		if ( strcasecmp( tag, "GENRE:MARC" ) &&
Packit 89ede9
		     strcasecmp( tag, "GENRE:BIBUTILS" ) &&
Packit 89ede9
		     strcasecmp( tag, "GENRE:UNKNOWN" ) ) continue;
Packit 89ede9
		data = in->data[i].data;
Packit 89ede9
		for ( j=0; j
Packit 89ede9
			if ( !strcasecmp( data, match_genres[j].name ) ) {
Packit 89ede9
				type = match_genres[j].type;
Packit 89ede9
				fields_setused( in, i );
Packit 89ede9
			}
Packit 89ede9
		}
Packit 89ede9
		if ( type==TYPE_UNKNOWN ) {
Packit 89ede9
			if ( !strcasecmp( data, "periodical" ) )
Packit 89ede9
				type = TYPE_ARTICLE;
Packit 89ede9
			else if ( !strcasecmp( data, "thesis" ) )
Packit 89ede9
				type = TYPE_THESIS;
Packit 89ede9
			else if ( !strcasecmp( data, "book" ) ) {
Packit 89ede9
				if ( in->level[i]==0 ) type = TYPE_BOOK;
Packit 89ede9
				else type = TYPE_INBOOK;
Packit 89ede9
			}
Packit 89ede9
			else if ( !strcasecmp( data, "collection" ) ) {
Packit 89ede9
				if ( in->level[i]==0 ) type = TYPE_BOOK;
Packit 89ede9
				else type = TYPE_INBOOK;
Packit 89ede9
			}
Packit 89ede9
			if ( type!=TYPE_UNKNOWN ) fields_setused( in, i );
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
	if ( type==TYPE_UNKNOWN ) {
Packit 89ede9
		for ( i=0; i<in->n; ++i ) {
Packit 89ede9
			if ( strcasecmp( in->tag[i].data, "RESOURCE" ) )
Packit 89ede9
				continue;
Packit 89ede9
			data = in->data[i].data;
Packit 89ede9
			if ( !strcasecmp( data, "moving image" ) )
Packit 89ede9
				type = TYPE_BROADCAST;
Packit 89ede9
			else if ( !strcasecmp( data, "software, multimedia" ) )
Packit 89ede9
				type = TYPE_PROGRAM;
Packit 89ede9
			if ( type!=TYPE_UNKNOWN ) fields_setused( in, i );
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	/* default to generic */
Packit 89ede9
	if ( type==TYPE_UNKNOWN ) type = TYPE_GENERIC;
Packit 89ede9
	
Packit 89ede9
	return type;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
append_title( fields *in, char *ttl, char *sub, char *adstag, int level, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	str fulltitle, *title, *subtitle, *vol, *iss, *sn, *en, *ar;
Packit 89ede9
	int fstatus, output = 0;
Packit 89ede9
Packit 89ede9
	str_init( &fulltitle );
Packit 89ede9
Packit 89ede9
	title     = fields_findv( in, level, FIELDS_STRP, ttl );
Packit 89ede9
	subtitle  = fields_findv( in, level, FIELDS_STRP, sub );
Packit 89ede9
Packit 89ede9
	if ( str_has_value( title ) ) {
Packit 89ede9
Packit 89ede9
		output = 1;
Packit 89ede9
Packit 89ede9
		title_combine( &fulltitle, title, subtitle );
Packit 89ede9
Packit 89ede9
		vol = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "VOLUME" );
Packit 89ede9
		if ( str_has_value( vol ) ) {
Packit 89ede9
			str_strcatc( &fulltitle, ", vol. " );
Packit 89ede9
			str_strcat( &fulltitle, vol );
Packit 89ede9
		}
Packit 89ede9
Packit 89ede9
		iss = fields_findv_firstof( in, LEVEL_ANY, FIELDS_STRP, "ISSUE",
Packit 89ede9
			"NUMBER", NULL );
Packit 89ede9
		if ( str_has_value( iss ) ) {
Packit 89ede9
			str_strcatc( &fulltitle, ", no. " );
Packit 89ede9
			str_strcat( &fulltitle, iss );
Packit 89ede9
		}
Packit 89ede9
Packit 89ede9
		sn = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "PAGES:START" );
Packit 89ede9
		en = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "PAGES:STOP" );
Packit 89ede9
		ar = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "ARTICLENUMBER" );
Packit 89ede9
Packit 89ede9
		if ( str_has_value( sn ) ) {
Packit 89ede9
			if ( str_has_value( en ) ) {
Packit 89ede9
				str_strcatc( &fulltitle, ", pp. " );
Packit 89ede9
			} else {
Packit 89ede9
				str_strcatc( &fulltitle, ", p. " );
Packit 89ede9
			}
Packit 89ede9
			str_strcat( &fulltitle, sn );
Packit 89ede9
		} else if ( str_has_value( ar ) ) {
Packit 89ede9
			str_strcatc( &fulltitle, ", p. " );
Packit 89ede9
			str_strcat( &fulltitle, ar );
Packit 89ede9
		}
Packit 89ede9
		if ( str_has_value( en ) ) {
Packit 89ede9
			str_addchar( &fulltitle, '-' );
Packit 89ede9
			str_strcat( &fulltitle, en );
Packit 89ede9
		}
Packit 89ede9
Packit 89ede9
		if ( str_memerr( &fulltitle ) ) {
Packit 89ede9
			*status = BIBL_ERR_MEMERR;
Packit 89ede9
			goto out;
Packit 89ede9
		}
Packit 89ede9
Packit 89ede9
		fstatus = fields_add( out, adstag, str_cstr( &fulltitle ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
Packit 89ede9
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
out:
Packit 89ede9
	str_free( &fulltitle );
Packit 89ede9
Packit 89ede9
	return output;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_titles( fields *in, int type, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	int added;
Packit 89ede9
	if ( type==TYPE_ARTICLE || type==TYPE_MAGARTICLE ) {
Packit 89ede9
		added = append_title( in, "TITLE", "SUBTITLE", "%J", LEVEL_HOST, out, status );
Packit 89ede9
		if ( added==0 )
Packit 89ede9
			(void) append_title( in, "SHORTTITLE", "SHORTSUBTITLE", "%J", LEVEL_HOST, out, status );
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_people( fields *in, char *tag1, char *tag2, char *tag3, char *adstag, int level, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	str oneperson, allpeople;
Packit 89ede9
	vplist_index i;
Packit 89ede9
	int fstatus;
Packit 89ede9
	vplist a;
Packit 89ede9
Packit 89ede9
	str_init( &oneperson );
Packit 89ede9
	str_init( &allpeople );
Packit 89ede9
	vplist_init( &a );
Packit 89ede9
Packit 89ede9
	fields_findv_eachof( in, level, FIELDS_CHRP, &a, tag1, tag2, tag3, NULL );
Packit 89ede9
	if ( a.n ) {
Packit 89ede9
		for ( i=0; i
Packit 89ede9
			if ( i!=0 ) str_strcatc( &allpeople, "; " );
Packit 89ede9
			name_build_withcomma( &oneperson, (char *) vplist_get( &a, i) );
Packit 89ede9
			str_strcat( &allpeople, &oneperson );
Packit 89ede9
		}
Packit 89ede9
		fstatus = fields_add( out, adstag, str_cstr( &allpeople ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	vplist_free( &a );
Packit 89ede9
	str_free( &oneperson );
Packit 89ede9
	str_free( &allpeople );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_pages( fields *in, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	str *sn, *en, *ar;
Packit 89ede9
	int fstatus;
Packit 89ede9
Packit 89ede9
	sn = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "PAGES:START" );
Packit 89ede9
	en = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "PAGES:STOP" );
Packit 89ede9
	ar = fields_findv( in, LEVEL_ANY, FIELDS_STRP, "ARTICLENUMBER" );
Packit 89ede9
Packit 89ede9
	if ( str_has_value( sn ) ) {
Packit 89ede9
		fstatus = fields_add( out, "%P", str_cstr( sn ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) {
Packit 89ede9
			*status = BIBL_ERR_MEMERR;
Packit 89ede9
			return;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	else if ( str_has_value( ar ) ) {
Packit 89ede9
		fstatus = fields_add( out, "%P", str_cstr( ar ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) {
Packit 89ede9
			*status = BIBL_ERR_MEMERR;
Packit 89ede9
			return;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	if ( str_has_value( en ) ) {
Packit 89ede9
		fstatus = fields_add( out, "%L", str_cstr( en ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) {
Packit 89ede9
			*status = BIBL_ERR_MEMERR;
Packit 89ede9
			return;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
mont2mont( const char *m )
Packit 89ede9
{
Packit 89ede9
	static char *monNames[]= { "jan", "feb", "mar", "apr", "may", 
Packit 89ede9
			"jun", "jul", "aug", "sep", "oct", "nov", "dec" };
Packit 89ede9
	int i;
Packit 89ede9
	if ( isdigit( (unsigned char)m[0] ) ) return atoi( m );
Packit 89ede9
        else {
Packit 89ede9
		for ( i=0; i<12; i++ ) {
Packit 89ede9
			if ( !strncasecmp( m, monNames[i], 3 ) ) return i+1;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
        return 0;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
get_month( fields *in, int level )
Packit 89ede9
{
Packit 89ede9
	str *month;
Packit 89ede9
Packit 89ede9
	month = fields_findv_firstof( in, level, FIELDS_STRP, "DATE:MONTH", "PARTDATE:MONTH", NULL );
Packit 89ede9
	if ( str_has_value( month ) ) return mont2mont( month->data );
Packit 89ede9
	else return 0;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_date( fields *in, char *adstag, int level, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	int month, fstatus;
Packit 89ede9
	char outstr[1000];
Packit 89ede9
	str *year;
Packit 89ede9
Packit 89ede9
	year = fields_findv_firstof( in, level, FIELDS_STRP, "DATE:YEAR", "PARTDATE:YEAR", NULL );
Packit 89ede9
	if ( str_has_value( year ) ) {
Packit 89ede9
		month = get_month( in, level );
Packit 89ede9
		sprintf( outstr, "%02d/%s", month, str_cstr( year ) );
Packit 89ede9
		fstatus = fields_add( out, adstag, outstr, LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
#include "adsout_journals.c"
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output_4digit_value( char *pos, long long n )
Packit 89ede9
{
Packit 89ede9
	char buf[6];
Packit 89ede9
	n = n % 10000; /* truncate to 0->9999, will fit in buf[6] */
Packit 89ede9
#ifdef WIN32
Packit 89ede9
	sprintf( buf, "%I64d", n );
Packit 89ede9
#else
Packit 89ede9
	sprintf( buf, "%lld", n );
Packit 89ede9
#endif
Packit 89ede9
	if ( n < 10 )        strncpy( pos+3, buf, 1 );
Packit 89ede9
	else if ( n < 100 )  strncpy( pos+2, buf, 2 );
Packit 89ede9
	else if ( n < 1000 ) strncpy( pos+1, buf, 3 );
Packit 89ede9
	else                 strncpy( pos,   buf, 4 );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static char
Packit 89ede9
get_firstinitial( fields *in )
Packit 89ede9
{
Packit 89ede9
	char *name;
Packit 89ede9
	int n;
Packit 89ede9
Packit 89ede9
	n = fields_find( in, "AUTHOR", LEVEL_MAIN );
Packit 89ede9
	if ( n==FIELDS_NOTFOUND ) n = fields_find( in, "AUTHOR", LEVEL_ANY );
Packit 89ede9
Packit 89ede9
	if ( n!=FIELDS_NOTFOUND ) {
Packit 89ede9
		name = fields_value( in, n, FIELDS_CHRP );
Packit 89ede9
		return name[0];
Packit 89ede9
	} else return '\0';
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
get_journalabbr( fields *in )
Packit 89ede9
{
Packit 89ede9
	char *jrnl;
Packit 89ede9
	int n, j;
Packit 89ede9
Packit 89ede9
	n = fields_find( in, "TITLE", LEVEL_HOST );
Packit 89ede9
	if ( n!=FIELDS_NOTFOUND ) {
Packit 89ede9
		jrnl = fields_value( in, n, FIELDS_CHRP );
Packit 89ede9
		for ( j=0; j
Packit 89ede9
			if ( !strcasecmp( jrnl, journals[j]+6 ) )
Packit 89ede9
				return j;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
	return -1;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_Rtag( fields *in, char *adstag, int type, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	char outstr[20], ch;
Packit 89ede9
	int n, i, fstatus;
Packit 89ede9
	long long page;
Packit 89ede9
Packit 89ede9
	strcpy( outstr, "..................." );
Packit 89ede9
Packit 89ede9
	/** YYYY */
Packit 89ede9
	n = fields_find( in, "DATE:YEAR", LEVEL_ANY );
Packit 89ede9
	if ( n==FIELDS_NOTFOUND ) n = fields_find( in, "PARTDATE:YEAR", LEVEL_ANY );
Packit 89ede9
	if ( n!=FIELDS_NOTFOUND ) output_4digit_value( outstr, atoi( fields_value( in, n, FIELDS_CHRP ) ) );
Packit 89ede9
Packit 89ede9
	/** JJJJ */
Packit 89ede9
	n = get_journalabbr( in );
Packit 89ede9
	if ( n!=-1 ) {
Packit 89ede9
		i = 0;
Packit 89ede9
		while ( i<5 && journals[n][i]!=' ' && journals[n][i]!='\t' ) {
Packit 89ede9
			outstr[4+i] = journals[n][i];
Packit 89ede9
			i++;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	/** VVVV */
Packit 89ede9
	n = fields_find( in, "VOLUME", LEVEL_ANY );
Packit 89ede9
	if ( n!=FIELDS_NOTFOUND ) output_4digit_value( outstr+9, atoi( fields_value( in, n, FIELDS_CHRP ) ) );
Packit 89ede9
Packit 89ede9
	/** MPPPP */
Packit 89ede9
	n = fields_find( in, "PAGES:START", LEVEL_ANY );
Packit 89ede9
	if ( n==FIELDS_NOTFOUND ) n = fields_find( in, "ARTICLENUMBER", LEVEL_ANY );
Packit 89ede9
	if ( n!=FIELDS_NOTFOUND ) {
Packit 89ede9
		page = atoll( fields_value( in, n, FIELDS_CHRP ) );
Packit 89ede9
		output_4digit_value( outstr+14, page );
Packit 89ede9
		if ( page>=10000 ) {
Packit 89ede9
			ch = 'a' + (page/10000);
Packit 89ede9
			outstr[13] = ch;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	/** A */
Packit 89ede9
        ch = toupper( (unsigned char) get_firstinitial( in ) );
Packit 89ede9
	if ( ch!='\0' ) outstr[18] = ch;
Packit 89ede9
Packit 89ede9
	fstatus = fields_add( out, adstag, outstr, LEVEL_MAIN );
Packit 89ede9
	if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_easyall( fields *in, char *tag, char *adstag, int level, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	vplist_index i;
Packit 89ede9
	int fstatus;
Packit 89ede9
	vplist a;
Packit 89ede9
Packit 89ede9
	vplist_init( &a );
Packit 89ede9
Packit 89ede9
	fields_findv_each( in, level, FIELDS_CHRP, &a, tag );
Packit 89ede9
Packit 89ede9
	for ( i=0; i
Packit 89ede9
		fstatus = fields_add( out, adstag, (char*) vplist_get( &a, i ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) {
Packit 89ede9
			*status = BIBL_ERR_MEMERR;
Packit 89ede9
			goto out;
Packit 89ede9
		}
Packit 89ede9
	}
Packit 89ede9
out:
Packit 89ede9
	vplist_free( &a );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_easy( fields *in, char *tag, char *adstag, int level, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	char *value;
Packit 89ede9
	int fstatus;
Packit 89ede9
Packit 89ede9
	value = fields_findv( in, level, FIELDS_CHRP, tag );
Packit 89ede9
	if ( value && value[0]!='\0' ) {
Packit 89ede9
		fstatus = fields_add( out, adstag, value, LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_keys( fields *in, char *tag, char *adstag, int level, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	vplist_index i;
Packit 89ede9
	str allkeys;
Packit 89ede9
	int fstatus;
Packit 89ede9
	vplist a;
Packit 89ede9
Packit 89ede9
	str_init( &allkeys );
Packit 89ede9
	vplist_init( &a );
Packit 89ede9
Packit 89ede9
	fields_findv_each( in, level, FIELDS_CHRP, &a, tag );
Packit 89ede9
Packit 89ede9
	if ( a.n ) {
Packit 89ede9
		for ( i=0; i
Packit 89ede9
			if ( i>0 ) str_strcatc( &allkeys, ", " );
Packit 89ede9
			str_strcatc( &allkeys, (char *) vplist_get( &a, i ) );
Packit 89ede9
		}
Packit 89ede9
		fstatus = fields_add( out, adstag, str_cstr( &allkeys ), LEVEL_MAIN );
Packit 89ede9
		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	str_free( &allkeys );
Packit 89ede9
	vplist_free( &a );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_urls( fields *in, fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	int lstatus;
Packit 89ede9
	slist types;
Packit 89ede9
Packit 89ede9
	lstatus = slist_init_valuesc( &types, "URL", "DOI", "PMID", "PMC", "ARXIV", "JSTOR", "MRNUMBER", "FILEATTACH", "FIGATTACH", NULL );
Packit 89ede9
	if ( lstatus!=SLIST_OK ) {
Packit 89ede9
		*status = BIBL_ERR_MEMERR;
Packit 89ede9
		return;
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	*status = urls_merge_and_add( in, LEVEL_ANY, out, "%U", LEVEL_MAIN, &types );
Packit 89ede9
Packit 89ede9
	slist_free( &types );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
append_trailer( fields *out, int *status )
Packit 89ede9
{
Packit 89ede9
	int fstatus;
Packit 89ede9
Packit 89ede9
	fstatus = fields_add( out, "%W", "PHY", LEVEL_MAIN );
Packit 89ede9
	if ( fstatus!=FIELDS_OK ) {
Packit 89ede9
		*status = BIBL_ERR_MEMERR;
Packit 89ede9
		return;
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	fstatus = fields_add( out, "%G", "AUTHOR", LEVEL_MAIN );
Packit 89ede9
	if ( fstatus!=FIELDS_OK ) {
Packit 89ede9
		*status = BIBL_ERR_MEMERR;
Packit 89ede9
		return;
Packit 89ede9
	}
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
output( FILE *fp, fields *out )
Packit 89ede9
{
Packit 89ede9
	char *tag, *value;
Packit 89ede9
	int i;
Packit 89ede9
Packit 89ede9
	for ( i=0; i<out->n; ++i ) {
Packit 89ede9
		tag   = fields_tag( out, i, FIELDS_CHRP );
Packit 89ede9
		value = fields_value( out, i, FIELDS_CHRP );
Packit 89ede9
		fprintf( fp, "%s %s\n", tag, value );
Packit 89ede9
	}
Packit 89ede9
Packit 89ede9
	fprintf( fp, "\n" );
Packit 89ede9
	fflush( fp );
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
append_data( fields *in, fields *out )
Packit 89ede9
{
Packit 89ede9
	int type, status = BIBL_OK;
Packit 89ede9
Packit 89ede9
	fields_clearused( in );
Packit 89ede9
	type = get_type( in );
Packit 89ede9
Packit 89ede9
	append_people ( in, "AUTHOR", "AUTHOR:ASIS", "AUTHOR:CORP", "%A", LEVEL_MAIN, out, &status );
Packit 89ede9
	append_people ( in, "EDITOR", "EDITOR:ASIS", "EDITOR:CORP", "%E", LEVEL_ANY,  out, &status );
Packit 89ede9
	append_easy   ( in, "TITLE",       "%T", LEVEL_ANY, out, &status );
Packit 89ede9
	append_titles ( in, type, out, &status );
Packit 89ede9
	append_date   ( in,               "%D", LEVEL_ANY, out, &status );
Packit 89ede9
	append_easy   ( in, "VOLUME",     "%V", LEVEL_ANY, out, &status );
Packit 89ede9
	append_easy   ( in, "ISSUE",      "%N", LEVEL_ANY, out, &status );
Packit 89ede9
	append_easy   ( in, "NUMBER",     "%N", LEVEL_ANY, out, &status );
Packit 89ede9
	append_easy   ( in, "LANGUAGE",   "%M", LEVEL_ANY, out, &status );
Packit 89ede9
	append_easyall( in, "NOTES",      "%X", LEVEL_ANY, out, &status );
Packit 89ede9
	append_easy   ( in, "ABSTRACT",   "%B", LEVEL_ANY, out, &status );
Packit 89ede9
	append_keys   ( in, "KEYWORD",    "%K", LEVEL_ANY, out, &status );
Packit 89ede9
	append_urls   ( in, out, &status );
Packit 89ede9
	append_pages  ( in, out, &status );
Packit 89ede9
	append_easyall( in, "DOI",        "%Y", LEVEL_ANY, out, &status );
Packit 89ede9
	append_trailer( out, &status );
Packit 89ede9
	append_Rtag   ( in, "%R", type, out, &status );
Packit 89ede9
Packit 89ede9
	return status;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static int
Packit 89ede9
adsout_write( fields *in, FILE *fp, param *p, unsigned long refnum )
Packit 89ede9
{
Packit 89ede9
	int status;
Packit 89ede9
	fields out;
Packit 89ede9
Packit 89ede9
	fields_init( &out );
Packit 89ede9
Packit 89ede9
	status = append_data( in, &out );
Packit 89ede9
	if ( status==BIBL_OK ) output( fp, &out );
Packit 89ede9
Packit 89ede9
	fields_free( &out );
Packit 89ede9
Packit 89ede9
	return status;
Packit 89ede9
}
Packit 89ede9
Packit 89ede9
static void
Packit 89ede9
adsout_writeheader( FILE *outptr, param *p )
Packit 89ede9
{
Packit 89ede9
	if ( p->utf8bom ) utf8_writebom( outptr );
Packit 89ede9
}
Packit 89ede9