<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># autolatex - BibCitationAnalyzer.pm
# Copyright (C) 2013-14  Stephane Galland &lt;galland@arakhne.org&gt;
#
# 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&lt;use AutoLaTeX::TeX::BibCitationAnalyzer;&gt;.

=head1 FUNCTIONS

The provided functions are:

=over 4

=cut
package AutoLaTeX::TeX::BibCitationAnalyzer;

$VERSION = '4.0';
@ISA = ('Exporter');
@EXPORT = qw( &amp;getAuxBibliographyData &amp;getAuxBibliographyCitations &amp;makeAuxBibliographyCitationMd5
              &amp;getBcfBibliographyCitations &amp;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'			=&gt; '[]!{}',
	'bibcite'			=&gt; '[]!{}',
	'bibdata'			=&gt; '[]!{}',
	'bibstyle'			=&gt; '[]!{}',
	);

=pod

=item B&lt;getAuxBibliographyData($)&gt;

Parse an aux file and extract the bibliography data.

=over 4

=item * C&lt;auxfile&gt; is the name of the AUX file to parse.

=back

I&lt;Returns:&gt; an associative array with the keys 'citations', 'databases', and 'styles'.

=cut
sub getAuxBibliographyData($) {
	my $input = shift;
	local *FILE;
	open(*FILE, "&lt; $input") or printErr("$input: $!");
	my $content = '';
	while (my $line = &lt;FILE&gt;) {
		$content .= $line;
	}
	close(*FILE);

	my $listener = AutoLaTeX::TeX::BibCitationAnalyzer-&gt;_new($input);

	my $parser = AutoLaTeX::TeX::TeXParser-&gt;new("$input", $listener);

	while (my ($k,$v) = each(%MACROS)) {
		$parser-&gt;addTextModeMacro($k,$v);
		$parser-&gt;addMathModeMacro($k,$v);
	}

	$parser-&gt;parse( $content );

	my @citations = keys %{$listener-&gt;{'citations'}};
	@citations = sort @citations;
	my @databases = keys %{$listener-&gt;{'databases'}};
	my @styles = keys %{$listener-&gt;{'styles'}};
	my %data = (
		'citations' =&gt; \@citations,
		'databases' =&gt; \@databases,
		'styles' =&gt; \@styles,
	);

	return %data;
}

=pod

=item B&lt;getAuxBibliographyCitations($)&gt;

Parse an aux file and extract the bibliography citations.

=over 4

=item * C&lt;auxfile&gt; is the name of the AUX file to parse.

=back

I&lt;Returns:&gt; the included files from the TeX file into an associative array.

=cut
sub getAuxBibliographyCitations($) {
	my $input = shift;
	
	local *FILE;
	open(*FILE, "&lt; $input") or printErr("$input: $!");
	my $content = '';
	while (my $line = &lt;FILE&gt;) {
		$content .= $line;
	}
	close(*FILE);

	my $listener = AutoLaTeX::TeX::BibCitationAnalyzer-&gt;_new($input);

	my $parser = AutoLaTeX::TeX::TeXParser-&gt;new("$input", $listener);

	while (my ($k,$v) = each(%MACROS)) {
		$parser-&gt;addTextModeMacro($k,$v);
		$parser-&gt;addMathModeMacro($k,$v);
	}

	$parser-&gt;parse( $content );

	my @citations = keys %{$listener-&gt;{'citations'}};
	@citations = sort @citations;

	return @citations;
}

=pod

=item B&lt;getBcfBibliographyCitations($)&gt;

Parse a BCF (biblatex) file and extract the bibliography citations.

=over 4

=item * C&lt;bcffile&gt; is the name of the BCF file to parse.

=back

I&lt;Returns:&gt; the included files from the TeX file into an associative array.

=cut
sub getBcfBibliographyCitations($) {
	my $input = shift;
	
	local *FILE;
	open(*FILE, "&lt; $input") or printErr("$input: $!");
	my $content = '';
	while (my $line = &lt;FILE&gt;) {
		$content .= $line;
	}
	close(*FILE);

	my @citations = ();

	while ($content =~ /\Q&lt;bcf:citekey&gt;\E(.+?)\Q&lt;\/bcf:citekey&gt;\E/gs) {
		push @citations, "$1";
	}

	@citations = sort @citations;

	return @citations;
}

=pod

=item B&lt;makeAuxBibliographyCitationMd5($)&gt;

Parse an aux file, extract the bibliography citations, and build a MD5.

=over 4

=item * C&lt;auxfile&gt; is the name of the AUX file to parse.

=back

I&lt;Returns:&gt; the MD5 of the citations.

=cut
sub makeAuxBibliographyCitationMd5($) {
	my @citations = getAuxBibliographyCitations($_[0]);
	return md5_base64(@citations);
}

=pod

=item B&lt;makeBsfBibliographyCitationMd5($)&gt;

Parse an BCF (biblatex) file, extract the bibliography citations, and build a MD5.

=over 4

=item * C&lt;bcffile&gt; is the name of the BCF file to parse.

=back

I&lt;Returns:&gt; 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]-&gt;{'text'}) {
			foreach my $bibdb (split(/\s*,\s*/, $_[1]-&gt;{'text'})) {
				if ($bibdb) {
					$self-&gt;{'databases'}{$bibdb} = 1;
				}
			}
		}
	}
	elsif ($macro eq '\\bibstyle') {
		if ($_[1]-&gt;{'text'}) {
			foreach my $bibdb (split(/\s*,\s*/, $_[1]-&gt;{'text'})) {
				if ($bibdb) {
					$self-&gt;{'styles'}{$bibdb} = 1;
				}
			}
		}
	}
	elsif ($_[1]-&gt;{'text'}) {
		foreach my $bibdb (split(/\s*,\s*/, $_[1]-&gt;{'text'})) {
			if ($bibdb) {
				$self-&gt;{'citations'}{$bibdb} = 1;
			}
		}
	}
	return '';
}

sub _new($) : method {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my $parent = ref($proto) &amp;&amp; $proto ;

	my $self ;
	if ( $parent ) {
		%{$self} = %{$parent} ;
	}
	else {
		$self = {
			'basename' =&gt; basename($_[0],'.tex'),
			'file' =&gt; $_[0],
			'expandMacro' =&gt; \&amp;_expandMacro,
			'citations' =&gt; {},
			'databases' =&gt; {},
			'styles' =&gt; {},
		};
	}
	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 &lt;http://www.arakhne.org/autolatex/&gt; or send email to the author at L&lt;galland@arakhne.org&gt;.

=head1 LICENSE

S&lt;GNU Public License (GPL)&gt;

=head1 COPYRIGHT

S&lt;Copyright (c) 2013 StÃ©phane Galland E&lt;lt&gt;galland@arakhne.orgE&lt;gt&gt;&gt;

=head1 SEE ALSO

L&lt;autolatex-dev&gt;
</pre></body></html>