diff options
author | Karl Berry <karl@freefriends.org> | 2017-04-16 22:25:15 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-04-16 22:25:15 +0000 |
commit | 75c789c980df299fd7e82e2a4f1e40e496bf3e3e (patch) | |
tree | a1d570e5bccdf4d18955f2b59f2e4df859cac685 /Master/texmf-dist/scripts/crossrefware/bbl2bib.pl | |
parent | ca335820d525cec5e0c68237c97333b952e61778 (diff) |
crossrefware (14apr17)
git-svn-id: svn://tug.org/texlive/trunk@43866 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/crossrefware/bbl2bib.pl')
-rwxr-xr-x | Master/texmf-dist/scripts/crossrefware/bbl2bib.pl | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/crossrefware/bbl2bib.pl b/Master/texmf-dist/scripts/crossrefware/bbl2bib.pl new file mode 100755 index 00000000000..7a05297a0fd --- /dev/null +++ b/Master/texmf-dist/scripts/crossrefware/bbl2bib.pl @@ -0,0 +1,259 @@ +#!/usr/bin/env perl + +=pod + +=head1 NAME + +bbl2bib.pl - convert thebibliography environment to a bib file + +=head1 SYNOPSIS + +bbl2bib.pl [B<-o> I<output>] I<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 changing the extension to C<.bib> + + +=back + +=head1 DESCRIPTION + +The script tries to reconstruct a C<bib> file from the corresponding +C<thebibliography> environment. One can argue that this operation is +akin to reconstructing a cow from the steak. The way the script does +it is searching for the entry in the MR database, and +creating the corresponding BibTeX fields. + +The script reads a TeX or Bbl file and extracts from it the +C<thebibliography> environment. For each bibitem it creates a plain +text bibliography entry, and then tries to match it in +the database. +=head1 INPUT FILE + +We assume some structure of the input file: + +=over 4 + +=item 1. + +The bibliography is contained between the lines + + \begin{thebibliography}... + +and + + \end{thebibliography} + +=item 2. + +Each bibliography item starts from the line + + \bibitem[...]{....} + +=back + + + +=head1 EXAMPLES + + bbl2bib -o - file.tex > result.bib + bbl2bib -o result.bib file.bbl + bbl2bib file.tex + +=head1 AUTHOR + +Boris Veytsman + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2014-2017 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; +BEGIN { + # find files relative to our installed location within TeX Live + chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root + if (length($TLMaster)) { + unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs"; + } +} +use IO::File; +use BibTeX::Parser; +use FileHandle; +use LaTeX::ToUnicode qw (convert); +use Getopt::Std; +use URI::Escape; +use LWP::Simple; + +my $USAGE="USAGE: $0 [-o output] file\n"; +my $VERSION = <<END; +bbl2bib v2.1 +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 +our %opts; +getopts('c:o:s: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/\.([^\.]*)$/.bib/; + +if (exists $opts{o}) { + $outputfile = $opts{o}; +} + + + +my $input= IO::File->new($inputfile) or + die "Cannot find Bbl or TeX file $inputfile\n$USAGE\n"; +my $output = IO::File->new("> $outputfile") or + die "Cannot write to $outputfile\n$USAGE\n"; + +my $userAgent = LWP::UserAgent->new; + + +# Bibitem is a hash with the entries 'key', 'text', 'mr', +# 'zbl' +my $bibitem; + +while (<$input>) { + if (!(/\\begin\{thebibliography\}/../\\end\{thebibliography\}/) || + /\\begin\{thebibliography\}/ || /\\end\{thebibliography\}/) { + next; + } + if (/\\bibitem(\[[^\]]*\])?\{([^\}]*)\}/) { + ProcessBibitem($bibitem); + $bibitem = undef; + $bibitem->{key}=$2; + $bibitem->{text}=""; + } + if (!/^\s*$/) { + $bibitem -> {text} .= $_; + } +} +ProcessBibitem($bibitem); + + +exit 0; + +sub ProcessBibitem { + my $bibitem = shift; + my $key = $bibitem->{key}; + my $text=$bibitem->{text}; + if (!length($text) || $text =~ /^\s+$/s) { + return; + } + + my $printtext = $text; + $printtext =~ s/^(.)/% $1/mg; + print $output "$printtext"; + $text =~ s/\n/ /mg; + $text =~ s/\\bibitem(\[[^\]]*\])?\{[^\}]*\}//; + + # Arxiv entry? + if ($text =~ s/\\arxiv\{([^\}]+)\}\.?//) { + $bibitem->{arxiv}=$1; + } + + # Mr number exists? + if ($text =~ s/\\mr\{([^\}]+)\}\.?//) { + $bibitem->{mr}=$1; + } + + # zbl number exists? + if ($text =~ s/\\zbl\{([^\}]+)\}\.?//) { + $bibitem->{zbl}=$1; + } + + # doi number exists? + if ($text =~ s/\\doi\{([^\}]+)\}\.?//) { + $bibitem->{doi}=$1; + } + + $bibitem->{bib} = SearchMref($bibitem); + PrintBibitem($bibitem); + return; +} + + +sub SearchMref { + my $bibitem = shift; + my $mirror = "http://www.ams.org/mathscinet-mref"; + my $string=uri_escape_utf8($bibitem->{text}); + my $response = $userAgent->get("$mirror?ref=$string&dataType=bibtex") -> + decoded_content(); + if ($response =~ /<pre>(.*)<\/pre>/s) { + my $bib= $1; + my $fh = new FileHandle; + open $fh, "<", \$bib; + my $parser = new BibTeX::Parser($fh); + my $entry = $parser->next; + if ($entry->parse_ok()) { + $entry->key($bibitem->{key}); + return ($entry); + } + } +} + + + + +sub PrintBibitem { + print "\n"; + my $bibitem = shift; + if (!ref($bibitem->{bib})) { + return; + } + my $entry=$bibitem->{bib}; + if ($bibitem->{mr} && ! $entry->field('mrnumber')) { + $entry->field('mrnumber', $bibitem->{mr}); + } + if ($entry->field('mrnumber')) { + my $mr=$entry->field('mrnumber'); + while (length($mr)<7) { + $mr = "0$mr"; + } + $mr=$entry->field('mrnumber', $mr); + } + if ($bibitem->{zbl} && ! $entry->field('zblnumber')) { + $entry->field('zblnumber', $bibitem->{zbl}); + } + if ($bibitem->{doi} && ! $entry->field('doi')) { + $entry->field('doi', $bibitem->{doi}); + } + if ($bibitem->{arxiv} && ! $entry->field('arxiv')) { + $entry->field('arxiv', $bibitem->{arxiv}); + } + + print $entry->to_string(), "\n\n"; +} + + |