diff options
author | Karl Berry <karl@freefriends.org> | 2014-10-19 22:36:21 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-10-19 22:36:21 +0000 |
commit | 85fe62616c2d0cda42038452c38374f1cf5d855a (patch) | |
tree | 45a4890dc18b6bd0d1e6142eeebf19ee293c10a3 /Master/texmf-dist/scripts/crossrefware | |
parent | c07d0b959c7e9bbc2b3beeeab1ebf9ab11489255 (diff) |
crossrefware (19oct14)
git-svn-id: svn://tug.org/texlive/trunk@35401 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/crossrefware')
-rwxr-xr-x | Master/texmf-dist/scripts/crossrefware/bibdoiadd.pl | 267 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/crossrefware/bibzbladd.pl | 215 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/crossrefware/ltx2crossrefxml.pl | 460 |
3 files changed, 942 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/crossrefware/bibdoiadd.pl b/Master/texmf-dist/scripts/crossrefware/bibdoiadd.pl new file mode 100755 index 00000000000..b9be8dec824 --- /dev/null +++ b/Master/texmf-dist/scripts/crossrefware/bibdoiadd.pl @@ -0,0 +1,267 @@ +#!/usr/bin/env perl + +=pod + +=head1 NAME + +bibdoiadd.pl - add DOI numbers to papers in a given bib file + +=head1 SYNOPSIS + +bibdoiadd [B<-c> I<config_file>] [B<-o> I<output>] I<bib_file> + +=head1 OPTIONS + +=over 4 + +=item B<-c> I<config_file> + +Configuration file. If this file is absent, some defaults are used. +See below for its format. + + +=item B<-o> I<output> + +Output file. If this option is not used, the name for the +output file is formed by adding C<_doi> to the input file + +=back + +=head1 DESCRIPTION + +The script reads a BibTeX file. It checks whether the entries have +DOIs. If now, tries to contact http://www.crossref.org to get the +corresponding DOI. The result is a BibTeX file with the fields +C<doi=...> added. + +The name of the output file is either set by the B<-o> option or +is derived by adding the suffix C<_doi> to the output file. + +There are two options for making queries with Crossref: free account +and paid membership. In the first case you still must register with +Crossref and are limited to a small number of queries, see the +agreement at +C<http://www.crossref.org/01company/free_services_agreement.html>. In +the second case you have a username and password, and can use them for +automatic queries. I am not sure whether the use of this script is +allowed for the free account holders. Anyway if you try to add DOI +to a large number of entries, you should register as a paid member. + + + +=head1 CONFIGURATION FILE + +The configuration file is mostly self-explanatory: it has comments +(starting with C<#>) and assginments in the form + + $field = value ; + +The important parameters are C<$mode> (C<'free'> or C<'paid'>, +C<$email> (for free users) and C<$username> & C<$password> for paid +members. + + +=head1 EXAMPLES + + bibdoiadd -c bibdoiadd.cfg citations.bib > result.bib + bibdoiadd -c bibdoiadd.cfg citations.bib -o result.bib + +=head1 AUTHOR + +Boris Veytsman + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2014 Boris Veytsman + +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the +extent permitted by law. + +=cut + +use strict; +use Text::BibTeX; +use Text::BibTeX::Name; +use Getopt::Std; +use URI::Escape; +use LWP::Simple; +use TeX::Encode; +use Encode; +use HTML::Entities; +use XML::Entities; + +my $USAGE="USAGE: $0 [-c config] [-o output] file\n"; +my $VERSION = <<END; +bibdoiadd v1.0 +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the +extent permitted by law. +$USAGE +END +my %opts; +getopts('c:o:hV',\%opts) or die $USAGE; + +if ($opts{h} || $opts{V}){ + print $VERSION; + exit 0; +} + +################################################################ +# Defaults and parameters +################################################################ + +my $inputfile = shift; + +my $outputfile = $inputfile; + +$outputfile =~ s/\.([^\.]*)$/_doi.$1/; + +if ($opts{o}) { + $outputfile = $opts{o}; +} + +our $mode='free'; +our $email; +our $username; +our $password; + +if ($opts{c}) { + if (-r $opts{c}) { + push @INC, "."; + require $opts{c}; + } else { + die "Cannot read options $opts{c}. $USAGE"; + } +} + + +# Check the consistency + +if ($mode eq 'free' && !length($email)) { + die "Crossref requires a registered e-mail for the free mode queries\n"; +} + +if ($mode eq 'paid' && (!length($username) || !length($password))) { + die + "Crossref requires a username and password for the paid mode queries\n"; +} + +my $input = new Text::BibTeX::File "$inputfile" or + die "Cannot BibTeX file $inputfile\n"; +my $output = new Text::BibTeX::File "> $outputfile" or + die "Cannot write to $outputfile\n"; + +my $prefix = + "http://www.crossref.org/openurl?redirect=false"; +if ($mode eq 'free') { + $prefix .= '&pid='.uri_escape($email); +} else { + $prefix .= '&pid='.uri_escape($username).":". + uri_escape($password); +} + +# Processing the input +while (my $entry = new Text::BibTeX::Entry $input) { + if (!$entry->parse_ok()) { + print STDERR "Cannot understand entry: "; + $entry->print(*STDERR); + print STDERR "Skipping this entry\n"; + next; + } + if (!(($entry->metatype() eq BTE_REGULAR) && + ($entry->type() eq 'article'))) { + $entry->write($output); + next; + } + if ($entry->exists('doi')) { + $entry->write($output); + next; + } + + + # Now we have an entry with no doi. Let us get to work. + my $doi = GetDoi($prefix,$entry); + if (length($doi)) { + $entry->set('doi',$doi); + } + $entry->write($output); + +} + +$input->close(); +$output->close(); +exit 0; + +############################################################### +# Getting one doi +############################################################### + +sub GetDoi { + my ($url,$entry) = @_; + if ($entry->exists('issn')) { + $url .= "&issn=".uri_escape(SanitizeText($entry->get('issn'))); + } + if ($entry->exists('journal')) { + $url .= "&title=".uri_escape(SanitizeText($entry->get('journal'))); + } + my @names=$entry->names ('author'); + if (scalar(@names)) { + my @lastnames = $names[0]->part ('last'); + if (scalar(@lastnames)) { + my $lastname = SanitizeText(join(' ',@lastnames)); + $url .= "&aulast=".uri_escape($lastname); + } + } + if ($entry->exists('volume')) { + $url .= "&volume=".uri_escape($entry->get('volume')); + } + if ($entry->exists('number')) { + $url .= "&issue=".uri_escape($entry->get('number')); + } + if ($entry->exists('pages')) { + my $pages=$entry->get('pages'); + $pages =~ s/-.*$//; + $url .= "&spage=".uri_escape($pages); + } + if ($entry->exists('year')) { + $url .= "&date=".uri_escape($entry->get('year')); + } + + my $result=get($url); + + if ($result =~ m/<doi [^>]*>(.*)<\/doi>/) { + return $1; + } else { + return ""; + } +} + +############################################################### +# Sanitization of a text string +############################################################### +sub SanitizeText { + my $string = shift; + # There is a bug in the decode function, which we need to work + # around: it adds space to constructions like \o x + $string =~ s/(\\[a-zA-Z])\s+/$1/g; + $string =~ s/\\newblock//g; + $string =~ s/\\urlprefix//g; + $string =~ s/\\emph//g; + $string =~ s/\\enquote//g; + $string =~ s/\\url/URL: /g; + $string =~ s/\\doi/DOI: /g; + $string =~ s/\\\\/ /g; + $string = decode('latex', $string); + $string =~ s/\\[a-zA-Z]+/ /g; + $string =~ s/\\\\/ /g; + $string =~ s/[\[\{\}\]]/ /g; + $string = encode_entities($string); + $string = XML::Entities::numify('all', $string); + $string =~ s/amp;//g; + $string =~ s/~/ /g; + $string =~ s/\s*([\.;,])/$1/g; + return $string; +} diff --git a/Master/texmf-dist/scripts/crossrefware/bibzbladd.pl b/Master/texmf-dist/scripts/crossrefware/bibzbladd.pl new file mode 100755 index 00000000000..4059b7b0a12 --- /dev/null +++ b/Master/texmf-dist/scripts/crossrefware/bibzbladd.pl @@ -0,0 +1,215 @@ +#!/usr/bin/env perl + +=pod + +=head1 NAME + +bibzbladd.pl - add Zbl numbers to papers in a given bib file + +=head1 SYNOPSIS + +bibzbladd [B<-o> I<output>] I<bib_file> + +=head1 OPTIONS + +=over 4 + + +=item B<-o> I<output> + +Output file. If this option is not used, the name for the +output file is formed by adding C<_zbl> to the input file + +=back + +=head1 DESCRIPTION + +The script reads a BibTeX file. It checks whether the entries have +Zbls. If now, tries to contact internet to get the numbers. The +result is a BibTeX file with the fields +C<zblnumber=...> added. + +The name of the output file is either set by the B<-o> option or +is derived by adding the suffix C<_zbl> to the output file. + +=head1 AUTHOR + +Boris Veytsman + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2014 Boris Veytsman + +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the +extent permitted by law. + +=cut + +use strict; +use Text::BibTeX; +use Text::BibTeX::Name; +use Getopt::Std; +use URI::Escape; +use LWP::UserAgent; +use TeX::Encode; + +my $USAGE="USAGE: $0 [-o output] file\n"; +my $VERSION = <<END; +bibzbladd v1.0 +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the +extent permitted by law. +$USAGE +END +my %opts; +getopts('o:hV',\%opts) or die $USAGE; + +if ($opts{h} || $opts{V}){ + print $VERSION; + exit 0; +} + +################################################################ +# Defaults and parameters +################################################################ + +my $inputfile = shift; + +my $outputfile = $inputfile; + +$outputfile =~ s/\.([^\.]*)$/_zbl.$1/; + +if ($opts{o}) { + $outputfile = $opts{o}; +} + +my $input = new Text::BibTeX::File "$inputfile" or + die "Cannot BibTeX file $inputfile\n"; +my $output = new Text::BibTeX::File "> $outputfile" or + die "Cannot write to $outputfile\n"; + + +# Creating the HTTP parameters +my $mirror = + "http://www.zentralblatt-math.org/MIRROR/zmath/en/search/"; +my $userAgent = LWP::UserAgent->new; + +# Processing the input +while (my $entry = new Text::BibTeX::Entry $input) { + if (!$entry->parse_ok()) { + print STDERR "Cannot understand entry: "; + $entry->print(*STDERR); + print STDERR "Skipping this entry\n"; + next; + } + if (!(($entry->metatype() eq BTE_REGULAR))) { + $entry->write($output); + next; + } + if ($entry->exists('zblnumber')) { + $entry->write($output); + next; + } + + + # Now we have an entry with no Zbl. Let us get to work. + my $zbl = GetZbl($entry, $userAgent, $mirror); + if (length($zbl)) { + $entry->set('zblnumber',$zbl); + } + $entry->write($output); + +} + +$input->close(); +$output->close(); +exit 0; + +############################################################### +# Getting one Zbl +############################################################### + +sub GetZbl { + my $entry=shift; + my $userAgent=shift; + my $mirror=shift; + + my @query; + + my @names=$entry->names ('author'); + if (scalar(@names)) { + foreach my $name (@names) { + my @lastnames = $name->part ('last'); + if (scalar(@lastnames)) { + foreach my $lastname (@lastnames) { + push @query, "au:$lastname"; + } + } + } + } + if (my $title = $entry->get('title')) { + push @query, "ti:$title"; + } + + if (my $year = $entry->get('year')) { + push @query, "py:$year"; + } + + if (my $year = $entry->get('year')) { + push @query, "py:$year"; + } + + my $type = $entry->type; + if ($type eq 'article') { + push @query, "dt:j"; + } + if ($type eq 'book') { + push @query, "dt:b"; + } + if ($type eq 'inproceedings' || $type eq 'incollection') { + push @query, "dt:a"; + } + + my $source = ""; + if ($type eq 'article') { + if ($entry->get('journal')) { + $source .= $entry->get('journal'); + } + if (my $vol=$entry->get('volume')) { + $source .= ",$vol"; + } + if (my $pages=$entry->get('pages')) { + $source .= ",$pages"; + } + } else { + if (my $bt=$entry->get('booktitle')) { + $source .= "$bt"; + } + } + + if ($source) { + push @query, "so:$source"; + } + + + my $qstring = join(" & ", @query); +# print STDERR "$qstring\n"; + + my $form; + + $form->{name}='form'; + $form->{q} = $qstring; + $form->{type} = "ascii"; + $form->{submit} = 'Search'; + + my $response = $userAgent->post($mirror, $form); + if ($response->decoded_content =~ /^an:\s*Zbl\s*(\S+)\s*$/m) { + return $1; + } else { + return (""); + } +} + diff --git a/Master/texmf-dist/scripts/crossrefware/ltx2crossrefxml.pl b/Master/texmf-dist/scripts/crossrefware/ltx2crossrefxml.pl new file mode 100755 index 00000000000..5ceee5f13df --- /dev/null +++ b/Master/texmf-dist/scripts/crossrefware/ltx2crossrefxml.pl @@ -0,0 +1,460 @@ +#!/usr/bin/env perl + +=pod + +=head1 NAME + +ltx2crossrefxml.pl - a tool for creation of XML files for submitting to crossref. + +=head1 SYNOPSIS + +ltx2crossrefxml [B<-c> I<config_file>] [B<-o> I<output>] I<latex_file> I<latex_file> ... + + +=head1 OPTIONS + +=over 4 + +=item B<-c> I<config_file> + +Configuration file. If this file is absent, some defaults are used. +See below for its format. + + +=item B<-o> I<output> + +Output file. If this option is not used, the XML is output to stdout. + +=back + +=head1 DESCRIPTION + +The script takes a number of latex files and produces an XML file +ready for submission to Crossref. Each file must be previously processed +by LaTeX with the newest C<resphilosophica> package: the package creates +the file C<.rti> wtih the information about the bibliography. + +The processing of reference list is at present rather limited: only so +called unstructured references are produced. + +=head1 CONFIGURATION FILE FORMAT + +The configuration file is mostly self-explanatory: it has comments +(starting with C<#>) and assginments in the form + + $field = value ; + +=head1 EXAMPLES + + ltx2crossrefxml.pl ../paper1/paper1.tex ../paper2/paper2.tex -o result.xml + + ltx2crossrefxml.pl -c myconfig.cnf paper.tex -o paper.xml + +=head1 AUTHOR + +Boris Veytsman + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2012 Boris Veytsman + +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +L<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to the +extent permitted by law. + + +=cut + + use strict; + use POSIX qw(strftime); + use Text::BibTeX; + use Text::BibTeX::Name; + use TeX::Encode; + use Encode; + use HTML::Entities; + use XML::Entities; + use File::Basename; + use File::Spec; + my $USAGE="USAGE: $0 [-c config] [-o output] file1 file2 ...\n"; +my $VERSION = <<END; +ltx2crossrefxml v1.0 +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the +extent permitted by law. +$USAGE +END + use Getopt::Std; + my %opts; + getopts('c:o:hV',\%opts) or die $USAGE; + +if ($opts{h} || $opts{V}){ + print $VERSION; + exit 0; +} + + ################################################################ + # Defaults and parameters + ################################################################ + + *OUT=*STDOUT; + + if (defined($opts{o})) { + open (OUT, ">$opts{o}") or die "Cannot open file $opts{o} for writing\n"; + } + + + our $depositorName='DEPOSITOR_NAME'; + our $depositorEmail='DEPOSITOR_EMAIL'; + our $registrant='REGISTRANT'; + our $fullTitle = "FULL TITLE"; + our $abbrevTitle = "ABBR. Title."; + our $issn = "1234-5678"; + our $coden = "CODEN"; + our $batchId="ltx2crossref$$"; + our $timestamp=strftime("%Y%m%d%H%M%S", gmtime); + + + if ($opts{c}) { + if (-r $opts{c}) { + require $opts{c}; + } else { + die "Cannot read options $opts{c}. $USAGE"; + } + } + + + + PrintHead(); + + # + # The hash %papers. Keys year->vol->issue->number + # + my %papers; + + foreach my $file (@ARGV) { + AddPaper($file); + } + + foreach my $year (keys %papers) { + foreach my $volume (keys %{$papers{$year}}) { + foreach my $issue (keys %{$papers{$year}->{$volume}}) { + PrintIssueHead($year, $volume, $issue); + my $paperList = $papers{$year}->{$volume}->{$issue}; + foreach my $paper (@{$paperList}) { + PrintPaper($paper); + } + } + } + + } + + PrintTail(); + + exit(0); + + +##################################################### +# Printing the head and the tail +##################################################### + +sub PrintHead { + + + print OUT <<END; +<doi_batch xmlns="http://www.crossref.org/schema/4.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="4.3.0" xsi:schemaLocation="http://www.crossref.org/schema/4.3.0 http://www.crossref.org/schema/deposit/crossref4.3.0.xsd"> + <head> + <doi_batch_id>$batchId</doi_batch_id> + <timestamp>$timestamp</timestamp> + <depositor> + <name>$depositorName</name> + <email_address>$depositorEmail</email_address> + </depositor> + <registrant>$registrant</registrant> + </head> + <body> + <journal> + <journal_metadata language="en"> + <full_title>$fullTitle</full_title> + <abbrev_title>$abbrevTitle</abbrev_title> + <issn>$issn</issn> + <coden>$coden</coden> + </journal_metadata> +END + +} + +sub PrintTail { + print OUT <<END; + </journal> + </body> +</doi_batch> +END + +return; +} + + +####################################################### +# Adding one paper +####################################################### + +sub AddPaper { + my $file = shift; + my ($name,$path,$suffix) = fileparse($file, '\.[^\.]*$'); + my $rpifile = File::Spec->catfile($path, "$name.rpi"); + open (RPI, $rpifile) or die + "Cannot find $rpifile. Did you process $file?\n"; + my %data; + while (<RPI>) { + chomp; + if (/^%([^=]*)\s*=\s*(.*)\s*$/) { + $data{$1}=$2; + } + } + close RPI; + my @bibliography; + foreach my $bibfile ($file, File::Spec->catfile($path, "$name.bbl")) { + @bibliography = (@bibliography, + AddBibliography($bibfile)); + } + $data{'bibliography'}=\@bibliography; + push @{$papers{$data{year}}->{$data{volume}}->{$data{issue}}}, \%data; +} + +############################################################## +# Reading a list of papers and adding it to the +# bibliography +############################################################## + +sub AddBibliography { + my $bibfile = shift; + open (BIB, $bibfile) or return; + my $insidebibliography = 0; + my $currpaper=""; + my @result; + my $key; + while (<BIB>) { + chomp; + if (/^\s*\\bibitem(?:\[.*\])?+\{(.+)\}/) { + if ($insidebibliography) { + if ($currpaper) { + my %paperhash; + $paperhash{$key}=$currpaper; + push @result, \%paperhash; + } + } + $key = $1; + $currpaper=""; + $insidebibliography=1; + next; + } + if (/^\s*\\end\{thebibliography\}/) { + if ($currpaper) { + my %paperhash; + $paperhash{$key}=$currpaper; + push @result, \%paperhash; + } + $currpaper=""; + $insidebibliography=0; + next; + } + if ($insidebibliography) { + $currpaper .= " $_"; + } + } + close BIB; + return @result; +} + +################################################################# +# Printing information about one issue +################################################################# + +sub PrintIssueHead { + my ($year, $volume, $issue) = @_; + print OUT <<END; + <journal_issue> + <publication_date media_type="print"> + <year>$year</year> + </publication_date> + <journal_volume> + <volume>$volume</volume> + </journal_volume> + <issue>$issue</issue> + </journal_issue> +END +} + +############################################################### +# Printing information about one paper +############################################################### +sub PrintPaper { + my $paper = shift; + my $title=SanitizeText($paper->{title}); + my $url=GetURL($paper); + print OUT <<END; + <journal_article publication_type="full_text"> + <titles> + <title> + $title + </title> + </titles> + <contributors> +END +my @authors = split /\s*\\and\s*/, $paper->{authors}; + my $seq='first'; + foreach my $author (@authors) { + print OUT <<END; + <person_name sequence="$seq" contributor_role="author"> +END +$seq='additional'; + PrintAuthor($author); + print OUT <<END; + </person_name> +END + + } + + print OUT <<END; + </contributors> + <publication_date media_type="print"> + <year>$paper->{year}</year> + </publication_date> + <pages> + <first_page>$paper->{startpage}</first_page> + <last_page>$paper->{endpage}</last_page> + </pages> + <doi_data> + <doi>$paper->{doi}</doi> + <timestamp>$timestamp</timestamp> + <resource>$url</resource> + </doi_data> +END + +if (scalar(@{$paper->{bibliography}})) { + print OUT <<END; + <citation_list> +END + foreach my $citation (@{$paper->{bibliography}}) { + PrintCitation($citation); + } + print OUT <<END; + </citation_list> +END +} + + print OUT <<END; + </journal_article> +END + + +} + + +############################################################### +# Sanitization of a text string +############################################################### +sub SanitizeText { + my $string = shift; + # There is a bug in the decode function, which we need to work + # around: it adds space to constructions like \o x + $string =~ s/(\\[a-zA-Z])\s+/$1/g; + $string =~ s/\\newblock//g; + $string =~ s/\\bgroup//g; + $string =~ s/\\egroup//g; + $string =~ s/\\scshape//g; + $string =~ s/\\urlprefix//g; + $string =~ s/\\emph//g; + $string =~ s/\\textbf//g; + $string =~ s/\\enquote//g; + $string =~ s/\\url/URL: /g; + $string =~ s/\\doi/DOI: /g; + $string =~ s/\\\\/ /g; + $string =~ s/\$//g; + $string = decode('latex', $string); + $string =~ s/\\[a-zA-Z]+/ /g; + $string =~ s/\\\\/ /g; + $string =~ s/[\[\{\}\]]/ /g; + $string = encode_entities($string); + $string = XML::Entities::numify('all', $string); + $string =~ s/amp;//g; + $string =~ s/~/ /g; + $string =~ s/\s*([\.;,])/$1/g; + return $string; +} + +################################################################ +# Printing one author +################################################################ +sub PrintAuthor { + my $author=shift; + + my $person=new Text::BibTeX::Name ($author); + + if ($person->part('first')) { + my @tokens = $person->part('first'); + my $line = join(" ", @tokens); + $line = SanitizeText($line); + print OUT <<END; + <given_name>$line</given_name> +END + + } + + if ($person->part('last')) { + my $line = SanitizeText($person->part('last')); + print OUT <<END; + <surname>$line</surname> +END + + } + + if ($person->part('jr')) { + my $line = SanitizeText($person->part('jr')); + print OUT <<END; + <suffix>$line</suffix> +END + + } + +} + +############################################################# +# Printing citations +############################################################# +sub PrintCitation { + my $paperhash=shift; + foreach my $key (keys (%{$paperhash})) { + my $citation=$paperhash->{$key}; + $citation=SanitizeText($citation); + + print OUT <<END; + <citation key="$key"> + <unstructured_citation> + $citation + </unstructured_citation> + </citation> +END +} + +} + +############################################################## +# Calculating URL +############################################################## + +sub GetURL { + my $paper = shift; + + my $result; + if ($paper->{paperUrl}) { + $result= $paper->{paperUrl} + } else { + my $doi=$paper->{doi}; + $result= 'http://www.pdcnet.org/oom/service?url_ver=Z39.88-2004&rft_val_fmt=&rft.imuse_synonym=resphilosophica&rft.DOI='.$doi.'&svc_id=info:www.pdcnet.org/collection'; + } + $result =~ s/&/&/g; + return $result; +} |