#!/usr/bin/perl my $version = "v1.1"; use strict; use warnings; # warn user (from perspective of caller) use Carp; # use nice English (or awk) names for ugly punctuation variables use English qw(-no_match_vars); # folder Mendeley exports .bib files to assumed to be "%HOME%/bib_files": #use File::HomeDir; use File::Spec; my ($tex_file, $mendeley_bib_base) = @ARGV; #to compare last modified dates use File::stat; # find used .bib file names open my $TEXFILE, $tex_file or croak "Cannot open $tex_file: $OS_ERROR"; my @bib_files; while (<$TEXFILE>) { if (/^[^%]*\\addbibresource\{([^\{\}]*)\}/) { push @bib_files, $1; } } close $TEXFILE or croak "Cannot close $tex_file: $OS_ERROR"; foreach my $out_file (@bib_files) { my $in_file = File::Spec->catfile($mendeley_bib_base, $out_file); # if Mendeley's .bib file is older than the previously patched one (the one in this folder), skip it my $sin_file = stat($in_file); my $sout_file = stat($out_file); if ($sin_file && $sout_file && $sin_file->mtime <= $sout_file->mtime) { print "skipping $out_file (already up to date)"; next; } print "importing and patching $in_file"; open my $INFILE, $in_file or warn "skipping $out_file (Could not open $in_file: $OS_ERROR)" and next; open my $OUTFILE, '>', $out_file or croak "Cannot open $out_file: $OS_ERROR"; print { $OUTFILE } "Do not edit! File automatically generated by patching $in_file using \"patch.bib.pl $version\". \n\n" and print { $OUTFILE } '@preamble{ " \providecommand{\noop}[1]{} " } % a do-nothing command that serves a purpose' and print { $OUTFILE } "\n\n" or croak "Cannot write to $out_file: $OS_ERROR"; while(<$INFILE>) { # remove double brackets around titles and add brackes around words that contain non primal upper case letters like FBI or iPhone or numbers like Cas9 and around single uppercase latters other than "A": if (/title ?= ?\{.*\},/) { s/^title ?= ?\{\{([^\n]*)\}\},$/title = \{$1\},/; s/((?:(?=\w+[A-Z]|[A-z]\w*[0-9])\w+|[B-Z](?=\W))|(?:".*"))/\{$1\}/g; } # Allow encoding "in press" articles in Medeley by using years 3000 to 3999 (can be used to order items): s/^year ?= ?\{(3[0-9]{3})\}/year = \{\\noop\{$1\}in press\}/; print { $OUTFILE } $_ or warn "Cannot write to $out_file: $OS_ERROR" and next; } close $INFILE or croak "Cannot close $in_file: $OS_ERROR"; close $OUTFILE or croak "Cannot close $out_file: $OS_ERROR"; }