summaryrefslogtreecommitdiff
path: root/support/autolatex/pm/AutoLaTeX/Core/Config.pm
diff options
context:
space:
mode:
Diffstat (limited to 'support/autolatex/pm/AutoLaTeX/Core/Config.pm')
-rw-r--r--support/autolatex/pm/AutoLaTeX/Core/Config.pm876
1 files changed, 876 insertions, 0 deletions
diff --git a/support/autolatex/pm/AutoLaTeX/Core/Config.pm b/support/autolatex/pm/AutoLaTeX/Core/Config.pm
new file mode 100644
index 0000000000..9859ee8dec
--- /dev/null
+++ b/support/autolatex/pm/AutoLaTeX/Core/Config.pm
@@ -0,0 +1,876 @@
+# autolatex - Config.pm
+# Copyright (C) 1998-15 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
+
+Config.pm - Configuration Files
+
+=head1 DESCRIPTION
+
+Provides a set of utilities for manipulating cofiguration files.
+
+To use this library, type C<use AutoLaTeX::Core::Config;>.
+
+=head1 FUNCTIONS
+
+The provided functions are:
+
+=over 4
+
+=cut
+package AutoLaTeX::Core::Config;
+
+$VERSION = '36.0';
+@ISA = ('Exporter');
+@EXPORT = qw( &getProjectConfigFilename &getUserConfigFilename &getSystemConfigFilename
+ &getSystemISTFilename &readConfiguration &readConfigFile &getUserConfigDirectory
+ &cfgBoolean &doConfigurationFileFixing &cfgToBoolean &writeConfigFile
+ &readOnlySystemConfiguration &readOnlyUserConfiguration &readOnlyProjectConfiguration
+ &setInclusionFlags &reinitInclusionFlags &cfgIsBoolean &rebuiltConfigValue ) ;
+@EXPORT_OK = qw();
+
+require 5.014;
+use strict;
+use utf8;
+use warnings;
+use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
+
+use File::Spec;
+use Config::Simple;
+
+use AutoLaTeX::Core::OS;
+use AutoLaTeX::Core::Util;
+use AutoLaTeX::Core::IntUtils;
+
+# Constant that is representing an empty string in the INI file.
+# This constant is mandatory because Config::Simple does not
+# support the empty values, such as "KEY =". In place,
+# the INI file must contains something like "KEY = <<<<empty>>>>".
+use constant EMPTY_INI_VALUE => '<<<<empty>>>>';
+
+#######################################################
+# Comments for the sections of the configuration file
+my %SECTION_COMMENTS = (
+ 'viewer' => _T("Configuration of the viewing functions"),
+ 'generation' => _T("Configuration of the generation functions"),
+ 'clean' => _T("Configuration of the several cleaning functions"),
+ 'scm' => _T("Configuration of the SCM functions"),
+ 'gtk' => _T("GTK interface configuration"),
+ 'qt' => _T("Qt interface configuration"),
+ 'windows' => _T("Windows interface configuration"),
+ 'macos' => _T("MacOS interface configuration"),
+ 'wxwidget' => _T("wxWidgets interface configuration"),
+);
+
+#######################################################
+# Comments for the public configuration entries
+my %CONFIGURATION_COMMENTS = (
+ # <NO CATEGORY>
+ # CLEAN
+ 'clean.files to clean' => _T( "List of additional files to remove when cleaning (shell ".
+ "wild cards are allowed). This list is used when the ".
+ "target 'clean' is invoked."),
+ 'clean.files to desintegrate' => _T( "List of additional files to remove when all cleaning ".
+ "(shell wild cards are allowed). This list is used when ".
+ "the target 'cleanall' is invoked."),
+ # GENERATION
+ 'generation.biblio' => _T( "Indicates if bibliography tool (bibtex,biber) should be run ('yes' or 'no')."),
+ 'generation.generate images' => _T( "Does the figures must be automatically generated ('yes' or 'no')?"),
+ 'generation.image directory' => _T( "Specify the directories inside which AutoLaTeX ".
+ "will find the pictures which must be processed ".
+ "by the translators. Each time this option is ".
+ "put on the command line, a directory is added ".
+ "inside the list of the directories to explore. ".
+ "The different paths are separated by the ".
+ "path-separator character (':' on Unix, ';' on ".
+ "Windows)"),
+ 'generation.main file' => _T( "Main filename (this option is only available in project's ".
+ "configuration files)."),
+ 'generation.generation type' => _T( "Type of generation.\n pdf : use pdflatex to create a ".
+ "PDF document."),
+ 'generation.makeglossaries' => _T( "Indicates if glossary tool (makeglossaries) should be run ('yes' or 'no')."),
+ 'generation.makeindex style' => _T( "Specify the style that must be used by makeindex.\n".
+ "Valid values are:\n <filename> if a filename ".
+ "was specified, AutoLaTeX assumes that it is the .ist ".
+ "file;\n \@system AutoLaTeX uses the system ".
+ "default .ist file (in AutoLaTeX distribution);\n".
+ " \@detect AutoLaTeX will tries to find a .ist ".
+ "file in the project's directory. If none was found, ".
+ "AutoLaTeX will not pass a style to makeindex;\n \@none".
+ " AutoLaTeX assumes that no .ist file must be ".
+ "passed to makeindex;\n <empty> AutoLaTeX assumes ".
+ "that no .ist file must be passed to makeindex."),
+ 'generation.post compilation runs' => _T( "Defines the minimal number of times the LaTeX compilation tools (usually ".
+ "pdflatex) is run during the last running stage of AutoLaTeX. The default value is 1."),
+ 'generation.translator include path' => _T( "Defines the paths from which the translators could be ".
+ "loaded. This is a list of paths separated by the path ".
+ "separator character used by your operating system: ':' ".
+ "on Unix platforms or ';' on Windows platforms for example."),
+ 'generation.synctex' => _T( "Indicates if the PDF document must be produced with the SyncTeX flag on or not. ".
+ "SyncTeX enables to link a PDF viewer (as evince) and a text editor (as Gedit). ".
+ "When you click inside one, the other is highlighting the line in its side."),
+ # SCM
+ 'scm.scm commit' => _T( "Tool to launch when a SCM commit action is requested. ".
+ "Basically the SCM tools are CVS, SVN, or GIT."),
+ 'scm.scm update' => _T( "Tool to launch when a SCM update action is requested. ".
+ "Basically the SCM tools are CVS, SVN, or GIT."),
+ # VIEWER
+ 'viewer.view' => _T( "Indicates if a viewer should be launch after the compilation. ".
+ "Valid values are 'yes' and 'no'."),
+ 'viewer.viewer' => _T( "Specify, if not commented,the command line of the viewer."),
+ 'viewer.asynchronous run' => _T( "Indicates if the viewer is launched in background, or not."),
+);
+
+#######################################################
+# Comments for the private configuration entries
+# action.create config file
+# action.create ist file
+# action.fix config file
+# config.command line
+# input.project directory
+# input.latex file
+# output.directory
+# ouput.ist file
+# output.latex basename
+
+
+=pod
+
+=item B<getProjectConfigFilename(@)>
+
+Replies the name of a project's configuration file
+which is located inside the given directory.
+
+I<Parameters:>
+
+=over 8
+
+=item * the components of the paths, each parameter is a directory in the path.
+
+=back
+
+I<Returns:> the configuration filename according to the current operating system rules.
+
+=cut
+sub getProjectConfigFilename(@) {
+ my $operatingsystem = getOperatingSystem();
+ if (("$operatingsystem" eq 'Unix')||(("$operatingsystem" eq 'Cygwin'))) {
+ return File::Spec->rel2abs(File::Spec->catfile(@_,".autolatex_project.cfg"));
+ }
+ else {
+ return File::Spec->rel2abs(File::Spec->catfile(@_,"autolatex_project.cfg"));
+ }
+}
+
+=pod
+
+=item B<getUserConfigFilename()>
+
+Replies the name of a user's configuration file.
+
+I<Returns:> the configuration filename according to the current operating system rules.
+
+=cut
+sub getUserConfigFilename() {
+ my $confdir = getUserConfigDirectory();
+ if (-d "$confdir") {
+ return File::Spec->catfile("$confdir","autolatex.conf");
+ }
+ my $operatingsystem = getOperatingSystem();
+ if (("$operatingsystem" eq 'Unix')||(("$operatingsystem" eq 'Cygwin'))) {
+ return File::Spec->rel2abs(File::Spec->catfile($ENV{'HOME'},".autolatex"));
+ }
+ elsif ("$operatingsystem" eq 'Win32') {
+ return File::Spec->rel2abs(File::Spec->catfile("C:","Documents and Settings",$ENV{'USER'},"Local Settings","Application Data","autolatex.conf"));
+ }
+ else {
+ return File::Spec->rel2abs(File::Spec->catfile($ENV{'HOME'},"autolatex.conf"));
+ }
+}
+
+=pod
+
+=item B<getUserConfigDirectory()>
+
+Replies the name of a user's configuration directory.
+
+I<Returns:> the configuration directory according to the current operating system rules.
+
+=cut
+sub getUserConfigDirectory() {
+ my $operatingsystem = getOperatingSystem();
+ if (("$operatingsystem" eq 'Unix')||(("$operatingsystem" eq 'Cygwin'))) {
+ return File::Spec->rel2abs(File::Spec->catfile($ENV{'HOME'},".autolatex"));
+ }
+ elsif ("$operatingsystem" eq 'Win32') {
+ return File::Spec->rel2abs(File::Spec->catfile("C:","Documents and Settings",$ENV{'USER'},"Local Settings","Application Data","autolatex"));
+ }
+ else {
+ return File::Spec->rel2abs(File::Spec->catfile($ENV{'HOME'},"autolatex"));
+ }
+}
+
+=pod
+
+=item B<getSystemConfigFilename()>
+
+Replies the name of the configuration file for all users.
+
+I<Returns:> the configuration filename according to the current operating system rules.
+
+=cut
+sub getSystemConfigFilename() {
+ return File::Spec->catfile(getAutoLaTeXDir(),"default.cfg");
+}
+
+=pod
+
+=item B<getSystemISTFilename()>
+
+Replies the name of the MakeIndex style file for all users.
+
+I<Returns:> the filename according to the current operating system rules.
+
+=cut
+sub getSystemISTFilename() {
+ return File::Spec->catfile(getAutoLaTeXDir(),"default.ist");
+}
+
+=pod
+
+=item B<cfgBoolean($;$)>
+
+Replies the Perl boolean value that corresponds to the specified
+string. If the first parameter is not a valid boolean string, the second
+parameter will be replied if it is specified; if not undef will be replied;
+
+The valid string are (case insensitive): S<true>, S<false>, S<yes>, S<no>.
+
+I<Parameters:>
+
+=over 8
+
+=item * the value to test.
+
+=item * the data structure to fill
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub cfgBoolean($;$) {
+ if ($_[0]) {
+ my $v = lc($_[0]);
+ return 1 if (($v eq 'yes')||($v eq 'true'));
+ return 0 if (($v eq 'no')||($v eq 'false'));
+ }
+ return $_[1];
+}
+
+=pod
+
+=item B<cfgToBoolean($)>
+
+Replies the configuration's file boolean value that corresponds to the specified
+Perl boolean value.
+
+I<Parameters:>
+
+=over 8
+
+=item * the value to test.
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub cfgToBoolean($) {
+ return ($_[0]) ? 'true' : 'false';
+}
+
+=pod
+
+=item B<cfgIsBoolean($)>
+
+Replies if the specified string is a valid boolean string.
+
+I<Parameters:>
+
+=over 8
+
+=item * the value to test.
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub cfgIsBoolean($) {
+ if (defined($_[0])) {
+ my $v = lc($_[0]);
+ return 1
+ if (($v eq 'yes')||($v eq 'no')||($v eq 'true')||($v eq 'false'));
+ }
+ return 0;
+}
+
+=pod
+
+=item B<readConfiguration()>
+
+Replies the current configuration. The configuration
+is extracted from the system configuration file
+(from AutoLaTeX distribution) and from the user
+configuration file.
+
+I<Returns:> a hashtable containing (attribute name, attribute value) pairs.
+The attribute name could be S<section.attribute> to describe the attribute inside
+a section.
+
+=cut
+sub readConfiguration() {
+ my %configuration = ();
+ my $systemFile = getSystemConfigFilename();
+ my $userFile = getUserConfigFilename();
+ readConfigFile("$systemFile",\%configuration);
+ readConfigFile("$userFile",\%configuration);
+ # Remove the main intput filename
+ if (exists $configuration{'generation.main file'}) {
+ delete $configuration{'generation.main file'};
+ }
+ return %configuration;
+}
+
+=pod
+
+=item B<readOnlySystemConfiguration()>
+
+Replies the current configuration. The configuration
+is extracted from the system configuration file
+(from AutoLaTeX distribution) only.
+
+I<Returns:> a hashtable containing (attribute name, attribute value) pairs.
+The attribute name could be S<section.attribute> to describe the attribute inside
+a section.
+
+=cut
+sub readOnlySystemConfiguration(;$) {
+ my %configuration = ();
+ my $systemFile = getSystemConfigFilename();
+ readConfigFile("$systemFile",\%configuration,$_[0]);
+ # Remove the main intput filename
+ if (exists $configuration{'generation.main file'}) {
+ delete $configuration{'generation.main file'};
+ }
+ return %configuration;
+}
+
+=pod
+
+=item B<readOnlyUserConfiguration(;$)>
+
+Replies the current configuration. The configuration
+is extracted from the user configuration file
+($HOME/.autolatex or $HOME/.autolatex/autolatex.conf) only.
+
+I<Returns:> a hashtable containing (attribute name, attribute value) pairs.
+The attribute name could be S<section.attribute> to describe the attribute inside
+a section.
+
+=cut
+sub readOnlyUserConfiguration(;$) {
+ my %configuration = ();
+ my $userFile = getUserConfigFilename();
+ readConfigFile("$userFile",\%configuration,$_[0]);
+ # Remove the main intput filename
+ if (exists $configuration{'generation.main file'}) {
+ delete $configuration{'generation.main file'};
+ }
+ return %configuration;
+}
+
+=pod
+
+=item B<readOnlyProjectConfiguration(@)>
+
+Replies the current configuration. The configuration
+is extracted from the project configuration file
+($PROJECT_PATH/.autolatex_project.cfg) only.
+
+I<Returns:> a hashtable containing (attribute name, attribute value) pairs.
+The attribute name could be S<section.attribute> to describe the attribute inside
+a section.
+
+=cut
+sub readOnlyProjectConfiguration(@) {
+ my %configuration = ();
+ my $userFile = getProjectConfigFilename(@_);
+ if (-r "$userFile") {
+ readConfigFile("$userFile",\%configuration);
+ $configuration{'__private__'}{'input.project directory'} = File::Spec->catfile(@_);
+ return \%configuration;
+ }
+ return undef;
+}
+
+=pod
+
+=item B<readConfigFile($\%;$)>
+
+Fill the configuration data structure from the specified file information.
+The structure of the filled hashtable is a set of (attribute name, attribute value) pairs.
+The attribute name could be S<section.attribute> to describe the attribute inside
+a section.
+
+I<Parameters:>
+
+=over 8
+
+=item * the name of the file to read
+
+=item * the data structure to fill
+
+=item * boolean value that indicates if a warning message should be ignored when an old fashion file was detected.
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub readConfigFile($\%;$) {
+ my $filename = shift;
+ die('second parameter of readConfigFile() is not a hash') unless(isHash($_[0]));
+ printDbg(formatText(_T("Opening configuration file {}"),$filename));
+ if (-r "$filename") {
+ my $cfgReader = new Config::Simple("$filename");
+ if ($cfgReader) {
+ my %config = $cfgReader->vars();
+ my $warningDisplayed = $_[1];
+ while (my ($k,$v) = each (%config)) {
+ $k = lc("$k");
+ if ($k !~ /^__private__/) {
+ ($k,$v) = ensureAccendentCompatibility("$k",$v,"$filename",$warningDisplayed);
+ $v = rebuiltConfigValue("$k",$v);
+ if ($v) {
+ $_[0]->{"$k"} = $v;
+ }
+ }
+ }
+ }
+ printDbg(_T("Succeed on reading"));
+ }
+ else {
+ printDbg(formatText(_T("Failed to read {}: {}"),$filename,$!));
+ }
+ 1;
+}
+
+# Put formatted comments inside an array
+sub pushComment(\@$;$) {
+ my $limit = $_[2] || 60;
+ $limit = 1 unless ($limit>=1);
+ my @lines = split(/\n/, $_[1]);
+ foreach my $line (@lines) {
+ my @words = split(/\s+/, $line);
+ my $wline = '';
+ if ($line =~ /^(\s+)/) {
+ $wline .= $1;
+ }
+ foreach my $w (@words) {
+ if ((length($wline)+length($w)+1)>$limit) {
+ push @{$_[0]}, "#$wline\n";
+ if (length($w)>$limit) {
+ while (length($w)>$limit) {
+ push @{$_[0]}, "# ".substr($w,0,$limit)."\n";
+ $w = substr($w,$limit);
+ }
+ }
+ $wline = " $w";
+ }
+ else {
+ $wline .= " $w";
+ }
+ }
+ if ($wline) {
+ push @{$_[0]}, "#$wline\n";
+ }
+ }
+}
+
+# Reformat the value to be written inside a configuration file.
+# $_[0]: value name,
+# $_[1]: value to validated.
+sub serializeConfigValue($$) {
+ my $v = $_[1];
+ if (isArray($v)) {
+ $v = '';
+ foreach my $ev (@{$_[1]}) {
+ if ($v) {
+ $v .= ', ';
+ }
+ $v .= &serializeConfigValue($_[0], $ev);
+ }
+ }
+ elsif (isHash($v)) {
+ $v = '';
+ while (my ($key, $value) = each(%{$_[1]})) {
+ if ($v) {
+ $v .= ', ';
+ }
+ $v .= "$key:{";
+ $v .= &serializeConfigValue($_[0], $value);
+ $v .= "}";
+ }
+ }
+ return $v;
+}
+
+=pod
+
+=item B<writeConfigFile($\%;$)>
+
+Write the specified configuration into a file.
+
+I<Parameters:>
+
+=over 8
+
+=item * the name of the file to write
+
+=item * the configuration data structure to write
+
+=item * (optional) indicates if the comments must be written
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub writeConfigFile($\%;$) {
+ my $filename = shift;
+ die('second parameter of writeConfigFile() is not a hash') unless(isHash($_[0]));
+
+ # Write the values
+ printDbg(formatText(_T("Writing configuration file {}"),$filename));
+ printDbgIndent();
+ my $cfgWriter = new Config::Simple(syntax=>'ini');
+ my $has = 0;
+ while (my ($attr,$value) = each (%{$_[0]})) {
+ if ($value && $attr ne '__private__') {
+ $value = serializeConfigValue($attr, $value);
+ if ($value) {
+ $cfgWriter->param("$attr",$value);
+ $has = 1;
+ }
+ }
+ }
+ if ($has) {
+ $cfgWriter->write("$filename") or printErr($cfgWriter->error());
+
+ if ($_[1]) {
+ # Updating for comments
+ printDbg(_T("Adding configuration comments"));
+ local *CFGFILE;
+ open (*CFGFILE, "< $filename") or printErr("$filename:","$!");
+ my @lines = ();
+ my $lastsection = undef;
+ while (my $l = <CFGFILE>) {
+ if ($l =~ /^\s*\[\s*(.+?)\s*\]\s*$/) {
+ $lastsection = lc($1);
+ if ($SECTION_COMMENTS{"$lastsection"}) {
+ push @lines, "\n";
+ pushComment @lines, $SECTION_COMMENTS{"$lastsection"};
+ }
+ else {
+ push @lines, "\n";
+ pushComment @lines, _T("Configuration of the translator")." '$lastsection'";
+ }
+ }
+ elsif (($l =~ /^\s*(.*?)\s*=/)&&($lastsection)) {
+ my $attr = lc($1);
+ if ($CONFIGURATION_COMMENTS{"$lastsection.$attr"}) {
+ push @lines, "\n";
+ pushComment @lines, $CONFIGURATION_COMMENTS{"$lastsection.$attr"};
+ }
+ }
+ push @lines, $l;
+ }
+ close(*CFGFILE);
+
+ printDbg(_T("Saving configuration comments"));
+ local *CFGFILE;
+ open (*CFGFILE, "> $filename") or printErr("$filename:","$!");
+ print CFGFILE (@lines);
+ close(*CFGFILE);
+ }
+ }
+ else {
+ # Create an empty file
+ open (*CFGFILE, "> $filename") or printErr("$filename:","$!");
+ close(*CFGFILE);
+ }
+ printDbgUnindent();
+ 1;
+}
+
+=pod
+
+=item B<doConfigurationFileFixing($)>
+
+Fix the specified configuration file.
+
+I<Parameters:>
+
+=over 8
+
+=item * the name of the file to fix
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub doConfigurationFileFixing($) {
+ my $filename = shift;
+ my %configuration = ();
+
+ readConfigFile("$filename",%configuration,1);
+
+ writeConfigFile("$filename",%configuration);
+
+ 1;
+}
+
+# Try to detect an old fashioned configuration file
+# and fix the value
+sub ensureAccendentCompatibility($$$$) {
+ my $k = $_[0];
+ my $v = $_[1];
+ my $changed = 0;
+ $v = '' unless (defined($v));
+
+ if ($k eq 'generation.bibtex') {
+ $k = 'generation.biblio';
+ $changed = 1;
+ }
+
+ if (!isArray($v)) {
+ # Remove comments on the same line as values
+ if ($v =~ /^\s*(.*?)\s*\#.*$/) {
+ $v = "$1" ;
+ $changed = 1;
+ }
+
+ if ($v eq '@detect@system') {
+ $v = ['detect','system'];
+ $changed = 1;
+ }
+ }
+
+ if (($changed)&&(!$_[3])) {
+ printWarn(formatText(_T("AutoLaTeX has detecting an old fashion syntax for the configuration file {}\nPlease regenerate this file with the command line option --fixconfig."), $_[2]));
+ $_[3] = 1;
+ }
+
+ return ($k,$v);
+}
+
+# Reformat the value from a configuration file to apply several rules
+# which could not be directly applied by the configuration readed.
+# $_[0]: value name,
+# $_[1]: value to validated.
+sub rebuiltConfigValue($$) {
+ my $v = $_[1];
+ if (($_[0])&&($v)) {
+ my $v_str = trim($v);
+ # If the string "empty value" is detected, delete the value
+ if ($v_str eq EMPTY_INI_VALUE) {
+ $v = '';
+ }
+ # Split the include path of translators
+ elsif ($_[0] eq 'generation.translator include path') {
+ my $sep = getPathListSeparator();
+ if (isHash($v)) {
+ while (my ($key,$val) = each(%{$v})) {
+ my @tab = split(/\s*$sep\s*/,"$val");
+ if (@tab>1) {
+ $v->{"$key"} = @tab;
+ }
+ else {
+ $v->{"$key"} = pop @tab;
+ }
+ }
+ }
+ else {
+ my @paths = ();
+ if (isArray($v)) {
+ foreach my $p (@{$v}) {
+ push @paths, split(/\s*$sep\s*/,"$p");
+ }
+ }
+ else {
+ push @paths, split(/\s*$sep\s*/,"$v");
+ }
+ if (@paths>1) {
+ $v = \@paths;
+ }
+ else {
+ $v = pop @paths;
+ }
+ }
+ }
+ }
+ return $v;
+}
+
+=pod
+
+=item B<setInclusionFlags(\%\%;\%\%)>
+
+Set the translator inclusion flags obtained from the configurations.
+
+This function assumed that the translator list is an hashtable of
+(translator_name => { 'included' => { level => boolean } }) pairs.
+
+I<Parameters:>
+
+=over 8
+
+=item * the translator list.
+
+=item * the system configuration.
+
+=item * the user configuration.
+
+=item * the project configuration.
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub setInclusionFlags(\%\%;\%\%) {
+ die('first parameter of setInclusionFlags() is not a hash')
+ unless (isHash($_[0]));
+ die('second parameter of setInclusionFlags() is not a hash')
+ unless (isHash($_[1]));
+ foreach my $trans (keys %{$_[0]}) {
+ if (!$_[0]->{"$trans"}{'included'}) {
+ $_[0]->{"$trans"}{'included'} = {};
+ }
+
+ if ((exists $_[1]->{"$trans.include module"})&&(cfgIsBoolean($_[1]->{"$trans.include module"}))) {
+ $_[0]->{"$trans"}{'included'}{'system'} = cfgBoolean($_[1]->{"$trans.include module"});
+ }
+ else {
+ # On system level, a module which was not specified as not includable must
+ # be included even if it will cause conflicts
+ $_[0]->{"$trans"}{'included'}{'system'} = undef;
+ }
+
+ if (($_[2])&&
+ (exists $_[2]->{"$trans.include module"})&&
+ (cfgIsBoolean($_[2]->{"$trans.include module"}))) {
+ $_[0]->{"$trans"}{'included'}{'user'} = cfgBoolean($_[2]->{"$trans.include module"});
+ }
+ else {
+ $_[0]->{"$trans"}{'included'}{'user'} = undef;
+ }
+
+ if (($_[3])&&
+ (exists $_[3]->{"$trans.include module"})&&
+ (cfgIsBoolean($_[3]->{"$trans.include module"}))) {
+ $_[0]->{"$trans"}{'included'}{'project'} = cfgBoolean($_[3]->{"$trans.include module"});
+ }
+ else {
+ $_[0]->{"$trans"}{'included'}{'project'} = undef;
+ }
+ }
+}
+
+=pod
+
+=item B<reinitInclusionFlags(\%\%;\%\%)>
+
+Init the translator inclusion flags obtained from the configurations.
+
+This function assumed that the translator list is an hashtable of
+(translator_name => { 'included' => { level => undef } }) pairs.
+
+I<Parameters:>
+
+=over 8
+
+=item * the translator list.
+
+=item * the system configuration.
+
+=item * the user configuration.
+
+=item * the project configuration.
+
+=back
+
+I<Returns:> nothing
+
+=cut
+sub reinitInclusionFlags(\%\%;\%\%) {
+ die('first parameter of setInclusionFlags() is not a hash')
+ unless (isHash($_[0]));
+ die('second parameter of setInclusionFlags() is not a hash')
+ unless (isHash($_[1]));
+ foreach my $trans (keys %{$_[0]}) {
+ if (!$_[0]->{"$trans"}{'included'}) {
+ $_[0]->{"$trans"}{'included'} = {};
+ }
+
+ $_[0]->{"$trans"}{'included'}{'system'} = undef;
+
+ if ($_[2]) {
+ $_[0]->{"$trans"}{'included'}{'user'} = undef;
+ }
+
+ if ($_[3]) {
+ $_[0]->{"$trans"}{'included'}{'project'} = undef;
+ }
+ }
+}
+
+1;
+__END__
+=back
+
+=head1 BUG REPORT AND FEEDBACK
+
+To report bugs, provide feedback, suggest new features, etc. (in prefered order): a) visit the developer site on GitHub <https://github.com/gallandarakhneorg/autolatex/>, b) visit the AutoLaTeX main page <http://www.arakhne.org/autolatex/>, or c) send email to the main author at galland@arakhne.org.
+
+=head1 LICENSE
+
+S<GNU Public License (GPL)>
+
+=head1 COPYRIGHT
+
+S<Copyright (c) 1998-2016 Stéphane Galland E<lt>galland@arakhne.orgE<gt>>
+
+=head1 SEE ALSO
+
+L<autolatex-dev>