diff options
Diffstat (limited to 'support/autolatex/pm/AutoLaTeX/TeX/BibCitationAnalyzer.pm')
-rw-r--r-- | support/autolatex/pm/AutoLaTeX/TeX/BibCitationAnalyzer.pm | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/support/autolatex/pm/AutoLaTeX/TeX/BibCitationAnalyzer.pm b/support/autolatex/pm/AutoLaTeX/TeX/BibCitationAnalyzer.pm new file mode 100644 index 0000000000..bae9cfe2c4 --- /dev/null +++ b/support/autolatex/pm/AutoLaTeX/TeX/BibCitationAnalyzer.pm @@ -0,0 +1,307 @@ +# autolatex - BibCitationAnalyzer.pm +# Copyright (C) 2013-14 Stephane Galland <galland@arakhne.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +=pod + +=head1 NAME + +BibCitationAnalyzer.pm - Extract bibliography citation from a AUX file. + +=head1 DESCRIPTION + +Tool that is extracting the bibliography citations from a AUX file. + +To use this library, type C<use AutoLaTeX::TeX::BibCitationAnalyzer;>. + +=head1 FUNCTIONS + +The provided functions are: + +=over 4 + +=cut +package AutoLaTeX::TeX::BibCitationAnalyzer; + +$VERSION = '4.0'; +@ISA = ('Exporter'); +@EXPORT = qw( &getAuxBibliographyData &getAuxBibliographyCitations &makeAuxBibliographyCitationMd5 + &getBcfBibliographyCitations &makeBcfBibliographyCitationMd5 ) ; +@EXPORT_OK = qw(); + +require 5.014; +use strict; +use utf8; +use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION); +use Config; # Perl configuration +use File::Spec; +use File::Basename; +use Digest::MD5 qw(md5_base64); + +use AutoLaTeX::Core::Util; +use AutoLaTeX::TeX::TeXParser; + +my %MACROS = ( + 'citation' => '[]!{}', + 'bibcite' => '[]!{}', + 'bibdata' => '[]!{}', + 'bibstyle' => '[]!{}', + ); + +=pod + +=item B<getAuxBibliographyData($)> + +Parse an aux file and extract the bibliography data. + +=over 4 + +=item * C<auxfile> is the name of the AUX file to parse. + +=back + +I<Returns:> an associative array with the keys 'citations', 'databases', and 'styles'. + +=cut +sub getAuxBibliographyData($) { + my $input = shift; + local *FILE; + open(*FILE, "< $input") or printErr("$input: $!"); + my $content = ''; + while (my $line = <FILE>) { + $content .= $line; + } + close(*FILE); + + my $listener = AutoLaTeX::TeX::BibCitationAnalyzer->_new($input); + + my $parser = AutoLaTeX::TeX::TeXParser->new("$input", $listener); + + while (my ($k,$v) = each(%MACROS)) { + $parser->addTextModeMacro($k,$v); + $parser->addMathModeMacro($k,$v); + } + + $parser->parse( $content ); + + my @citations = keys %{$listener->{'citations'}}; + @citations = sort @citations; + my @databases = keys %{$listener->{'databases'}}; + my @styles = keys %{$listener->{'styles'}}; + my %data = ( + 'citations' => \@citations, + 'databases' => \@databases, + 'styles' => \@styles, + ); + + return %data; +} + +=pod + +=item B<getAuxBibliographyCitations($)> + +Parse an aux file and extract the bibliography citations. + +=over 4 + +=item * C<auxfile> is the name of the AUX file to parse. + +=back + +I<Returns:> the included files from the TeX file into an associative array. + +=cut +sub getAuxBibliographyCitations($) { + my $input = shift; + + local *FILE; + open(*FILE, "< $input") or printErr("$input: $!"); + my $content = ''; + while (my $line = <FILE>) { + $content .= $line; + } + close(*FILE); + + my $listener = AutoLaTeX::TeX::BibCitationAnalyzer->_new($input); + + my $parser = AutoLaTeX::TeX::TeXParser->new("$input", $listener); + + while (my ($k,$v) = each(%MACROS)) { + $parser->addTextModeMacro($k,$v); + $parser->addMathModeMacro($k,$v); + } + + $parser->parse( $content ); + + my @citations = keys %{$listener->{'citations'}}; + @citations = sort @citations; + + return @citations; +} + +=pod + +=item B<getBcfBibliographyCitations($)> + +Parse a BCF (biblatex) file and extract the bibliography citations. + +=over 4 + +=item * C<bcffile> is the name of the BCF file to parse. + +=back + +I<Returns:> the included files from the TeX file into an associative array. + +=cut +sub getBcfBibliographyCitations($) { + my $input = shift; + + local *FILE; + open(*FILE, "< $input") or printErr("$input: $!"); + my $content = ''; + while (my $line = <FILE>) { + $content .= $line; + } + close(*FILE); + + my @citations = (); + + while ($content =~ /\Q<bcf:citekey>\E(.+?)\Q<\/bcf:citekey>\E/gs) { + push @citations, "$1"; + } + + @citations = sort @citations; + + return @citations; +} + +=pod + +=item B<makeAuxBibliographyCitationMd5($)> + +Parse an aux file, extract the bibliography citations, and build a MD5. + +=over 4 + +=item * C<auxfile> is the name of the AUX file to parse. + +=back + +I<Returns:> the MD5 of the citations. + +=cut +sub makeAuxBibliographyCitationMd5($) { + my @citations = getAuxBibliographyCitations($_[0]); + return md5_base64(@citations); +} + +=pod + +=item B<makeBsfBibliographyCitationMd5($)> + +Parse an BCF (biblatex) file, extract the bibliography citations, and build a MD5. + +=over 4 + +=item * C<bcffile> is the name of the BCF file to parse. + +=back + +I<Returns:> the MD5 of the citations. + +=cut +sub makeBcfBibliographyCitationMd5($) { + my @citations = getBcfBibliographyCitations($_[0]); + return md5_base64(@citations); +} + +sub _expandMacro($$@) : method { + my $self = shift; + my $parser = shift; + my $macro = shift; + if ($macro eq '\\bibdata') { + if ($_[1]->{'text'}) { + foreach my $bibdb (split(/\s*,\s*/, $_[1]->{'text'})) { + if ($bibdb) { + $self->{'databases'}{$bibdb} = 1; + } + } + } + } + elsif ($macro eq '\\bibstyle') { + if ($_[1]->{'text'}) { + foreach my $bibdb (split(/\s*,\s*/, $_[1]->{'text'})) { + if ($bibdb) { + $self->{'styles'}{$bibdb} = 1; + } + } + } + } + elsif ($_[1]->{'text'}) { + foreach my $bibdb (split(/\s*,\s*/, $_[1]->{'text'})) { + if ($bibdb) { + $self->{'citations'}{$bibdb} = 1; + } + } + } + return ''; +} + +sub _new($) : method { + my $proto = shift; + my $class = ref($proto) || $proto; + my $parent = ref($proto) && $proto ; + + my $self ; + if ( $parent ) { + %{$self} = %{$parent} ; + } + else { + $self = { + 'basename' => basename($_[0],'.tex'), + 'file' => $_[0], + 'expandMacro' => \&_expandMacro, + 'citations' => {}, + 'databases' => {}, + 'styles' => {}, + }; + } + bless( $self, $class ); + return $self; +} + +1; +__END__ +=back + +=head1 BUG REPORT AND FEEDBACK + +To report bugs, provide feedback, suggest new features, etc. visit the AutoLaTeX Project management page at <http://www.arakhne.org/autolatex/> or send email to the author at L<galland@arakhne.org>. + +=head1 LICENSE + +S<GNU Public License (GPL)> + +=head1 COPYRIGHT + +S<Copyright (c) 2013 Stéphane Galland E<lt>galland@arakhne.orgE<gt>> + +=head1 SEE ALSO + +L<autolatex-dev> |