1 /*
2  * notes.c
3  *
4  * Copyright (c) Chris Putnam 2016-2020
5  *
6  * Program and source code released under the GPL version 2
7  *
8  */
9 #include <string.h>
10 #include "url.h"
11 #include "notes.h"
12 
13 /*
14  * notes are mostly directly copies; however, lots of formats hide
15  * URLs/DOIs in the notes fields. For example:
16  *
17  * For RIS, Oxford Journals hides DOI in the N1 field.
18  * For Endnote, Wiley hides DOI in the %1 field.
19  * etc.
20  */
21 
22 typedef struct url_t {
23 	char *prefix;
24 	char *tag;
25 	int offset;
26 } url_t;
27 
28 static void
notes_added_url(fields * bibout,str * invalue,int level,int * ok)29 notes_added_url( fields *bibout, str *invalue, int level, int *ok )
30 {
31 	url_t prefixes[] = {
32 		{ "arXiv:",                                    "ARXIV",     6 },
33 		{ "http://arxiv.org/abs/",                     "ARXIV",    21 },
34 		{ "jstor:",                                    "JSTOR",     6 },
35 		{ "http://www.jstor.org/stable/",              "JSTOR",    28 },
36 		{ "medline:",                                  "MEDLINE",   8 },
37 		{ "pubmed:",                                   "PMID",      7 },
38 		{ "http://www.ncbi.nlm.nih.gov/pubmed/",       "PMID",     35 },
39 		{ "http://www.ncbi.nlm.nih.gov/pmc/articles/", "PMC",      41 },
40 		{ "http://dx.doi.org/",                        "DOI",      19 },
41 		{ "isi:",                                      "ISIREFNUM", 4 },
42 	};
43 	int nprefixes = sizeof( prefixes ) / sizeof( prefixes[0] );
44 
45 	const char *p = str_cstr( invalue );
46 	char *tag = "URL";
47 	int fstatus;
48 	int i;
49 
50 	/* bibtex/biblatex-specific */
51 	if ( !strncasecmp( p, "\\urllink", 8 ) ) p += 8;
52 	if ( !strncasecmp( p, "\\url", 4 ) ) p += 4;
53 
54 	for ( i=0; i<nprefixes; ++i ) {
55 		if ( !strncasecmp( p, prefixes[i].prefix, prefixes[i].offset ) ) {
56 			tag = prefixes[i].tag;
57 			p   = p + prefixes[i].offset;
58 			break;
59 		}
60 	}
61 
62 	fstatus = fields_add( bibout, tag, p, level );
63 
64 	if ( fstatus==FIELDS_OK ) *ok = 1;
65 	else *ok = 0;
66 }
67 
68 static int
notes_added_doi(fields * bibout,str * invalue,int level,int * ok)69 notes_added_doi( fields *bibout, str *invalue, int level, int *ok )
70 {
71 	int doi, fstatus;
72 
73 	doi = is_doi( str_cstr( invalue ) );
74 
75 	if ( doi != -1 ) {
76 		fstatus = fields_add( bibout, "DOI", &(invalue->data[doi]), level );
77 		if ( fstatus != FIELDS_OK ) *ok = 0;
78 		return 1;
79 	}
80 
81 	else return 0;
82 }
83 
84 int
notes_add(fields * bibout,str * invalue,int level)85 notes_add( fields *bibout, str *invalue, int level )
86 {
87 	int fstatus, done = 0, ok = 1;
88 
89 	if ( !is_embedded_link( str_cstr( invalue ) ) ) {
90 		fstatus = fields_add( bibout, "NOTES", str_cstr( invalue ), level );
91 		if ( fstatus != FIELDS_OK ) ok = 0;
92 	}
93 
94 	else {
95 
96 		done = notes_added_doi( bibout, invalue, level, &ok );
97 		if ( !done ) notes_added_url( bibout, invalue, level, &ok );
98 
99 	}
100 
101 	return ok;
102 }
103