|
Packit |
89ede9 |
/*
|
|
Packit |
89ede9 |
* biblatexin.c
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Copyright (c) Chris Putnam 2008-2018
|
|
Packit |
89ede9 |
* Copyright (c) Johannes Wilm 2010-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 <string.h>
|
|
Packit |
89ede9 |
#include <ctype.h>
|
|
Packit |
89ede9 |
#include "is_ws.h"
|
|
Packit |
89ede9 |
#include "strsearch.h"
|
|
Packit |
89ede9 |
#include "str.h"
|
|
Packit |
89ede9 |
#include "utf8.h"
|
|
Packit |
89ede9 |
#include "str_conv.h"
|
|
Packit |
89ede9 |
#include "fields.h"
|
|
Packit |
89ede9 |
#include "slist.h"
|
|
Packit |
89ede9 |
#include "name.h"
|
|
Packit |
89ede9 |
#include "reftypes.h"
|
|
Packit |
89ede9 |
#include "bibformats.h"
|
|
Packit |
89ede9 |
#include "generic.h"
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
extern variants biblatex_all[];
|
|
Packit |
89ede9 |
extern int biblatex_nall;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static slist find = { 0, 0, 0, NULL };
|
|
Packit |
89ede9 |
static slist replace = { 0, 0, 0, NULL };
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*****************************************************
|
|
Packit |
89ede9 |
PUBLIC: void biblatexin_initparams()
|
|
Packit |
89ede9 |
*****************************************************/
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int biblatexin_convertf( fields *bibin, fields *info, int reftype, param *p );
|
|
Packit |
89ede9 |
static int biblatexin_processf( fields *bibin, char *data, char *filename, long nref, param *p );
|
|
Packit |
89ede9 |
static int biblatexin_cleanf( bibl *bin, param *p );
|
|
Packit |
89ede9 |
static int biblatexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, str *line, str *reference, int *fcharset );
|
|
Packit |
89ede9 |
static int biblatexin_typef( fields *bibin, char *filename, int nrefs, param *p );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
void
|
|
Packit |
89ede9 |
biblatexin_initparams( param *p, const char *progname )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
p->readformat = BIBL_BIBLATEXIN;
|
|
Packit |
89ede9 |
p->charsetin = BIBL_CHARSET_DEFAULT;
|
|
Packit |
89ede9 |
p->charsetin_src = BIBL_SRC_DEFAULT;
|
|
Packit |
89ede9 |
p->latexin = 1;
|
|
Packit |
89ede9 |
p->xmlin = 0;
|
|
Packit |
89ede9 |
p->utf8in = 0;
|
|
Packit |
89ede9 |
p->nosplittitle = 0;
|
|
Packit |
89ede9 |
p->verbose = 0;
|
|
Packit |
89ede9 |
p->addcount = 0;
|
|
Packit |
89ede9 |
p->output_raw = 0;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
p->readf = biblatexin_readf;
|
|
Packit |
89ede9 |
p->processf = biblatexin_processf;
|
|
Packit |
89ede9 |
p->cleanf = biblatexin_cleanf;
|
|
Packit |
89ede9 |
p->typef = biblatexin_typef;
|
|
Packit |
89ede9 |
p->convertf = biblatexin_convertf;
|
|
Packit |
89ede9 |
p->all = biblatex_all;
|
|
Packit |
89ede9 |
p->nall = biblatex_nall;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
slist_init( &(p->asis) );
|
|
Packit |
89ede9 |
slist_init( &(p->corps) );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !progname ) p->progname = NULL;
|
|
Packit |
89ede9 |
else p->progname = strdup( progname );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*****************************************************
|
|
Packit |
89ede9 |
PUBLIC: int biblatexin_readf()
|
|
Packit |
89ede9 |
*****************************************************/
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*
|
|
Packit |
89ede9 |
* readf can "read too far", so we store this information in line, thus
|
|
Packit |
89ede9 |
* the next new text is in line, either from having read too far or
|
|
Packit |
89ede9 |
* from the next chunk obtained via str_fget()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* return 1 on success, 0 on error/end-of-file
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
readmore( FILE *fp, char *buf, int bufsize, int *bufpos, str *line )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( line->len ) return 1;
|
|
Packit |
89ede9 |
else return str_fget( fp, buf, bufsize, bufpos, line );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*
|
|
Packit |
89ede9 |
* readf()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* returns zero if cannot get reference and hit end of-file
|
|
Packit |
89ede9 |
* returns 1 if last reference in file, 2 if reference within file
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_readf( FILE *fp, char *buf, int bufsize, int *bufpos, str *line, str *reference, int *fcharset )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int haveref = 0;
|
|
Packit |
89ede9 |
char *p;
|
|
Packit |
89ede9 |
while ( haveref!=2 && readmore( fp, buf, bufsize, bufpos, line ) ) {
|
|
Packit |
89ede9 |
if ( line->len == 0 ) continue; /* blank line */
|
|
Packit |
89ede9 |
p = &(line->data[0]);
|
|
Packit |
89ede9 |
p = skip_ws( p );
|
|
Packit |
89ede9 |
if ( *p == '%' ) { /* commented out line */
|
|
Packit |
89ede9 |
str_empty( line );
|
|
Packit |
89ede9 |
continue;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( *p == '@' ) haveref++;
|
|
Packit |
89ede9 |
if ( haveref && haveref<2 ) {
|
|
Packit |
89ede9 |
str_strcatc( reference, p );
|
|
Packit |
89ede9 |
str_addchar( reference, '\n' );
|
|
Packit |
89ede9 |
str_empty( line );
|
|
Packit |
89ede9 |
} else if ( !haveref ) str_empty( line );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
*fcharset = CHARSET_UNKNOWN;
|
|
Packit |
89ede9 |
return haveref;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*****************************************************
|
|
Packit |
89ede9 |
PUBLIC: int biblatexin_processf()
|
|
Packit |
89ede9 |
*****************************************************/
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static char *
|
|
Packit |
89ede9 |
process_biblatextype( char *p, str *type )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
str tmp;
|
|
Packit |
89ede9 |
str_init( &tmp );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( *p=='@' ) p++;
|
|
Packit |
89ede9 |
p = str_cpytodelim( &tmp, p, "{( \t\r\n", 0 );
|
|
Packit |
89ede9 |
p = skip_ws( p );
|
|
Packit |
89ede9 |
if ( *p=='{' || *p=='(' ) p++;
|
|
Packit |
89ede9 |
p = skip_ws( p );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( str_has_value( &tmp ) ) str_strcpy( type, &tmp );
|
|
Packit |
89ede9 |
else str_empty( type );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_free( &tmp );
|
|
Packit |
89ede9 |
return p;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static char *
|
|
Packit |
89ede9 |
process_biblatexid( char *p, str *id )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
char *start_p = p;
|
|
Packit |
89ede9 |
str tmp;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_init( &tmp );
|
|
Packit |
89ede9 |
p = str_cpytodelim( &tmp, p, ",", 1 );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( str_has_value( &tmp ) ) {
|
|
Packit |
89ede9 |
if ( strchr( tmp.data, '=' ) ) {
|
|
Packit |
89ede9 |
/* Endnote writes biblatex files w/o fields, try to
|
|
Packit |
89ede9 |
* distinguish via presence of an equal sign.... if
|
|
Packit |
89ede9 |
* it's there, assume that it's a tag/data pair instead
|
|
Packit |
89ede9 |
* and roll back.
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
p = start_p;
|
|
Packit |
89ede9 |
str_empty( id );
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
str_strcpy( id, &tmp );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
str_empty( id );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_free( &tmp );
|
|
Packit |
89ede9 |
return skip_ws( p );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static char *
|
|
Packit |
89ede9 |
biblatex_tag( char *p, str *tag )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
p = str_cpytodelim( tag, skip_ws( p ), "= \t\r\n", 0 );
|
|
Packit |
89ede9 |
return skip_ws( p );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static char *
|
|
Packit |
89ede9 |
biblatex_data( char *p, fields *bibin, slist *tokens, long nref, param *pm )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
unsigned int nbracket = 0, nquotes = 0;
|
|
Packit |
89ede9 |
char *startp = p;
|
|
Packit |
89ede9 |
str tok, *s;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_init( &tok );
|
|
Packit |
89ede9 |
while ( p && *p ) {
|
|
Packit |
89ede9 |
if ( !nquotes && !nbracket ) {
|
|
Packit |
89ede9 |
if ( *p==',' || *p=='=' || *p=='}' || *p==')' )
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( *p=='\"' && nbracket==0 && ( p==startp || *(p-1)!='\\' ) ) {
|
|
Packit |
89ede9 |
nquotes = !nquotes;
|
|
Packit |
89ede9 |
str_addchar( &tok, *p );
|
|
Packit |
89ede9 |
if ( !nquotes ) {
|
|
Packit |
89ede9 |
s = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !s ) { p = NULL; goto outerr; }
|
|
Packit |
89ede9 |
str_empty( &tok );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
} else if ( *p=='#' && !nquotes && !nbracket ) {
|
|
Packit |
89ede9 |
if ( str_has_value( &tok ) ) {
|
|
Packit |
89ede9 |
s = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !s ) { p = NULL; goto outerr; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_strcpyc( &tok, "#" );
|
|
Packit |
89ede9 |
s = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !s ) { p = NULL; goto outerr; }
|
|
Packit |
89ede9 |
str_empty( &tok );
|
|
Packit |
89ede9 |
} else if ( *p=='{' && !nquotes && ( p==startp || *(p-1)!='\\' ) ) {
|
|
Packit |
89ede9 |
nbracket++;
|
|
Packit |
89ede9 |
str_addchar( &tok, *p );
|
|
Packit |
89ede9 |
} else if ( *p=='}' && !nquotes && ( p==startp || *(p-1)!='\\' ) ) {
|
|
Packit |
89ede9 |
nbracket--;
|
|
Packit |
89ede9 |
str_addchar( &tok, *p );
|
|
Packit |
89ede9 |
if ( nbracket==0 ) {
|
|
Packit |
89ede9 |
s = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !s ) { p = NULL; goto outerr; }
|
|
Packit |
89ede9 |
str_empty( &tok );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
} else if ( !is_ws( *p ) || nquotes || nbracket ) {
|
|
Packit |
89ede9 |
if ( !is_ws( *p ) ) str_addchar( &tok, *p );
|
|
Packit |
89ede9 |
else {
|
|
Packit |
89ede9 |
if ( tok.len!=0 && *p!='\n' && *p!='\r' )
|
|
Packit |
89ede9 |
str_addchar( &tok, *p );
|
|
Packit |
89ede9 |
else if ( tok.len!=0 && (*p=='\n' || *p=='\r')) {
|
|
Packit |
89ede9 |
str_addchar( &tok, ' ' );
|
|
Packit |
89ede9 |
while ( is_ws( *(p+1) ) ) p++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
} else if ( is_ws( *p ) ) {
|
|
Packit |
89ede9 |
if ( str_has_value( &tok ) ) {
|
|
Packit |
89ede9 |
s = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !s ) { p = NULL; goto outerr; }
|
|
Packit |
89ede9 |
str_empty( &tok );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
p++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
if ( nbracket!=0 ) {
|
|
Packit |
89ede9 |
fprintf( stderr, "%s: Mismatch in number of brackets in reference %ld\n", pm->progname, nref );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( nquotes!=0 ) {
|
|
Packit |
89ede9 |
fprintf( stderr, "%s: Mismatch in number of quotes in reference %ld\n", pm->progname, nref );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( str_has_value( &tok ) ) {
|
|
Packit |
89ede9 |
s = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !s ) p = NULL;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
outerr:
|
|
Packit |
89ede9 |
str_free( &tok );
|
|
Packit |
89ede9 |
return p;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* replace_strings()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* do string replacement -- only if unprotected by quotation marks or curly brackets
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
replace_strings( slist *tokens, fields *bibin, long nref, param *pm )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int i, n, ok;
|
|
Packit |
89ede9 |
char *q;
|
|
Packit |
89ede9 |
str *s;
|
|
Packit |
89ede9 |
i = 0;
|
|
Packit |
89ede9 |
while ( i < tokens->n ) {
|
|
Packit |
89ede9 |
s = slist_str( tokens, i );
|
|
Packit |
89ede9 |
if ( !strcmp( s->data, "#" ) ) {
|
|
Packit |
89ede9 |
} else if ( s->data[0]!='\"' && s->data[0]!='{' ) {
|
|
Packit |
89ede9 |
n = slist_find( &find, s );
|
|
Packit |
89ede9 |
if ( n!=-1 ) {
|
|
Packit |
89ede9 |
str_strcpy( s, slist_str( &replace, n ) );
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
q = s->data;
|
|
Packit |
89ede9 |
ok = 1;
|
|
Packit |
89ede9 |
while ( *q && ok ) {
|
|
Packit |
89ede9 |
if ( !isdigit( *q ) ) ok = 0;
|
|
Packit |
89ede9 |
q++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( !ok ) {
|
|
Packit |
89ede9 |
fprintf( stderr, "%s: Warning: Non-numeric "
|
|
Packit |
89ede9 |
"BibTeX elements should be in quotations or "
|
|
Packit |
89ede9 |
"curly brackets in reference %ld\n", pm->progname, nref );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
i++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
string_concatenate( slist *tokens, fields *bibin, long nref, param *pm )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int i, status;
|
|
Packit |
89ede9 |
str *s, *t;
|
|
Packit |
89ede9 |
i = 0;
|
|
Packit |
89ede9 |
while ( i < tokens->n ) {
|
|
Packit |
89ede9 |
s = slist_str( tokens, i );
|
|
Packit |
89ede9 |
if ( !strcmp( str_cstr( s ), "#" ) ) {
|
|
Packit |
89ede9 |
if ( i==0 || i==tokens->n-1 ) {
|
|
Packit |
89ede9 |
fprintf( stderr, "%s: Warning: Stray string concatenation "
|
|
Packit |
89ede9 |
"('#' character) in reference %ld\n", pm->progname, nref );
|
|
Packit |
89ede9 |
status = slist_remove( tokens, i );
|
|
Packit |
89ede9 |
if ( status!=SLIST_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
continue;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
s = slist_str( tokens, i-1 );
|
|
Packit |
89ede9 |
if ( s->data[0]!='\"' && s->data[s->len-1]!='\"' )
|
|
Packit |
89ede9 |
fprintf( stderr, "%s: Warning: String concentation should "
|
|
Packit |
89ede9 |
"be used in context of quotations marks in reference %ld\n", pm->progname, nref );
|
|
Packit |
89ede9 |
t = slist_str( tokens, i+1 );
|
|
Packit |
89ede9 |
if ( t->data[0]!='\"' && t->data[s->len-1]!='\"' )
|
|
Packit |
89ede9 |
fprintf( stderr, "%s: Warning: String concentation should "
|
|
Packit |
89ede9 |
"be used in context of quotations marks in reference %ld\n", pm->progname, nref );
|
|
Packit |
89ede9 |
if ( ( s->data[s->len-1]=='\"' && t->data[0]=='\"') || (s->data[s->len-1]=='}' && t->data[0]=='{') ) {
|
|
Packit |
89ede9 |
str_trimend( s, 1 );
|
|
Packit |
89ede9 |
str_trimbegin( t, 1 );
|
|
Packit |
89ede9 |
str_strcat( s, t );
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
str_strcat( s, t );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
status = slist_remove( tokens, i );
|
|
Packit |
89ede9 |
if ( status!=SLIST_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
status = slist_remove( tokens, i );
|
|
Packit |
89ede9 |
if ( status!=SLIST_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
} else i++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static char *
|
|
Packit |
89ede9 |
process_biblatexline( char *p, str *tag, str *data, uchar stripquotes, long nref, param *pm )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int i, status;
|
|
Packit |
89ede9 |
slist tokens;
|
|
Packit |
89ede9 |
str *s;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_empty( data );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
p = biblatex_tag( p, tag );
|
|
Packit |
89ede9 |
if ( str_is_empty( tag ) ) {
|
|
Packit |
89ede9 |
/* ...skip this line */
|
|
Packit |
89ede9 |
while ( *p && *p!='\n' && *p!='\r' ) p++;
|
|
Packit |
89ede9 |
while ( *p=='\n' || *p=='\r' ) p++;
|
|
Packit |
89ede9 |
return p;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
slist_init( &tokens );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( *p=='=' ) p = biblatex_data( p+1, NULL, &tokens, nref, pm );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
replace_strings( &tokens, NULL, nref, pm );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
status = string_concatenate( &tokens, NULL, nref, pm );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) {
|
|
Packit |
89ede9 |
p = NULL;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
s = slist_str( &tokens, i );
|
|
Packit |
89ede9 |
if ( ( stripquotes && s->data[0]=='\"' && s->data[s->len-1]=='\"' ) ||
|
|
Packit |
89ede9 |
( s->data[0]=='{' && s->data[s->len-1]=='}' ) ) {
|
|
Packit |
89ede9 |
str_trimbegin( s, 1 );
|
|
Packit |
89ede9 |
str_trimend( s, 1 );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_strcat( data, slist_str( &tokens, i ) );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
slist_free( &tokens );
|
|
Packit |
89ede9 |
return p;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
process_cite( fields *bibin, char *p, char *filename, long nref, param *pm )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus, status = BIBL_OK;
|
|
Packit |
89ede9 |
str type, id, tag, data;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
strs_init( &type, &id, &tag, &data, NULL );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
p = process_biblatextype( p, &type );
|
|
Packit |
89ede9 |
p = process_biblatexid( p, &id );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( str_is_empty( &type ) || str_is_empty( &id ) ) goto out;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
fstatus = fields_add( bibin, "INTERNAL_TYPE", str_cstr( &type ), 0 );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
fstatus = fields_add( bibin, "REFNUM", str_cstr( &id ), 0 );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
while ( *p ) {
|
|
Packit |
89ede9 |
p = process_biblatexline( p, &tag, &data, 1, nref, pm );
|
|
Packit |
89ede9 |
if ( !p ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
/* no anonymous or empty fields allowed */
|
|
Packit |
89ede9 |
if ( str_has_value( &tag ) && str_has_value( &data ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibin, str_cstr( &tag ), str_cstr( &data ), 0 );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
strs_empty( &tag, &data, NULL );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
strs_free( &type, &id, &tag, &data, NULL );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* process_string()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Handle lines like:
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* '@STRING{TL = {Tetrahedron Lett.}}'
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* p should point to just after '@STRING'
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* In BibTeX, if a string is defined several times, the last one is kept.
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
process_string( char *p, long nref, param *pm )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int n, status = BIBL_OK;
|
|
Packit |
89ede9 |
str s1, s2, *s;
|
|
Packit |
89ede9 |
strs_init( &s1, &s2, NULL );
|
|
Packit |
89ede9 |
while ( *p && *p!='{' && *p!='(' ) p++;
|
|
Packit |
89ede9 |
if ( *p=='{' || *p=='(' ) p++;
|
|
Packit |
89ede9 |
(void) process_biblatexline( skip_ws( p ), &s1, &s2, 0, nref, pm );
|
|
Packit |
89ede9 |
if ( str_has_value( &s2 ) ) {
|
|
Packit |
89ede9 |
str_findreplace( &s2, "\\ ", " " );
|
|
Packit |
89ede9 |
if ( str_memerr( &s2 ) ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( str_has_value( &s1 ) ) {
|
|
Packit |
89ede9 |
n = slist_find( &find, &s1 );
|
|
Packit |
89ede9 |
if ( n==-1 ) {
|
|
Packit |
89ede9 |
s = slist_add( &find, &s1 );
|
|
Packit |
89ede9 |
if ( s==NULL ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
if ( str_has_value( &s2 ) ) s = slist_add( &replace, &s2 );
|
|
Packit |
89ede9 |
else s = slist_addc( &replace, "" );
|
|
Packit |
89ede9 |
if ( s==NULL ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
if ( str_has_value( &s2 ) ) s = slist_set( &replace, n, &s2 );
|
|
Packit |
89ede9 |
else s = slist_setc( &replace, n, "" );
|
|
Packit |
89ede9 |
if ( s==NULL ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
strs_free( &s1, &s2, NULL );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_processf( fields *bibin, char *data, char *filename, long nref, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( !strncasecmp( data, "@STRING", 7 ) ) {
|
|
Packit |
89ede9 |
process_string( data+7, nref, p );
|
|
Packit |
89ede9 |
return 0;
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
process_cite( bibin, data, filename, nref, p );
|
|
Packit |
89ede9 |
return 1;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*****************************************************
|
|
Packit |
89ede9 |
PUBLIC: void biblatexin_cleanf()
|
|
Packit |
89ede9 |
*****************************************************/
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
biblatex_process_tilde( str *s )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
char *p, *q;
|
|
Packit |
89ede9 |
int n = 0;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
p = q = s->data;
|
|
Packit |
89ede9 |
if ( !p ) return;
|
|
Packit |
89ede9 |
while ( *p ) {
|
|
Packit |
89ede9 |
if ( *p=='~' ) {
|
|
Packit |
89ede9 |
*q = ' ';
|
|
Packit |
89ede9 |
} else if ( *p=='\\' && *(p+1)=='~' ) {
|
|
Packit |
89ede9 |
n++;
|
|
Packit |
89ede9 |
p++;
|
|
Packit |
89ede9 |
*q = '~';
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
*q = *p;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
p++;
|
|
Packit |
89ede9 |
q++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
*q = '\0';
|
|
Packit |
89ede9 |
s->len -= n;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
biblatex_process_bracket( str *s )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
char *p, *q;
|
|
Packit |
89ede9 |
int n = 0;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
p = q = s->data;
|
|
Packit |
89ede9 |
if ( !p ) return;
|
|
Packit |
89ede9 |
while ( *p ) {
|
|
Packit |
89ede9 |
if ( *p=='\\' && ( *(p+1)=='{' || *(p+1)=='}' ) ) {
|
|
Packit |
89ede9 |
n++;
|
|
Packit |
89ede9 |
p++;
|
|
Packit |
89ede9 |
*q = *p;
|
|
Packit |
89ede9 |
q++;
|
|
Packit |
89ede9 |
} else if ( *p=='{' || *p=='}' ) {
|
|
Packit |
89ede9 |
n++;
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
*q = *p;
|
|
Packit |
89ede9 |
q++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
p++;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
*q = '\0';
|
|
Packit |
89ede9 |
s->len -= n;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatex_cleantoken( str *s )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
/* 'textcomp' annotations */
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textit", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textbf", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textsl", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textsc", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textsf", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\texttt", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textsubscript", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textsuperscript", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\emph", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\url", "" );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* Other text annotations */
|
|
Packit |
89ede9 |
str_findreplace( s, "\\it ", "" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\em ", "" );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_findreplace( s, "\\%", "%" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\$", "$" );
|
|
Packit |
89ede9 |
while ( str_findreplace( s, " ", " " ) ) {}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* 'textcomp' annotations that we don't want to substitute on output*/
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textdollar", "$" );
|
|
Packit |
89ede9 |
str_findreplace( s, "\\textunderscore", "_" );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
biblatex_process_bracket( s );
|
|
Packit |
89ede9 |
biblatex_process_tilde( s );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !str_memerr( s ) ) return BIBL_OK;
|
|
Packit |
89ede9 |
else return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatex_split( slist *tokens, str *s )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int i, n = s->len, nbrackets = 0, status = BIBL_OK;
|
|
Packit |
89ede9 |
str tok, *t;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_init( &tok );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
if ( s->data[i]=='{' && ( i==0 || s->data[i-1]!='\\' ) ) {
|
|
Packit |
89ede9 |
nbrackets++;
|
|
Packit |
89ede9 |
str_addchar( &tok, '{' );
|
|
Packit |
89ede9 |
} else if ( s->data[i]=='}' && ( i==0 || s->data[i-1]!='\\' ) ) {
|
|
Packit |
89ede9 |
nbrackets--;
|
|
Packit |
89ede9 |
str_addchar( &tok, '}' );
|
|
Packit |
89ede9 |
} else if ( !is_ws( s->data[i] ) || nbrackets ) {
|
|
Packit |
89ede9 |
str_addchar( &tok, s->data[i] );
|
|
Packit |
89ede9 |
} else if ( is_ws( s->data[i] ) ) {
|
|
Packit |
89ede9 |
if ( str_memerr( &tok ) ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
if ( str_has_value( &tok ) ) {
|
|
Packit |
89ede9 |
t = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !t ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_empty( &tok );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( str_has_value( &tok ) ) {
|
|
Packit |
89ede9 |
if ( str_memerr( &tok ) ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
t = slist_add( tokens, &tok );
|
|
Packit |
89ede9 |
if ( !t ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
for ( i=0; i<tokens->n; ++i ) {
|
|
Packit |
89ede9 |
t = slist_str( tokens, i );
|
|
Packit |
89ede9 |
str_trimstartingws( t );
|
|
Packit |
89ede9 |
str_trimendingws( t );
|
|
Packit |
89ede9 |
if ( str_memerr( t ) ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
str_free( &tok );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_addtitleurl( fields *info, str *in )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus, status = BIBL_OK;
|
|
Packit |
89ede9 |
char *p;
|
|
Packit |
89ede9 |
str s;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_init( &s );
|
|
Packit |
89ede9 |
/* skip past "\href{" */
|
|
Packit |
89ede9 |
p = str_cpytodelim( &s, in->data + 6, "}", 1 );
|
|
Packit |
89ede9 |
if ( str_memerr( &s ) ) {
|
|
Packit |
89ede9 |
status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
fstatus = fields_add( info, "URL", s.data, 0 );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) {
|
|
Packit |
89ede9 |
status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
(void) str_cpytodelim( &s, p, "", 0 );
|
|
Packit |
89ede9 |
if ( str_memerr( &s ) ) {
|
|
Packit |
89ede9 |
status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_swapstrings( &s, in );
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
str_free( &s );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
is_name_tag( str *tag )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( str_has_value( tag ) ) {
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "author" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "editor" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "editorb" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "editorc" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "director" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "producer" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "execproducer" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "writer" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "redactor" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "annotator" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "commentator" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "translator" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "foreword" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "afterword" ) ) return 1;
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "introduction" ) ) return 1;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return 0;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
is_url_tag( str *tag )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( str_has_value( tag ) ) {
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( tag ), "url" ) ) return 1;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return 0;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_cleandata( str *tag, str *s, fields *info, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
slist tokens;
|
|
Packit |
89ede9 |
str *tok;
|
|
Packit |
89ede9 |
int i, status = BIBL_OK;
|
|
Packit |
89ede9 |
if ( str_is_empty( s ) ) return status;
|
|
Packit |
89ede9 |
/* protect url from undergoing any parsing */
|
|
Packit |
89ede9 |
if ( is_url_tag( tag ) ) return status;
|
|
Packit |
89ede9 |
slist_init( &tokens );
|
|
Packit |
89ede9 |
biblatex_split( &tokens, s );
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
if ( !strncasecmp(slist_cstr( &tokens, i ), "\\href{", 6 )) {
|
|
Packit |
89ede9 |
status = biblatexin_addtitleurl( info, slist_str( &tokens, i ) );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( p && p->latexin && !is_name_tag( tag ) ) {
|
|
Packit |
89ede9 |
status = biblatex_cleantoken( slist_str( &tokens, i ) );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_empty( s );
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
tok = slist_str( &tokens, i );
|
|
Packit |
89ede9 |
if ( i>0 ) str_addchar( s, ' ' );
|
|
Packit |
89ede9 |
str_strcat( s, tok );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
slist_free( &tokens );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static long
|
|
Packit |
89ede9 |
biblatexin_findref( bibl *bin, char *citekey )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int n;
|
|
Packit |
89ede9 |
long i;
|
|
Packit |
89ede9 |
for ( i=0; i<bin->nrefs; ++i ) {
|
|
Packit |
89ede9 |
n = fields_find( bin->ref[i], "refnum", LEVEL_ANY );
|
|
Packit |
89ede9 |
if ( n==FIELDS_NOTFOUND ) continue;
|
|
Packit |
89ede9 |
if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return -1;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
biblatexin_nocrossref( bibl *bin, long i, int n, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int n1 = fields_find( bin->ref[i], "REFNUM", LEVEL_ANY );
|
|
Packit |
89ede9 |
if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
|
|
Packit |
89ede9 |
fprintf( stderr, "Cannot find cross-reference '%s'", bin->ref[i]->data[n].data);
|
|
Packit |
89ede9 |
if ( n1!=FIELDS_NOTFOUND )
|
|
Packit |
89ede9 |
fprintf( stderr, " for reference '%s'", bin->ref[i]->data[n1].data );
|
|
Packit |
89ede9 |
fprintf( stderr, "\n" );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_crossref_oneref( fields *ref, fields *cross )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int j, nl, ntype, fstatus;
|
|
Packit |
89ede9 |
char *type, *nt, *nd;
|
|
Packit |
89ede9 |
ntype = fields_find( ref, "INTERNAL_TYPE", LEVEL_ANY );
|
|
Packit |
89ede9 |
type = ( char * ) fields_value( ref, ntype, FIELDS_CHRP_NOUSE );
|
|
Packit |
89ede9 |
for ( j=0; j<cross->n; ++j ) {
|
|
Packit |
89ede9 |
nt = ( char * ) fields_tag( cross, j, FIELDS_CHRP_NOUSE );
|
|
Packit |
89ede9 |
if ( !strcasecmp( nt, "INTERNAL_TYPE" ) ) continue;
|
|
Packit |
89ede9 |
if ( !strcasecmp( nt, "REFNUM" ) ) continue;
|
|
Packit |
89ede9 |
if ( !strcasecmp( nt, "TITLE" ) ) {
|
|
Packit |
89ede9 |
if ( !strcasecmp( type, "Inproceedings" ) ||
|
|
Packit |
89ede9 |
!strcasecmp( type, "Incollection" ) )
|
|
Packit |
89ede9 |
nt = "booktitle";
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
nd = ( char * ) fields_value( cross, j, FIELDS_CHRP_NOUSE );
|
|
Packit |
89ede9 |
nl = fields_level( cross, j ) + 1;
|
|
Packit |
89ede9 |
fstatus = fields_add( ref, nt, nd, nl );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_crossref( bibl *bin, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int n, ncross, status = BIBL_OK;
|
|
Packit |
89ede9 |
fields *ref, *cross;
|
|
Packit |
89ede9 |
long i;
|
|
Packit |
89ede9 |
for ( i=0; i<bin->nrefs; ++i ) {
|
|
Packit |
89ede9 |
ref = bin->ref[i];
|
|
Packit |
89ede9 |
n = fields_find( ref, "CROSSREF", LEVEL_ANY );
|
|
Packit |
89ede9 |
if ( n==FIELDS_NOTFOUND ) continue;
|
|
Packit |
89ede9 |
fields_setused( ref, n );
|
|
Packit |
89ede9 |
ncross = biblatexin_findref(bin, (char*)fields_value(ref,n, FIELDS_CHRP_NOUSE));
|
|
Packit |
89ede9 |
if ( ncross==-1 ) {
|
|
Packit |
89ede9 |
biblatexin_nocrossref( bin, i, n, p );
|
|
Packit |
89ede9 |
continue;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
cross = bin->ref[ncross];
|
|
Packit |
89ede9 |
status = biblatexin_crossref_oneref( ref, cross );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_cleanref( fields *bibin, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int i, n, status;
|
|
Packit |
89ede9 |
str *t, *d;
|
|
Packit |
89ede9 |
n = fields_num( bibin );
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
t = fields_tag( bibin, i, FIELDS_STRP_NOUSE );
|
|
Packit |
89ede9 |
d = fields_value( bibin, i, FIELDS_STRP_NOUSE );
|
|
Packit |
89ede9 |
status = biblatexin_cleandata( t, d, bibin, p );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) return status;
|
|
Packit |
89ede9 |
if ( !strsearch( str_cstr( t ), "AUTHORS" ) ) {
|
|
Packit |
89ede9 |
str_findreplace( d, "\n", " " );
|
|
Packit |
89ede9 |
str_findreplace( d, "\r", " " );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
else if ( !strsearch( str_cstr( t ), "ABSTRACT" ) ||
|
|
Packit |
89ede9 |
!strsearch( str_cstr( t ), "SUMMARY" ) ||
|
|
Packit |
89ede9 |
!strsearch( str_cstr( t ), "NOTE" ) ) {
|
|
Packit |
89ede9 |
str_findreplace( d, "\n", "" );
|
|
Packit |
89ede9 |
str_findreplace( d, "\r", "" );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_cleanf( bibl *bin, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int status;
|
|
Packit |
89ede9 |
long i;
|
|
Packit |
89ede9 |
for ( i=0; i<bin->nrefs; ++i ) {
|
|
Packit |
89ede9 |
status = biblatexin_cleanref( bin->ref[i], p );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
status = biblatexin_crossref( bin, p );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*****************************************************
|
|
Packit |
89ede9 |
PUBLIC: void biblatexin_typef()
|
|
Packit |
89ede9 |
*****************************************************/
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_typef( fields *bibin, char *filename, int nrefs, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int ntypename, nrefname, is_default;
|
|
Packit |
89ede9 |
char *refname = "", *typename="";
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
ntypename = fields_find( bibin, "INTERNAL_TYPE", LEVEL_MAIN );
|
|
Packit |
89ede9 |
nrefname = fields_find( bibin, "REFNUM", LEVEL_MAIN );
|
|
Packit |
89ede9 |
if ( nrefname!=FIELDS_NOTFOUND ) refname = fields_value( bibin, nrefname, FIELDS_CHRP_NOUSE );
|
|
Packit |
89ede9 |
if ( ntypename!=FIELDS_NOTFOUND ) typename = fields_value( bibin, ntypename, FIELDS_CHRP_NOUSE );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
return get_reftype( typename, nrefs, p->progname, p->all, p->nall, refname, &is_default, REFTYPE_CHATTY );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*****************************************************
|
|
Packit |
89ede9 |
PUBLIC: int biblatexin_convertf(), returns BIBL_OK or BIBL_ERR_MEMERR
|
|
Packit |
89ede9 |
*****************************************************/
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* get_title_elements()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* find all of the biblatex title elements for the current level
|
|
Packit |
89ede9 |
* internal "TITLE" -> "title", "booktitle", "maintitle"
|
|
Packit |
89ede9 |
* internal "SUBTITLE" -> "subtitle", "booksubtitle", "mainsubtitle"
|
|
Packit |
89ede9 |
* internal "TITLEADDON" -> "titleaddon", "booktitleaddon", "maintitleaddon"
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* place in ttl, subttl, and ttladdon strings
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* return 1 if an element is found, 0 if not
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
get_title_elements( fields *bibin, int currlevel, int reftype, variants *all, int nall, str *ttl, str *subttl, str *ttladdon )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int nfields, process, level, i;
|
|
Packit |
89ede9 |
str *t, *d;
|
|
Packit |
89ede9 |
char *newtag;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
strs_empty( ttl, subttl, ttladdon, NULL );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
nfields = fields_num( bibin );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* ...skip already used titles */
|
|
Packit |
89ede9 |
if ( fields_used( bibin, i ) ) continue;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* ...skip empty elements */
|
|
Packit |
89ede9 |
t = fields_tag ( bibin, i, FIELDS_STRP_NOUSE );
|
|
Packit |
89ede9 |
d = fields_value( bibin, i, FIELDS_STRP_NOUSE );
|
|
Packit |
89ede9 |
if ( d->len == 0 ) continue;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !translate_oldtag( t->data, reftype, all, nall, &process, &level, &newtag ) )
|
|
Packit |
89ede9 |
continue;
|
|
Packit |
89ede9 |
if ( process != TITLE ) continue;
|
|
Packit |
89ede9 |
if ( level != currlevel ) continue;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
fields_setused( bibin, i );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !strcasecmp( newtag, "TITLE" ) ) {
|
|
Packit |
89ede9 |
if ( str_has_value( ttl ) ) str_addchar( ttl, ' ' );
|
|
Packit |
89ede9 |
str_strcat( ttl, d );
|
|
Packit |
89ede9 |
} else if ( !strcasecmp( newtag, "SUBTITLE" ) ) {
|
|
Packit |
89ede9 |
if ( str_has_value( subttl ) ) str_addchar( subttl, ' ' );
|
|
Packit |
89ede9 |
str_strcat( subttl, d );
|
|
Packit |
89ede9 |
} else if ( !strcasecmp( newtag, "TITLEADDON" ) ) {
|
|
Packit |
89ede9 |
if ( str_has_value( ttladdon ) ) str_addchar( ttladdon, ' ' );
|
|
Packit |
89ede9 |
str_strcat( ttladdon, d );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
return ( ttl->len>0 || subttl->len > 0 || ttladdon->len > 0 );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* attach_subtitle()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Add subtitle (if exists) to the title
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
attach_subtitle( str *title, str *subtitle )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( str_has_value( subtitle ) ) {
|
|
Packit |
89ede9 |
if ( str_has_value( title ) ) {
|
|
Packit |
89ede9 |
if ( title->data[title->len-1]!=':' && title->data[title->len-1]!='?' )
|
|
Packit |
89ede9 |
str_addchar( title, ':' );
|
|
Packit |
89ede9 |
str_addchar( title, ' ' );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_strcat( title, subtitle );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* attach_addon()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Add titleaddon (if exists) to the title.
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
attach_addon( str *title, str *addon )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( str_has_value( addon ) ) {
|
|
Packit |
89ede9 |
if ( str_has_value( title ) ) {
|
|
Packit |
89ede9 |
if ( title->data[title->len-1]!='.' )
|
|
Packit |
89ede9 |
str_addchar( title, '.' );
|
|
Packit |
89ede9 |
str_addchar( title, ' ' );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
str_strcat( title, addon );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
process_combined_title( fields *info, str *ttl, str *subttl, str *ttladdon, int currlevel )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus, status = BIBL_OK;
|
|
Packit |
89ede9 |
str combined;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_init( &combined );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_strcpy( &combined, ttl );
|
|
Packit |
89ede9 |
attach_subtitle( &combined, subttl );
|
|
Packit |
89ede9 |
attach_addon( &combined, ttladdon );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( str_memerr( &combined ) ) {
|
|
Packit |
89ede9 |
status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
fstatus = fields_add( info, "TITLE", combined.data, currlevel );
|
|
Packit |
89ede9 |
if ( fstatus==FIELDS_OK ) status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
str_free( &combined );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
process_separated_title( fields *info, str *ttl, str *subttl, str *ttladdon, int currlevel )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus;
|
|
Packit |
89ede9 |
if ( str_has_value( ttladdon ) ) {
|
|
Packit |
89ede9 |
if ( subttl->len ) attach_addon( subttl, ttladdon );
|
|
Packit |
89ede9 |
else attach_addon( ttl, ttladdon );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( str_has_value( ttl ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( info, "TITLE", str_cstr( ttl ), currlevel );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( str_has_value( subttl ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( info, "SUBTITLE", str_cstr( subttl ), currlevel );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
process_title_all( fields *bibin, fields *info, int reftype, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int currlevel, found, status = BIBL_OK;
|
|
Packit |
89ede9 |
str ttl, subttl, ttladdon;
|
|
Packit |
89ede9 |
strs_init( &ttl, &subttl, &ttladdon, NULL );
|
|
Packit |
89ede9 |
for ( currlevel = 0; currlevel
|
|
Packit |
89ede9 |
found = get_title_elements( bibin, currlevel, reftype, p->all, p->nall, &ttl, &subttl, &ttladdon );
|
|
Packit |
89ede9 |
if ( !found ) continue;
|
|
Packit |
89ede9 |
if ( p->nosplittitle )
|
|
Packit |
89ede9 |
status = process_combined_title( info, &ttl, &subttl, &ttladdon, currlevel );
|
|
Packit |
89ede9 |
else
|
|
Packit |
89ede9 |
status = process_separated_title( info, &ttl, &subttl, &ttladdon, currlevel );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
strs_free( &ttl, &subttl, &ttladdon, NULL );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatex_matches_list( fields *info, char *tag, char *suffix, str *data, int level, slist *names, int *match )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int i, fstatus, status = BIBL_OK;
|
|
Packit |
89ede9 |
str newtag;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
*match = 0;
|
|
Packit |
89ede9 |
if ( names->n==0 ) return status;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
str_init( &newtag );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
for ( i=0; i<names->n; ++i ) {
|
|
Packit |
89ede9 |
if ( strcmp( str_cstr( data ), slist_cstr( names, i ) ) ) continue;
|
|
Packit |
89ede9 |
str_initstrc( &newtag, tag );
|
|
Packit |
89ede9 |
str_strcatc( &newtag, suffix );
|
|
Packit |
89ede9 |
fstatus = fields_add( info, str_cstr( &newtag ), str_cstr( data ), level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) {
|
|
Packit |
89ede9 |
status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
*match = 1;
|
|
Packit |
89ede9 |
goto out;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
str_free( &newtag );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatex_names( fields *info, char *tag, str *data, int level, slist *asis, slist *corps )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int begin, end, ok, n, etal, i, match, status = BIBL_OK;
|
|
Packit |
89ede9 |
slist tokens;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* If we match the asis or corps list add and bail. */
|
|
Packit |
89ede9 |
status = biblatex_matches_list( info, tag, ":ASIS", data, level, asis, &match );
|
|
Packit |
89ede9 |
if ( match==1 || status!=BIBL_OK ) return status;
|
|
Packit |
89ede9 |
status = biblatex_matches_list( info, tag, ":CORP", data, level, corps, &match );
|
|
Packit |
89ede9 |
if ( match==1 || status!=BIBL_OK ) return status;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
slist_init( &tokens );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
biblatex_split( &tokens, data );
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
biblatex_cleantoken( slist_str( &tokens, i ) );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
etal = name_findetal( &tokens );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
begin = 0;
|
|
Packit |
89ede9 |
n = tokens.n - etal;
|
|
Packit |
89ede9 |
while ( begin < n ) {
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
end = begin + 1;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
while ( end < n && strcasecmp( slist_cstr( &tokens, end ), "and" ) )
|
|
Packit |
89ede9 |
end++;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( end - begin == 1 ) {
|
|
Packit |
89ede9 |
ok = name_addsingleelement( info, tag, slist_cstr( &tokens, begin ), level, 0 );
|
|
Packit |
89ede9 |
if ( !ok ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
ok = name_addmultielement( info, tag, &tokens, begin, end, level );
|
|
Packit |
89ede9 |
if ( !ok ) { status = BIBL_ERR_MEMERR; goto out; }
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
begin = end + 1;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* Handle repeated 'and' errors */
|
|
Packit |
89ede9 |
while ( begin < n && !strcasecmp( slist_cstr( &tokens, begin ), "and" ) )
|
|
Packit |
89ede9 |
begin++;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( etal ) {
|
|
Packit |
89ede9 |
ok = name_addsingleelement( info, tag, "et al.", level, 0 );
|
|
Packit |
89ede9 |
if ( !ok ) status = BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
out:
|
|
Packit |
89ede9 |
slist_free( &tokens );
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_bltsubtype( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus1, fstatus2;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !strcasecmp( str_cstr( invalue ), "magazine" ) ) {
|
|
Packit |
89ede9 |
fstatus1 = fields_add( bibout, "GENRE:BIBUTILS", "magazine article", LEVEL_MAIN );
|
|
Packit |
89ede9 |
fstatus2 = fields_add( bibout, "GENRE:BIBUTILS", "magazine", LEVEL_HOST );
|
|
Packit |
89ede9 |
if ( fstatus1!=FIELDS_OK || fstatus2!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
else if ( !strcasecmp( str_cstr( invalue ), "newspaper" ) ) {
|
|
Packit |
89ede9 |
fstatus1 = fields_add( bibout, "GENRE:BIBUTILS", "newspaper article", LEVEL_MAIN );
|
|
Packit |
89ede9 |
fstatus2 = fields_add( bibout, "GENRE:MARC", "newspaper", LEVEL_HOST );
|
|
Packit |
89ede9 |
if ( fstatus1!=FIELDS_OK || fstatus2!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* biblatex drops school field if institution is present */
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_bltschool( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus;
|
|
Packit |
89ede9 |
if ( fields_find( bibin, "institution", LEVEL_ANY ) != FIELDS_NOTFOUND )
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
else {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, outtag, str_cstr( invalue ), level );
|
|
Packit |
89ede9 |
if ( fstatus==FIELDS_OK ) return BIBL_OK;
|
|
Packit |
89ede9 |
else return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_bltthesistype( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
char *p = invalue->data;
|
|
Packit |
89ede9 |
int fstatus = FIELDS_OK;
|
|
Packit |
89ede9 |
/* type in the @thesis is used to distinguish Ph.D. and Master's thesis */
|
|
Packit |
89ede9 |
if ( !strncasecmp( p, "phdthesis", 9 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Ph.D. thesis", level );
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( p, "mastersthesis", 13 ) || !strncasecmp( p, "masterthesis", 12 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Masters thesis", level );
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( p, "mathesis", 8 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Masters thesis", level );
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( p, "diploma", 7 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Diploma thesis", level );
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( p, "habilitation", 12 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Habilitation thesis", level );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
if ( fstatus==FIELDS_OK ) return BIBL_OK;
|
|
Packit |
89ede9 |
else return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_bteprint( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int neprint, netype, fstatus;
|
|
Packit |
89ede9 |
char *eprint = NULL, *etype = NULL;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
neprint = fields_find( bibin, "eprint", LEVEL_ANY );
|
|
Packit |
89ede9 |
netype = fields_find( bibin, "eprinttype", LEVEL_ANY );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( neprint!=FIELDS_NOTFOUND ) eprint = bibin->data[neprint].data;
|
|
Packit |
89ede9 |
if ( netype!=FIELDS_NOTFOUND ) etype = bibin->data[netype].data;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( eprint && etype ) {
|
|
Packit |
89ede9 |
if ( !strncasecmp( etype, "arxiv", 5 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "ARXIV", eprint, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( etype, "jstor", 5 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "JSTOR", eprint, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( etype, "pubmed", 6 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "PMID", eprint, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
} else if ( !strncasecmp( etype, "medline", 7 ) ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "MEDLINE", eprint, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
} else {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "EPRINT", eprint, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "EPRINTTYPE", etype, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
fields_setused( bibin, neprint );
|
|
Packit |
89ede9 |
fields_setused( bibin, netype );
|
|
Packit |
89ede9 |
} else if ( eprint ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "EPRINT", eprint, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
fields_setused( bibin, neprint );
|
|
Packit |
89ede9 |
} else if ( etype ) {
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "EPRINTTYPE", etype, level );
|
|
Packit |
89ede9 |
if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
fields_setused( bibin, netype );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return BIBL_OK;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_btgenre( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( fields_add( bibout, "GENRE:BIBUTILS", str_cstr( invalue ), level ) == FIELDS_OK ) return BIBL_OK;
|
|
Packit |
89ede9 |
else return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* biblatexin_howpublished()
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* howpublished={},
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Normally indicates the manner in which something was
|
|
Packit |
89ede9 |
* published in lieu of a formal publisher, so typically
|
|
Packit |
89ede9 |
* 'howpublished' and 'publisher' will never be in the
|
|
Packit |
89ede9 |
* same reference.
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Occasionally, people put Diploma thesis information
|
|
Packit |
89ede9 |
* into this field, so check for that first.
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_howpublished( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
int fstatus;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !strncasecmp( str_cstr( invalue ), "Diplom", 6 ) )
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Diploma thesis", level );
|
|
Packit |
89ede9 |
else if ( !strncasecmp( str_cstr( invalue ), "Habilitation", 13 ) )
|
|
Packit |
89ede9 |
fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Habilitation thesis", level );
|
|
Packit |
89ede9 |
else
|
|
Packit |
89ede9 |
fstatus = fields_add( bibout, "PUBLISHER", str_cstr( invalue ), level );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( fstatus==FIELDS_OK ) return BIBL_OK;
|
|
Packit |
89ede9 |
else return BIBL_ERR_MEMERR;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/*
|
|
Packit |
89ede9 |
* biblatex has multiple editor fields "editor", "editora", "editorb", "editorc",
|
|
Packit |
89ede9 |
* each of which can be modified from a type of "EDITOR" via "editortype",
|
|
Packit |
89ede9 |
* "editoratype", "editorbtype", "editorctype".
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* Defined types:
|
|
Packit |
89ede9 |
* "editor"
|
|
Packit |
89ede9 |
* "collaborator"
|
|
Packit |
89ede9 |
* "compiler"
|
|
Packit |
89ede9 |
* "redactor"
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* "reviser" ?
|
|
Packit |
89ede9 |
* "founder" ?
|
|
Packit |
89ede9 |
* "continuator" ?
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* bibtex-chicago
|
|
Packit |
89ede9 |
*
|
|
Packit |
89ede9 |
* "director"
|
|
Packit |
89ede9 |
* "producer"
|
|
Packit |
89ede9 |
* "conductor"
|
|
Packit |
89ede9 |
* "none" (for performer)
|
|
Packit |
89ede9 |
*/
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_blteditor( fields *bibin, int m, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
char *editor_fields[] = { "editor", "editora", "editorb", "editorc" };
|
|
Packit |
89ede9 |
char *editor_types[] = { "editortype", "editoratype", "editorbtype", "editorctype" };
|
|
Packit |
89ede9 |
int i, n = 0, ntype, neditors = sizeof( editor_fields ) / sizeof( editor_fields[0] );
|
|
Packit |
89ede9 |
char *type, *usetag = "EDITOR";
|
|
Packit |
89ede9 |
for ( i=1; i
|
|
Packit |
89ede9 |
if ( !strcasecmp( intag->data, editor_fields[i] ) ) n = i;
|
|
Packit |
89ede9 |
ntype = fields_find( bibin, editor_types[n], LEVEL_ANY );
|
|
Packit |
89ede9 |
if ( ntype!=FIELDS_NOTFOUND ) {
|
|
Packit |
89ede9 |
type = fields_value( bibin, ntype, FIELDS_CHRP_NOUSE );
|
|
Packit |
89ede9 |
if ( !strcasecmp( type, "collaborator" ) ) usetag = "COLLABORATOR";
|
|
Packit |
89ede9 |
else if ( !strcasecmp( type, "compiler" ) ) usetag = "COMPILER";
|
|
Packit |
89ede9 |
else if ( !strcasecmp( type, "redactor" ) ) usetag = "REDACTOR";
|
|
Packit |
89ede9 |
else if ( !strcasecmp( type, "director" ) ) usetag = "DIRECTOR";
|
|
Packit |
89ede9 |
else if ( !strcasecmp( type, "producer" ) ) usetag = "PRODUCER";
|
|
Packit |
89ede9 |
else if ( !strcasecmp( type, "none" ) ) usetag = "PERFORMER";
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
return biblatex_names( bibout, usetag, invalue, level, &(pm->asis), &(pm->corps) );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_person( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
return biblatex_names( bibout, outtag, invalue, level, &(pm->asis), &(pm->corps) );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static void
|
|
Packit |
89ede9 |
biblatexin_notag( param *p, char *tag )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
if ( p->verbose && strcmp( tag, "INTERNAL_TYPE" ) ) {
|
|
Packit |
89ede9 |
if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
|
|
Packit |
89ede9 |
fprintf( stderr, " Cannot find tag '%s'\n", tag );
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
static int
|
|
Packit |
89ede9 |
biblatexin_convertf( fields *bibin, fields *bibout, int reftype, param *p )
|
|
Packit |
89ede9 |
{
|
|
Packit |
89ede9 |
static int (*convertfns[NUM_REFTYPES])(fields *, int, str *, str *, int, param *, char *, fields *) = {
|
|
Packit |
89ede9 |
[ 0 ... NUM_REFTYPES-1 ] = generic_null,
|
|
Packit |
89ede9 |
[ SIMPLE ] = generic_simple,
|
|
Packit |
89ede9 |
[ PAGES ] = generic_pages,
|
|
Packit |
89ede9 |
[ NOTES ] = generic_notes,
|
|
Packit |
89ede9 |
[ PERSON ] = biblatexin_person,
|
|
Packit |
89ede9 |
[ BLT_EDITOR ] = biblatexin_blteditor,
|
|
Packit |
89ede9 |
[ HOWPUBLISHED ] = biblatexin_howpublished,
|
|
Packit |
89ede9 |
[ URL ] = generic_url,
|
|
Packit |
89ede9 |
[ GENRE ] = biblatexin_btgenre,
|
|
Packit |
89ede9 |
[ BT_EPRINT ] = biblatexin_bteprint,
|
|
Packit |
89ede9 |
[ BLT_THESIS_TYPE ] = biblatexin_bltthesistype,
|
|
Packit |
89ede9 |
[ BLT_SCHOOL ] = biblatexin_bltschool,
|
|
Packit |
89ede9 |
[ BLT_SUBTYPE ] = biblatexin_bltsubtype,
|
|
Packit |
89ede9 |
[ BLT_SKIP ] = generic_skip,
|
|
Packit |
89ede9 |
[ TITLE ] = generic_null, /* delay processing until later */
|
|
Packit |
89ede9 |
};
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
int process, level, i, nfields, status = BIBL_OK;
|
|
Packit |
89ede9 |
str *intag, *invalue;
|
|
Packit |
89ede9 |
char *outtag;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
nfields = fields_num( bibin );
|
|
Packit |
89ede9 |
for ( i=0; i
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* skip ones already "used" such as successful crossref */
|
|
Packit |
89ede9 |
if ( fields_used( bibin, i ) ) continue;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
/* skip ones with no data or no tags (e.g. don't match ALWAYS/DEFAULT entries) */
|
|
Packit |
89ede9 |
intag = fields_tag ( bibin, i, FIELDS_STRP_NOUSE );
|
|
Packit |
89ede9 |
invalue = fields_value( bibin, i, FIELDS_STRP_NOUSE );
|
|
Packit |
89ede9 |
if ( str_is_empty( intag ) || str_is_empty( invalue ) ) continue;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( !translate_oldtag( intag->data, reftype, p->all, p->nall, &process, &level, &outtag ) ) {
|
|
Packit |
89ede9 |
biblatexin_notag( p, intag->data );
|
|
Packit |
89ede9 |
continue;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
status = convertfns[ process ]( bibin, i, intag, invalue, level, p, outtag, bibout );
|
|
Packit |
89ede9 |
if ( status!=BIBL_OK ) return status;
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( convertfns[ process ] != generic_null )
|
|
Packit |
89ede9 |
fields_setused( bibin, i );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
status = process_title_all( bibin, bibout, reftype, p );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
if ( status==BIBL_OK && p->verbose ) fields_report( bibout, stdout );
|
|
Packit |
89ede9 |
|
|
Packit |
89ede9 |
return status;
|
|
Packit |
89ede9 |
}
|
|
Packit |
89ede9 |
|