<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/env perl

=pod

=head1 NAME

bibmradd.pl - add MR numbers to papers in a given bib file

=head1 SYNOPSIS

bibmradd  [-d] [B&lt;-f&gt;] [B&lt;-e&gt; 1|0] [B&lt;-o&gt; I&lt;output&gt;] I&lt;bib_file&gt;

=head1 OPTIONS

=over 4

=item B&lt;-d&gt;

Debug mode

=item B&lt;-e&gt;

If 1 (default), add an empty mrnumber if a mr cannot be found.  This
prevents repeated searches for the same entries if you add new entries
to the file.  Calling C&lt;-e 0&gt; suppresses this behavior.


=item B&lt;-f&gt;

Force searching for MR numbers even if the entry already has one.

=item B&lt;-o&gt; I&lt;output&gt;

Output file.  If this option is not used, the name for the 
output file is formed by adding C&lt;_mr&gt; to the input file

=back

=head1 DESCRIPTION

The script reads a BibTeX file. It checks whether the entries have
mrnumbers. If not, it tries to find the numbers from Internet sites. The
result is a BibTeX file with C&lt;mrnumber=...&gt; fields added.

The name of the output file is either set by the B&lt;-o&gt; option or 
is derived by adding the suffix C&lt;_mr&gt; to the output file.

See the C&lt;bibdoiadd&gt; script for more details on the processing.

=head1 AUTHOR

Boris Veytsman

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2014-2024 Boris Veytsman

This is free software.  You may redistribute copies of it under the
terms of the GNU General Public License
L&lt;http://www.gnu.org/licenses/gpl.html&gt;.  There is NO WARRANTY, to the
extent permitted by law.

=cut

use strict; use warnings;
use Cwd;
use File::Basename;
use File::Spec;

BEGIN {
    # find files relative to our installed location within TeX Live
    chomp(my $TLMaster = `kpsewhich -var-value=TEXMFROOT`); # TL root
    if (length($TLMaster)) {
	unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs";
    }
     # find development bibtexperllibs in sibling checkout to this script,
     # even if $0 is a symlink. All irrelevant when using from an installation.
     my $real0 = Cwd::abs_path($0);
     my $scriptdir = File::Basename::dirname($real0);
     my $dev_btxperllibs = Cwd::abs_path("$scriptdir/../bibtexperllibs");
     # we need the lib/ subdirectories inside ...
     unshift (@INC, glob ("$dev_btxperllibs/*/lib")) if -d $dev_btxperllibs;
}
use IO::File;
use BibTeX::Parser;
use Getopt::Std;
use URI::Escape;
use LWP::UserAgent;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
# Sometimes AMS forgets to update certificates
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;

my $USAGE="USAGE: $0  [-d] [-e 1|0] [-f] [-o output] file\n";
my $VERSION = &lt;&lt;END;
bibmradd v2.3
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('de:fo: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/\.([^\.]*)$/_mr.$1/;

if ($opts{o}) {
    $outputfile = $opts{o};
}

my $forceSearch=$opts{f};

my $forceEmpty = 1;
if (exists $opts{e}) {
    $forceEmpty = $opts{e};
}		

my $debug = $opts{d};

my $input= IO::File-&gt;new($inputfile) or 
    die "Cannot find BibTeX file $inputfile\n$USAGE\n";
my $output = IO::File-&gt;new("&gt; $outputfile") or 
    die "Cannot write to $outputfile\n$USAGE\n";

my $parser=new BibTeX::Parser($input);



# Creating the HTTP parameters
my $mirror =
    "http://www.ams.org/mathscinet-mref";
my $userAgent = LWP::UserAgent-&gt;new;

while (my $entry = $parser-&gt;next ) {
    if (!$entry-&gt;parse_ok()) {
	print STDERR "Cannot understand entry: ";
	$entry-&gt;print(*STDERR);
	print STDERR "Skipping this entry\n";
	next;
    }
    if ($entry-&gt;has('mrnumber') &amp;&amp; !$forceSearch) {
	print $output $entry-&gt;raw_bibtex(), "\n\n";
	if ($debug) {
	    print STDERR "DEBUG:  entry ", $entry-&gt;key(), 
	    " has mrnumber ", $entry-&gt;field('mrnumber'), 
	    " and no forced search is requested\n";
	}
	next;
    }
    

     # Now we have an entry with no MR.  Let us get to work.
    if ($debug) {
	print STDERR "DEBUG:  Searching for mr number for entry ",
	$entry-&gt;key, "\n";
    }
     my $mr = GetMr($entry, $userAgent, $mirror);
     if (length($mr) || $forceEmpty) {
 	$entry-&gt;field('mrnumber', $mr);
     }
    print $output $entry-&gt;to_string(), "\n\n";

}

$input-&gt;close();
$output-&gt;close();
exit 0;

###############################################################
#  Getting one MR
###############################################################

sub GetMr {
    my $entry=shift;
    my $userAgent=shift;
    my $mirror=shift;
    
    my @query;

    my $string=uri_escape_utf8($entry-&gt;to_string());
    
    if ($debug) {
	print STDERR "DEBUG:  query: $mirror?ref=$string&amp;dataType=bibtex\n" ;
    }


    my $response = $userAgent-&gt;get("$mirror?ref=$string&amp;dataType=bibtex");
    if ($debug) {
	print STDERR "DEBUG:  response: ",
	$response-&gt;decoded_content, "\n";
    }
    
    if ($response-&gt;decoded_content =~ /MRNUMBER\s*=\s*{(.*)}/m) {
	my $mr=$1;
	# Somehow mref deletes leading zeros.  They are needed!
	while (length($mr)&lt;7) {
	    $mr = "0$mr";
	}
	if ($debug) {
	    print STDERR "DEBUG:  got MR: $mr\n",
	}
	return $mr;
     } else {
	if ($debug) {
	    print STDERR "DEBUG: Did not get MR\n",
	}
 	return ("");
    }

}
</pre></body></html>