File Coverage

blib/lib/Bib/CrossRef.pm
Criterion Covered Total %
statement 154 319 48.2
branch 13 106 12.2
condition 0 3 0.0
subroutine 42 48 87.5
pod 22 22 100.0
total 231 498 46.3


'; '; '; '; '; '; '; '; '."\n"; '."\n";
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   69021 use 5.8.8;
  1         11  
10 1     1   5 use strict;
  1         2  
  1         21  
11 1     1   4 use warnings;
  1         2  
  1         48  
12 1     1   21 no warnings 'uninitialized';
  1         2  
  1         51  
13              
14             require Exporter;
15 1     1   701 use LWP::UserAgent;
  1         50577  
  1         45  
16 1     1   794 use JSON qw/decode_json/;
  1         10309  
  1         7  
17 1     1   180 use URI::Escape qw(uri_escape_utf8 uri_unescape);
  1         3  
  1         71  
18 1     1   536 use HTML::Entities qw(decode_entities encode_entities);
  1         14158  
  1         111  
19 1     1   986 use XML::Simple;
  1         9664  
  1         11  
20 1     1   120 use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA);
  1         2  
  1         3858  
21              
22             #use Data::Dumper;
23              
24             $VERSION = '0.10';
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              
33             sub new {
34 2     2 1 727 my $self;
35 2         7 $self->{html} = 0; # use html for error messages ?
36 2         5 $self->{ref} = {}; # the reference itself
37 2         5 bless $self;
38 2         5 return $self;
39             }
40              
41             sub sethtml {
42 1     1 1 998 $_[0]->{html} = 1;
43             }
44              
45             sub clearhtml {
46 0     0 1 0 $_[0]->{html} = 0;
47             }
48              
49             sub _err {
50 1     1   16 my ($self, $str) = @_;
51 1 50       4 if ($self->{html}) {
52 0         0 print "

",$str,"

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