line
stmt
bran
cond
sub
pod
time
code
1
############################################################
2
#
3
# Bib::CrossRef - Uses crossref to robustly parse bibliometric references.
4
#
5
############################################################
6
7
package Bib::CrossRef;
8
9
1
1
65762
use 5.8.8;
1
11
10
1
1
5
use strict;
1
2
1
19
11
1
1
5
use warnings;
1
1
1
44
12
1
1
6
no warnings 'uninitialized';
1
1
1
45
13
14
require Exporter;
15
1
1
648
use LWP::UserAgent;
1
47539
1
38
16
1
1
683
use JSON qw/decode_json/;
1
9818
1
6
17
1
1
162
use URI::Escape qw(uri_escape_utf8 uri_unescape);
1
2
1
66
18
1
1
467
use HTML::Entities qw(decode_entities encode_entities);
1
5319
1
84
19
1
1
804
use XML::Simple;
1
8776
1
7
20
1
1
83
use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA);
1
2
1
3649
21
22
#use Data::Dumper;
23
24
$VERSION = '0.12';
25
@ISA = qw(Exporter);
26
@EXPORT = qw();
27
@EXPORT_OK = qw(
28
sethtml clearhtml parse_text parse_doi print printheader printfooter
29
doi score date atitle jtitle volume issue genre spage epage authcount auth query
30
);
31
%EXPORT_TAGS = (all => \@EXPORT_OK);
32
# disable SSL cert checking
33
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
34
35
sub new {
36
2
2
1
599
my $self;
37
2
5
$self->{html} = 0; # use html for error messages ?
38
2
4
$self->{ref} = {}; # the reference itself
39
2
3
bless $self;
40
2
5
return $self;
41
}
42
43
sub sethtml {
44
1
1
1
966
$_[0]->{html} = 1;
45
}
46
47
sub clearhtml {
48
0
0
1
0
$_[0]->{html} = 0;
49
}
50
51
sub _err {
52
1
1
16
my ($self, $str) = @_;
53
1
50
4
if ($self->{html}) {
54
0
0
print "",$str,"
";
55
} else {
56
1
97
print $str,"\n";
57
}
58
}
59
60
sub doi {
61
3
3
1
10
my $self = shift @_;
62
3
10
return $self->{ref}->{'doi'};
63
}
64
65
sub _setdoi {
66
1
1
502
my $self = shift @_;
67
1
2
my $val = shift @_;
68
1
4
$self->{ref}->{'doi'}=$val;
69
}
70
71
sub url {
72
1
1
1
3
my $self = shift @_;
73
1
4
return $self->{ref}->{'url'};
74
}
75
76
sub _seturl {
77
0
0
0
my $self = shift @_;
78
0
0
my $val = shift @_;
79
0
0
$self->{ref}->{'url'}=$val;
80
}
81
82
sub score {
83
2
2
1
4
my $self = shift @_;
84
2
7
return $self->{ref}->{'score'};
85
}
86
87
sub _setscore {
88
1
1
2
my $self = shift @_;
89
1
3
my $val = shift @_;
90
1
2
$self->{ref}->{'score'}=$val;
91
}
92
93
sub atitle {
94
2
2
1
3
my $self = shift @_;
95
2
8
return $self->{ref}->{'atitle'};
96
}
97
98
sub _setatitle {
99
1
1
3
my $self = shift @_;
100
1
3
my $val = shift @_;
101
1
3
$self->{ref}->{'atitle'}=$val;
102
}
103
104
sub jtitle {
105
2
2
1
4
my $self = shift @_;
106
2
9
return $self->{ref}->{'jtitle'};
107
}
108
109
sub _setjtitle {
110
1
1
3
my $self = shift @_;
111
1
3
my $val = shift @_;
112
1
2
$self->{ref}->{'jtitle'}=$val;
113
}
114
115
sub volume {
116
3
3
1
5
my $self = shift @_;
117
3
13
return $self->{ref}->{'volume'};
118
}
119
120
sub _setvolume {
121
1
1
3
my $self = shift @_;
122
1
2
my $val = shift @_;
123
1
3
$self->{ref}->{'volume'}=$val;
124
}
125
126
sub issue {
127
3
3
1
6
my $self = shift @_;
128
3
8
return $self->{ref}->{'issue'};
129
}
130
131
sub _setissue {
132
1
1
2
my $self = shift @_;
133
1
2
my $val = shift @_;
134
1
3
$self->{ref}->{'issue'}=$val;
135
}
136
137
sub date {
138
2
2
1
4
my $self = shift @_;
139
2
7
return $self->{ref}->{'date'};
140
}
141
142
sub _setdate {
143
1
1
3
my $self = shift @_;
144
1
2
my $val = shift @_;
145
1
4
$self->{ref}->{'date'}=$val;
146
}
147
148
sub genre {
149
2
2
1
4
my $self = shift @_;
150
2
8
return $self->{ref}->{'genre'};
151
}
152
153
sub _setgenre {
154
1
1
3
my $self = shift @_;
155
1
2
my $val = shift @_;
156
1
5
$self->{ref}->{'genre'}=$val;
157
}
158
159
sub spage {
160
3
3
1
5
my $self = shift @_;
161
3
10
return $self->{ref}->{'spage'};
162
}
163
164
sub _setspage {
165
1
1
3
my $self = shift @_;
166
1
2
my $val = shift @_;
167
1
4
$self->{ref}->{'spage'}=$val;
168
}
169
170
sub epage {
171
3
3
1
7
my $self = shift @_;
172
3
11
return $self->{ref}->{'epage'};
173
}
174
175
sub _setepage {
176
1
1
3
my $self = shift @_;
177
1
2
my $val = shift @_;
178
1
3
$self->{ref}->{'epage'}=$val;
179
}
180
181
sub authcount {
182
4
4
1
6
my $self = shift @_;
183
4
13
return $self->{ref}->{'authcount'};
184
}
185
186
sub _setauthcount {
187
1
1
2
my $self = shift @_;
188
1
3
my $val = shift @_;
189
1
3
$self->{ref}->{'authcount'}=$val;
190
}
191
192
sub auth {
193
4
4
1
9
my ($self, $num) = @_;
194
4
23
return $self->{ref}->{'au'.$num};
195
}
196
197
sub _setauth {
198
2
2
3
my $self = shift @_;
199
2
4
my $i = shift @_;
200
2
3
my $val = shift @_;
201
2
7
$self->{ref}->{'au'.$i}=$val;
202
}
203
204
sub query {
205
1
1
1
2
my $self = shift @_;
206
1
4
return $self->{ref}->{'query'};
207
}
208
209
sub _setquery {
210
0
0
0
my $self = shift @_;
211
0
0
my $val = shift @_;
212
0
0
$self->{ref}->{'query'}=$val;
213
}
214
215
sub parse_text {
216
# given free format text, use crossref.org to try to convert into a paper reference and doi
217
1
1
1
356
my ($self, $cites) = @_;
218
219
1
3
my $cites_clean = $cites;
220
# tidy up string, escape nasty characters etc.
221
1
13
$cites_clean =~ s/\s+/+/g; #$cites_clean = uri_escape_utf8($cites_clean);
222
#print $cites_clean;
223
# crossref like us to give a mailto email when making request so they can get in touch if the script is generating errors,
224
# feel free to change the email address here to something more appropriate
225
# change to using /works API instead of /dois API
226
1
10
my $req = HTTP::Request->new(GET => 'https://api.crossref.org/works?mailto=doug@leith.ie&rows=1&query='.$cites_clean);
227
1
7896
my $ua = LWP::UserAgent->new;
228
1
2884
my $res = $ua->request($req);
229
1
50
1896
if ($res->is_success) {
230
# extract json response
231
0
0
my $json = decode_json($res->decoded_content);
232
#use Data::Dumper;
233
#print Dumper($json->{'message'}{'items'});
234
0
0
my $ref={};
235
# keep a record of the query string we used
236
0
0
$ref->{'query'} = $cites;
237
0
0
my $response = $json->{'message'}{'items'}[0];
238
#print Dumper($response);
239
# extract doi and matching score
240
0
0
$ref->{'doi'} = $response->{'DOI'};
241
0
0
$ref->{'doi'} =~ s/http:\/\/dx.doi.org\///; # remove any http header
242
0
0
$ref->{'url'} = $response->{'URL'};
243
0
0
$ref->{'score'} = $response->{'score'}; #$json->[0]{'normalizedScore'};
244
0
0
$ref->{'issue'} = $response->{'journal-issue'}{'issue'};
245
0
0
$ref->{'genre'} = $response->{'type'};
246
0
0
0
if ($ref->{'genre'} =~ m/journal-article/) { $ref->{'genre'}='article';} # for backward compatibility
0
0
247
#print $ref->{'genre'};
248
0
0
$ref->{'jtitle'} = $response->{'container-title'}[0];
249
0
0
$ref->{'atitle'} = $response->{'title'}[0];
250
0
0
$ref->{'volume'} = $response->{'volume'};
251
0
0
my @bits = split /-/, $response->{'page'};
252
0
0
$ref->{'spage'} = $bits[0];
253
0
0
$ref->{'epage'} = $bits[1];
254
0
0
$ref->{'date'} = $response->{'issued'}{'date-parts'}[0][0];
255
0
0
$ref->{'authcount'}=0;
256
0
0
while (defined $response->{'author'}[$ref->{'authcount'}]) {
257
0
0
my $val = $response->{'author'}[$ref->{'authcount'}];
258
#print Dumper($val);
259
0
0
$ref->{'authcount'}++;
260
0
0
$ref->{'au'.$ref->{'authcount'}} = $val->{'given'}.' '.$val->{'family'};
261
}
262
263
0
0
$self->{ref} = $ref;
264
} else {
265
1
15
$self->_err("Problem with search.crossref.org: ".$res->status_line);
266
}
267
}
268
269
sub parse_doi {
270
# given a DOI, use unixref interface to convert into a full citation
271
0
0
1
0
my ($self, $doi) = @_;
272
273
0
0
my $req = HTTP::Request->new(GET =>'http://dx.doi.org/'.$doi,['Accept' =>'application/vnd.crossref.unixsd+xml']);
274
0
0
my $ua = LWP::UserAgent->new;
275
0
0
my $res = $ua->request($req);
276
0
0
0
if ($res->is_success) {
277
# now parse the xml
278
0
0
my $xs = XML::Simple->new();
279
0
0
my $data = $xs->XMLin($res->decoded_content);
280
0
0
my $cite = $data->{'query_result'}->{'body'}->{'query'}->{'doi_record'}->{'crossref'};
281
0
0
my $cc = undef;
282
0
0
0
if (exists($cite->{'conference'})) {
0
0
283
0
0
$self->_setgenre('proceeding');
284
0
0
0
if (exists($cite->{'conference'}->{'proceedings_metadata'})) {
285
0
0
$self->_setjtitle($cite->{'conference'}->{'proceedings_metadata'}->{'proceedings_title'});
286
0
0
0
if (exists $cite->{'conference'}->{'proceedings_metadata'}->{'publication_date'}) {$self->_setdate($cite->{'conference'}->{'proceedings_metadata'}->{'publication_date'}->{'year'});}
0
0
287
} else {
288
0
0
$self->_setjtitle($cite->{'conference'}->{'proceedings_series_metadata'}->{'series_metadata'}->{'proceedings_title'});
289
0
0
$self->_setvolume($cite->{'conference'}->{'proceedings_series_metadata'}->{'series_metadata'}->{'volume'});
290
0
0
0
if (exists $cite->{'conference'}->{'proceedings_series_metadata'}->{'publication_date'}) {$self->_setdate($cite->{'conference'}->{'proceedings_series_metadata'}->{'publication_date'}->{'year'});}
0
0
291
}
292
0
0
$cc = $cite->{'conference'}->{'conference_paper'};
293
} elsif (exists($cite->{'journal'})) {
294
0
0
$self->_setgenre('article');
295
0
0
$self->_setjtitle($cite->{'journal'}->{'journal_metadata'}->{'full_title'});
296
0
0
$cc = $cite->{'journal'}->{'journal_issue'};
297
0
0
0
if (exists($cc->{'journal_volume'})) {$self->_setvolume($cc->{'journal_volume'}->{'volume'});}
0
0
298
0
0
0
if (exists($cc->{'issue'})) {$self->_setissue($cc->{'issue'});}
0
0
299
0
0
$cc = $cite->{'journal'}->{'journal_article'};
300
} elsif (exists($cite->{'book'})) {
301
0
0
0
if ($cite->{'book'}->{'book_type'} ne 'other' ) {
302
0
0
$self->_setgenre('book');
303
} else {
304
0
0
$self->_setgenre('bookitem');
305
}
306
0
0
my $jtitle = '';
307
0
0
0
if (exists($cite->{'book'}->{'book_series_metadata'})) {
0
308
0
0
0
if (exists($cite->{'book'}->{'book_series_metadata'}->{'titles'}->{'title'})) {
309
0
0
$jtitle .= $cite->{'book'}->{'book_series_metadata'}->{'titles'}->{'title'}.': ';
310
}
311
0
0
$jtitle .= $cite->{'book'}->{'book_series_metadata'}->{'series_metadata'}->{'titles'}->{'title'};
312
0
0
$self->_setvolume($cite->{'book'}->{'book_series_metadata'}->{'volume'});
313
0
0
0
if (exists $cite->{'book'}->{'book_series_metadata'}->{'publication_date'}) {$self->_setdate($cite->{'book'}->{'book_series_metadata'}->{'publication_date'}->{'year'});}
0
0
314
} elsif (exists($cite->{'book'}->{'book_metadata'})) {
315
0
0
$jtitle .= $cite->{'book'}->{'book_metadata'}->{'titles'}->{'title'};
316
0
0
0
if (exists($cite->{'book'}->{'book_metadata'}->{'series_metadata'}->{'titles'}->{'title'})) {
317
0
0
$jtitle .= ": ".$cite->{'book'}->{'book_metadata'}->{'series_metadata'}->{'titles'}->{'title'};
318
0
0
0
if (exists $cite->{'book'}->{'book_metadata'}->{'series_metadata'}->{'volume'}) {$self->_setvolume($cite->{'book'}->{'book_metadata'}->{'series_metadata'}->{'volume'});}
0
0
319
}
320
0
0
0
if (exists $cite->{'book'}->{'book_metadata'}->{'volume'}) {$self->_setvolume($cite->{'book'}->{'book_metadata'}->{'volume'});}
0
0
321
0
0
0
if (exists $cite->{'book'}->{'book_metadata'}->{'publication_date'}) {$self->_setdate($cite->{'book'}->{'book_metadata'}->{'publication_date'}->{'year'});}
0
0
322
} else {
323
0
0
0
if (exists($cite->{'book'}->{'book_set_metadata'}->{'titles'}->{'title'})) {
324
0
0
$jtitle .= $cite->{'book'}->{'book_set_metadata'}->{'titles'}->{'title'}.': ';
325
}
326
0
0
$jtitle .= $cite->{'book'}->{'book_set_metadata'}->{'set_metadata'}->{'titles'}->{'title'};
327
}
328
0
0
$self->_setjtitle($jtitle);
329
0
0
$cc = $cite->{'book'}->{'content_item'};
330
} else {
331
# something else -- might be dissertation, report-paper, standard, sa-component, database
332
# fall back to alternative interface for now
333
0
0
$self->parse_text($doi);
334
0
0
return; # stop here
335
}
336
0
0
$self->_setscore(1);
337
0
0
$self->_setquery($doi);
338
0
0
$self->_setdoi($doi);
339
0
0
0
if (!defined $cc) {
340
# seems like an incomplete entry
341
0
0
return;
342
}
343
#$self->_setatitle($cc->{'titles'}->{'title'});
344
0
0
my $title;
345
0
0
0
if (ref $cc->{titles} ne "HASH") {
346
0
0
$title = $cc->{titles}->[0];
347
} else {
348
0
0
$title = $cc->{'titles'}->{'title'};
349
}
350
0
0
$self->_setatitle($title);
351
0
0
$self->_setdoi($cc->{'doi_data'}->{'doi'});
352
0
0
0
if (ref($cc->{'publication_date'}) eq "HASH") {
353
0
0
$self->_setdate($cc->{'publication_date'}->{'year'});
354
} else { # we have multiple dates, lets try and pick put the print date
355
0
0
my $found = 0; my $count=0;
0
0
356
0
0
foreach my $d (@{$cc->{'publication_date'}}) {
0
0
357
0
0
0
if ($d->{'media_type'} eq 'print') {
358
0
0
$self->_setdate($d->{'year'}); $found = 1;
0
0
359
}
360
0
0
$count++;
361
}
362
0
0
0
0
if ((!$found) && ($count>0)) {$self->_setdate(${$cc->{'publication_date'}}[0]->{'year'});}
0
0
0
0
363
}
364
0
0
0
if (exists(${$cc}{'pages'})) {
0
0
365
0
0
0
if (exists(${$cc->{'pages'}}{'first_page'})) {$self->_setspage($cc->{'pages'}->{'first_page'});}
0
0
0
0
366
0
0
0
if (exists(${$cc->{'pages'}}{'last_page'})) {$self->_setepage($cc->{'pages'}->{'last_page'});}
0
0
0
0
367
}
368
0
0
$cc = $cc->{'contributors'}->{'person_name'};
369
0
0
0
if (ref($cc) eq "HASH") {
370
0
0
$self->_setauthcount(1);
371
0
0
$self->_setauth(1,$cc->{'given_name'}.' '.$cc->{'surname'});
372
} else {
373
0
0
my $count = 0;
374
0
0
foreach my $au (@{$cc}) {
0
0
375
0
0
0
if ($au->{'contributor_role'} ne 'author') {next;}
0
0
376
0
0
$count++;
377
0
0
$self->_setauth($count, $au->{'given_name'}.' '.$au->{'surname'});
378
}
379
0
0
$self->_setauthcount($count);
380
}
381
} else {
382
0
0
$self->_err("Problem with search.crossref.org/guestquery: ".$res->status_line);
383
}
384
}
385
386
sub printheader {
387
0
0
1
0
my $self = shift @_;
388
0
0
my $id = shift @_;
389
0
0
my $str = '';
390
0
0
0
if (defined $id) {$str = 'id="'.$id.'"';}
0
0
391
0
0
return 'Use Type Year Authors Title Journal Volume Issue Pages DOI url '."\n";
392
}
393
394
sub printfooter {
395
0
0
1
0
return "
\n";
396
}
397
398
sub _authstring {
399
1
1
2
my $self = shift @_;
400
1
2
my $out='';
401
1
50
2
if ($self->authcount > 0) {
402
1
3
$out = $self->auth(1);
403
1
3
for (my $j = 2; $j <= $self->authcount; $j++) {
404
1
4
$out.=' and '.$self->auth($j);
405
}
406
}
407
1
4
return $out;
408
}
409
410
sub print {
411
# return a reference in human readable form
412
1
1
1
3
my ($self, $id, $add) = @_;
413
1
3
my $ref = $self->{ref};
414
1
50
4
if (!defined $id) {$id='';}
0
0
415
1
50
3
if (!defined $add) {$add='';}
1
2
416
417
1
2
my $out='';
418
1
50
4
if ($self->{html}) {
419
1
2
$out.=sprintf "%s", ' ';
420
1
5
$out.=sprintf "%s", ' '.$id.' ';
421
1
50
3
if ($self->score<1) {
422
0
0
$out.=sprintf "%s", ' ';
423
0
0
$out.=sprintf "%s", ' Poor match ';
424
} else {
425
1
5
$out.=sprintf "%s", ' ';
426
}
427
1
3
$out.=sprintf "%s", ' '.$self->genre.' '.$self->date.' ';
428
1
4
$out.=sprintf "%s", ' '.$self->_authstring.' ';
429
1
4
$out.=sprintf "%s", ' '.$self->atitle.' '.encode_entities($self->jtitle).' ';
430
1
22
$out.=sprintf "%s", ' ';
431
1
50
3
if (defined $self->volume) {
432
1
2
$out.=sprintf "%s", $self->volume;
433
}
434
1
2
$out.=sprintf "%s", ' ';
435
1
50
3
if (defined $self->issue) {
436
1
3
$out.=sprintf "%s", $self->issue;
437
}
438
1
2
$out.=sprintf "%s", ' ';
439
1
50
2
if (defined $self->spage) {
440
1
4
$out.=sprintf "%s", $self->spage;
441
}
442
1
50
2
if (defined $self->epage) {
443
1
3
$out.=sprintf "%s", '-'.$self->epage;
444
}
445
1
23
$out.=sprintf "%s", ' ';
446
1
50
4
if (defined $self->doi) {
447
1
25
my $doi = $self->doi;
448
1
10
$doi =~ s/http:\/\/dx.doi.org\///;
449
1
3
$out.=$doi;
450
}
451
1
2
$out.=sprintf "%s", ' ';
452
1
50
3
if (defined $self->url) {
453
0
0
$out.=sprintf "%s", ''.$self->url.' ';
454
}
455
1
4
$out.= ' '.$add;
456
1
2
$out.=sprintf "%s", ' '."\n";
457
1
3
$out.=sprintf "%s", ' '.encode_entities($self->query).' '."\n";
458
} else {
459
0
0
0
if (length($id)>0) {$out .= $id.". ";}
0
0
460
0
0
0
if ($self->score<1) {
461
0
0
$out.=sprintf "%s", 'Poor match (score='.$self->score."):\n";
462
0
0
$out.=sprintf "%s", $self->query."\n";
463
} else {
464
#print "$count. ";
465
}
466
0
0
$out.=sprintf "%s", $self->genre.': '.$self->date.", ".$self->_authstring.", ";
467
0
0
$out.=sprintf "%s", "\'".$self->atitle."\'. ".$self->jtitle;
468
0
0
0
if (defined $self->volume) {
469
0
0
$out.=sprintf "%s", ", ".$self->volume;
470
0
0
0
if (defined $self->issue) {
471
0
0
$out.=sprintf "%s", "(".$self->issue.")";
472
}
473
}
474
0
0
0
if (defined $self->spage) {
475
0
0
$out.=sprintf "%s", ",pp".$self->spage;
476
}
477
0
0
0
if (defined $self->epage) {
478
0
0
$out.=sprintf "%s", '-'.$self->epage;
479
}
480
0
0
0
if (defined $self->doi) {
481
0
0
my $doi = $self->doi;
482
0
0
$doi =~ s/http:\/\/dx.doi.org\///;
483
0
0
$out.=sprintf "%s", ", DOI: ".$doi;
484
}
485
0
0
0
if (defined $self->url) {
486
0
0
$out.=sprintf "%s", ", ".$self->url;
487
}
488
}
489
1
13
return $out;
490
}
491
492
1;
493
494
=pod
495
496
=head1 NAME
497
498
Bib::CrossRef - Uses crossref to robustly parse bibliometric references.
499
500
=head1 SYNOPSIS
501
502
use strict;
503
use Bib::CrossRef;
504
505
# Create a new object
506
507
my $ref = Bib::CrossRef->new();
508
509
# Supply some details, Bib::CrossRef will do its best to use this to derive full citation details e.g. the DOI of a document ...
510
511
$ref->parse_text('10.1109/jstsp.2013.2251604');
512
513
# Show the full citation details, in human readable form
514
515
print $ref->print();
516
517
article: 2013, Alessandro Checco and Douglas J. Leith, 'Learning-Based Constraint Satisfaction With Sensing Restrictions'. IEEE Journal of Selected Topics in Signal Processing, 7(5),pp811-820, DOI: http://dx.doi.org/10.1109/jstsp.2013.2251604
518
519
# Show the full citation details, in html format
520
521
$ref->sethtml;
522
print $ref->printheader;
523
print $ref->print;
524
print $ref->printfooter;
525
526
527
=head1 EXAMPLES
528
529
A valid DOI will always be resolved to a full citation
530
e.g.
531
532
$ref->sparse_text('10.1109/jstsp.2013.2251604');
533
print $ref->print();
534
535
article: 2013, Alessandro Checco and Douglas J. Leith, 'Learning-Based Constraint Satisfaction With Sensing Restrictions'. IEEE Journal of Selected Topics in Signal Processing, 7(5),pp811-820, DOI: http://dx.doi.org/10.1109/jstsp.2013.2251604
536
537
An attempt will be made to resolve almost any text containing citation info
538
e.g. article title only
539
540
$ref->parse_text('Learning-Based Constraint Satisfaction With Sensing Restrictions');
541
542
e.g. author and journal
543
544
$ref->parse_text('Alessandro Checco, Douglas J. Leith, IEEE Journal of Selected Topics in Signal Processing, 7(5)');
545
546
Please bear in mind that crossref provides a great service for free -- don't abuse it by making excessive queries. If making many queries, be
547
sure to rate limit them to a sensible level or you will likely get blocked.
548
549
=head1 METHODS
550
551
=head2 new
552
553
my $ref = Bib::CrossRef->new();
554
555
Creates a new Bib::CrossRef object
556
557
=head2 parse_text
558
559
$ref->parse_text($string)
560
561
Given a text string, Bib::CrossRef will try to resolve into a full citation with the help of crossref.org
562
563
=head2 parse_doi
564
565
$ref->parse_doi($doi)
566
567
Given a string containing a DOI e.g. 10.1109/tnet.2012.2202686, resolve into a full citation with the unixref
568
interface of crossref.org. This should be definitive publishers DOI and is usually
569
much as the same as calling $ref->parse_text($doi), but is included completeness.
570
571
=head2 doi
572
573
my $info = $ref->doi
574
575
Returns a string containg the DOI (digital object identifier) field from a full citation. If present, this
576
should be unique to the document.
577
578
=head2 score
579
580
my $info = $ref->score
581
582
Returns a matching score from crossref.org. If less than 1, the text provided to set_details() was likely
583
insufficient to allow the correct full citation to be obtained.
584
585
=head2 genre
586
587
my $info = $ref->genre
588
589
Returns the type of publication e.g. jounal paper, conference paper etc
590
591
=head2 date
592
593
my $info = $ref->date
594
595
Returns the year of publication
596
597
=head2 atitle
598
599
my $info = $ref->atitle
600
601
Returns the article title
602
603
=head2 jtitle
604
605
my $info = $ref->jtitle
606
607
Returns the name of the journal (in long form)
608
609
=head2 authcount
610
611
my $info = $ref->authcount
612
613
Returns the number of authors
614
615
=head2 auth
616
617
my $info = $ref->auth($num)
618
619
Get the name of author number $num (first author is $ref->auth(1))
620
621
=head2 volume
622
623
my $info = $ref->volume
624
625
Returns the volume number in which paper appeared
626
627
=head2 issue
628
629
my $info = $ref->issue
630
631
Returns the issue number in which paper appeared
632
633
=head2 spage
634
635
my $info = $ref->spage
636
637
Returns the start page
638
639
=head2 epage
640
641
my $info = $ref->epage
642
643
Returns the end page
644
645
=head2 url
646
647
Return the url, if any
648
649
=head2 query
650
651
my $info = $ref->query
652
653
Returns the free form string from which full citation is derived
654
655
=head2 print
656
657
print $ref->printheader;
658
659
Prints full citation in human readable form.
660
661
=head2 sethtml
662
663
$ref->sethtml
664
665
Set output format to be html
666
667
=head2 clearhtml
668
669
$ref->clearhtml
670
671
Set output format to be plain text
672
673
=head2 printheader
674
675
print $ref->printheader;
676
677
When html formatting is enabled, prints some html header tags
678
679
=head2 printfooter
680
681
print $ref->printfooter;
682
683
When html formatting is enabled, prints some html footer tags
684
685
=head1 EXPORTS
686
687
You can export the following functions if you do not want to use the object orientated interface:
688
689
parse_text parse_doi sethtml clearhtml set_details print printheader printfooter
690
doi score date atitle jtitle volume issue genre spage epage authcount auth query url
691
692
The tag C is available to easily export everything:
693
694
use Bib::CrossRef qw(:all);
695
696
=head1 VERSION
697
698
Ver 0.09
699
700
=head1 AUTHOR
701
702
Doug Leith
703
704
=head1 BUGS
705
706
Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
707
708
=head1 COPYRIGHT
709
710
Copyright 2015 D.J.Leith.
711
712
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
713
714
See http://dev.perl.org/licenses/ for more information.
715
716
=cut
717
718
719
__END__