--- /dev/null
+#!/usr/bin/perl -w
+
+# tex2pdf - script for translating latex docs to pdf
+#
+# Copyright (C) 2000-2002 by Steffen Evers and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# 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; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# The GNU General Public License is also available online:
+# http://www.gnu.org/licenses/gpl.html
+#
+# Thanks a lot to all the people that have already contributed to this project!
+#
+# The changelog including the credits has become too long. So, I have removed it
+# from the script, but it is still available online (see below).
+#
+# Special thanks to the following people for their contribution
+# (see the changelog for details):
+# Matej Cepl, Herbert Voss, Nicolas Marsgui, Bruce Foster, Mark van Rossum,
+# Matt Bandy, Garrick Chien Welsh, Stacy J. Prowell, Pavel Sedivy,
+# Holger Daszler, Olaf Gabler, Ahmet Sekercioglui, Richard, Steffen Macke,
+# Rainer Dorsch & friends, Jean-Pierre Chretien, Fernando Perez,
+# Ha Duong Minh, Oscar Lopez
+#
+# Project Homepage: http://tex2pdf.berlios.de
+# Developer Homepage: http://developer.berlios.de/projects/tex2pdf
+# Mailing lists: http://developer.berlios.de/mail/?group_id=57
+# Changelog: http://tex2pdf.berlios.de/changelog.html
+#
+# Anyone is invited to help to improve tex2pdf. Therefore any kind of feedback
+# is welcome. Maybe you even would like to hack the code and send us your
+# changes. This would help a lot and is highly appreciated. Think about it :-)
+# Subscribing to the developer mailing list might be a first step (see above).
+#
+# Send feedback to: tex2pdf-devel@lists.berlios.de
+#
+
+######## Imports
+
+use File::Basename;
+use File::Copy;
+use Getopt::Long;
+use Sys::Hostname;
+use Cwd;
+use strict;
+
+####### global variables
+
+my $MYRELEASE="3.0.21";
+my $MYHOSTNAME=hostname;
+my $MYNAME=basename $0;
+my $MYUSER=$ENV{'USER'};
+my $USER_HOME=$ENV{'HOME'};
+if (not $MYUSER) { $MYUSER = 'nobody'; }
+if (not $USER_HOME) { $USER_HOME = '/tmp'; }
+
+my @TMPFILES=();
+my @TMP_TEX_FILES=();
+my $NUM_PARAM_MIN=0;
+my $NUM_PARAM_MAX=9;
+my @REF_DOCS;
+my $MTP_PREAMBLE_FILENAME="preamble.cfg";
+my $MTP_TMP_BASESUFFIX="-mp";
+my @EPS_SUFFIXES=('eps','ps','ps.gz','eps.gz' );
+my $PDF_ORIG_SUFFIX='pdf.orig';
+my @BITMAP_SUFFIXES=( 'jpg', 'png', 'tif' );
+
+# (initial) log file of this script
+# this log file will be moved to the specified log_dir after configuration
+# and the variable will be updated to the new name
+my $MYLOGFILE="$USER_HOME/tex2pdf-$$.log";
+my $LOGFILE_VERBOSITY=9;
+
+### text token for no value
+my $NIL="NOVALUE";
+my $UNDEF="undefined";
+
+### token for boolean 'false', 'no'
+my $NO="no";
+my $FALSE=0;
+
+### token for boolean 'true', 'yes'
+my $YES="yes";
+my $TRUE=1;
+
+### file to store private parameters
+# If you only want to change your private parameters change them there
+# default: $HOME/.tex2pdf3rc
+my $RC_FILENAME="$USER_HOME/.tex2pdf3rc";
+my $MYRCFILE_VERSION=7;
+my $RCVERSION_STRING="rcfile_version";
+
+## set global variable configured to prevent access to configuration
+# parameters before configuration process is finished
+my $CONFIGURED=$FALSE;
+my $PRE_CONFIG_VERBOSITY=4;
+
+########################## NEW PERL CONFIGURATON
+
+my %CONFIGURATION = ();
+my %PARAMETER_LIST = ();
+my @PARAMETER_ORDER = ();
+my %PARAMETER_TYPES = ();
+
+## Array index for the various information in each parameter specifcation
+## referenced by %PARAMETER_LIST
+my $TYPE=0;
+my $OPT_ALIAS=1;
+my $OPT_SPEC=2;
+my $DEF_VALUE=3;
+my $DESCRIPTION=4;
+my $QUESTION=5;
+my $EXPLANATION=6;
+
+&add_param_type('paper',
+ [ ['a4paper' , 'a4 paper' ],
+ [ 'letterpaper', 'letter paper' ],
+ [ 'legalpaper', 'legal paper' ],
+ [ 'executivepaper', 'executive paper' ],
+ [ $NIL, 'do not set value - leave it to hyperref' ]
+ ] );
+
+&add_param_type('color',
+ [ [ 'yellow', 'LaTeX color yellow' ],
+ [ 'red', 'LaTeX color red' ],
+ [ 'green', 'LaTeX color green' ],
+ [ 'cyan', 'LaTeX color cyan' ],
+ [ 'blue', 'LaTeX color blue' ],
+ [ 'magenta', 'LaTeX color magenta' ],
+ [ 'black', 'LaTeX color black' ],
+ [ $NIL , 'do not set this value - leave it to hyperref' ]
+ ] );
+
+&add_param_type('destination',
+ [ [ 'source', 'directory of the LaTeX source document' ] ,
+ [ 'input', 'root directory of referenced material' ],
+ [ 'custom', 'custom directory as specified' ]
+ ] );
+
+### Option parameters: these parameters have no default value and can not
+# be configured interactively, but only as a command line option
+# an option parameter is not allowed to have a default value, question or
+# explanation
+# and all parameter of type action are treated as option parameters
+# $key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation
+
+&add_param('help', 'action', undef, '|h', '',
+ 'print a short help text and exit');
+
+&add_param('version', 'action', undef, '|v', '',
+ 'print the version of this script and exit');
+
+&add_param('print_config', 'action', undef, '|o', '',
+ 'print the current configuration and exit');
+
+&add_param('configure', 'action', undef, '|c', '',
+ 'configure all parameters interactivly, store them and exit');
+
+&add_param('title', 'text', undef, '|t', '=s',
+ 'set PDF info title for specified document');
+
+&add_param('author', 'text', undef, '|a', '=s',
+ 'set PDF info author for specified document');
+
+&add_param('input_path', 'directory', undef, '', '=s',
+ 'set path for referenced material in main document');
+
+### Full parameters
+# parameter type action is not allowed
+# $key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation
+
+&add_param('logdir', 'directory',"$USER_HOME/tex2pdf-log/", '', '=s',
+ 'set directory for saving log files',
+ 'What log directory should be used?',
+ "The log directory is used to store information about the generation\n"
+ ."process for later review, e.g. for debugging.");
+
+&add_param('lyxrc_path', 'directory', "$USER_HOME/.lyx/", '', '=s',
+ 'set the configuration directory of LyX',
+ 'What is the directory for your LyX configuration data?',
+ "If I have to generate a LateX file from a LyX file I need to clear two "
+ ."temporary\nfiles in your LyX configuration directory. They will "
+ ."be backuped and normally\ndo not contain any valuable data anyway. If "
+ ."you do not use LyX, simply leave\nthe default.");
+
+&add_param('lyx_exec', 'text', "lyx", '', '=s',
+ 'specify the LyX executable for converting lyx to latex',
+ 'Which executable should I use for converting LyX docs to LaTeX?',
+ "I use LyX to generate a LateX file from a LyX file. As you might use\n"
+ ."several versions of LyX at the same time or do not have it in your path"
+ ."\nyou can give me the apropriate executable here (e.g. '/usr/bin/lyx')."
+ ."\nIn most cases the default 'lyx' should be fine.");
+
+&add_param('debug', 'bool', $NO, '', '!',
+'do not delete temporary files after execution and be as verbose as possible',
+ 'Do you want to debug this script?',
+ "I will not remove any temporary files. This could cause problems on a "
+ ."second\nexecution as I might refuse to overwrite these files for security "
+ ."reasons.\nYou have to remove them manually in this case. Additionally, I "
+ ."will provide\nas much information during execution as possible.");
+
+&add_param('delete_pdf_images', 'bool', $NO, '', '!',
+ 'delete generated PDF image files after execution',
+ 'Should generated PDF image files be deleted after execution?',
+ "Pdflatex cannot handle EPS images. Therefore all such images need to be\n"
+ ."translated to PDF in advance. After a successful generation of the final "
+ ."PDF \ndocument or after encountering an error I could leave this PDF "
+ ."images for\n later executions or simply delete them.");
+
+&add_param('clean_on_abort', 'bool', $YES, '', '!',
+ 'also delete temporary files after abort',
+ 'Should temporary files be deleted when aborting?',
+ "When the generation of the PDF file fails for some reason you might still "
+ ."want\nto keep already generated temporary files for some reason, e.g. "
+ ."debugging.\nIf you do not want to keep them set this parameter to 'yes'.");
+
+&add_param('tmp_base_suffix', 'text', '-pdf', '', '=s',
+ 'specify the extension of the basename for temporary TeX files',
+ 'What string should be used as basename suffix for temporary files?',
+ "I have to find names for my temporary files. Therefore I construct a new "
+ ."name\nfrom the original filename and this string. Me and various called "
+ ."applications\nwill then create several files with this constructed "
+ ."basename and different\nextensions. When cleaning up I will simple "
+ ."delete all files with the\nconstructed basenames I have used.");
+
+&add_param('overwrite', 'bool', $NO, '', '!',
+ 'ignore existence of files with same basename as temporary TeX files',
+ 'Should I overwrite existing (temporary) files?',
+ "In spite of the precaution with the appended base suffix, there still "
+ ."might\nexist files with an identical basename. If you set this option I "
+ ."will consider\nsuch files as old temporary files and overwrite them "
+ ."during generation.\nHowever, I will not remove any files with this "
+ ."constructed basename on the\nclean up. You have to remove them manually.");
+
+&add_param('clean_logs', 'bool', $YES, '|l', '!',
+ 'delete all log files in log directory before execution',
+ 'Should the old log files be removed before execution?',
+ "I can remove old log files prior to execution. However, you might "
+ ."experience\nproblems if you run the script on several documents at the "
+ ."same time. If you\nwant to be on the safe side, answer '$NO'. Than you "
+ ."have to remove the logs\nmanually from time to time.");
+
+&add_param('check_commands', 'bool', $YES, '', '!',
+ 'make sure that required shell commands does exist before start',
+ 'Should I look for required executables?',
+ "As I use several different applications for PDF generation you might want "
+ ."to \nmake sure that they are available before the real work starts.");
+
+&add_param('destination', 'destination', 'source', '', '=s',
+ 'specifiy final location of generated PDF document',
+ 'Where should I store the resulting PDF document?',
+ "Depending on the application that starts this script (or you if you call "
+ ."it\ndirectly) you might want to have the resulting PDF document located "
+ ."at\ndifferent places.");
+
+&add_param('custom_path', 'directory', $USER_HOME.'/', '|d', '=s',
+ "specify custom path for 'destination' parameter",
+ 'What custom directory should be used?',
+ "When ever you specifiy to store the generated PDF document (command line "
+ ."or\nconfiguration) in a custom directory I will put it here.");
+
+&add_param('colorlinks', 'three', $YES, '', '!',
+ 'activate colored links in PDF doc (hyperref)',
+ 'Should colors be used for links?',
+ "I can use different colors for links inside the PDF document.\nYou can "
+ ."use '$UNDEF' to tell me that you would like to leave this up to\n"
+ ."independent hyperref configuration.");
+
+&add_param('paper', 'paper', 'a4paper', '|p', '=s',
+ 'specify papersize of the PDF doc (hyperref)',
+ 'What papersize should be used?',
+ "I can set the papersize of the resulting PDF document");
+
+&add_param('citecolor', 'color', 'blue', '', '=s',
+ 'specify color of citations in PDF doc (hyperref)',
+ 'What color should be used for citation?', "");
+
+&add_param('urlcolor', 'color', 'blue', '', '=s',
+ 'specify color of URLs in PDF doc (hyperref)',
+ 'What color should be used for URLs?', "");
+
+&add_param('linkcolor', 'color', 'blue', '', '=s',
+ 'specify color of internal links in PDF doc (hyperref)',
+ 'What color should be used for normal internal links?', "");
+
+&add_param('pagecolor', 'color', 'blue', '', '=s',
+ 'specify color of links to other pages in PDF doc (hyperref)',
+ 'What color should be used for page links?', "");
+
+&add_param('link_toc_page', 'bool', $YES, '', '!',
+ 'link table of contents to pages instead of sections (hyperref)',
+ 'Should TOC be linked to pages?',
+ "The table of contents of the resulting PDF document is normally linked to "
+ ."the\ncorresponding section. However, you can also link it to the "
+ ."corresponding page\ninstead.");
+
+&add_param('default_title', 'text', $NIL, '', '=s',
+ 'set default PDF info title',
+ 'What is the default title?',
+ "A PDF document contains meta data about itself: the document info.\nOne "
+ ."of the info fields is the document title. You can set a default value\n"
+ ."which will be used in the case the script cannot determine a proper "
+ ."title from\nthe LaTeX document and you have not set one on the command "
+ ."line.\nYou can use '$NIL' to tell me that you would like to leave this "
+ ."up to\nindependent hyperref configuration.");
+
+&add_param('default_author', 'text', $NIL, '', '=s',
+ 'set default PDF info author',
+ 'What is the default author?',
+ "A PDF document contains meta data about itself: the document info.\nOne "
+ ."of the info fields is the document author. You can set a default value\n"
+ ."which will be used in the case the script cannot determine a proper "
+ ."author\nfrom the LaTeX document and you have not set one on the command "
+ ."line.\nYou can use '$NIL' to tell me that you would like to leave this "
+ ."up to\nindependent hyperref configuration.");
+
+&add_param('force_index', 'bool', $NO, '|i', '!',
+ 'force explicit inclusion of (existing) index in PDF doc',
+ 'Should the call of makeindex be forced?',
+ "Older versions of pdflatex have not included the index of a document\n"
+ ."automatically. If you are missing the index in your document you can "
+ ."force the\ncall of makeindex on the condition that an index file was "
+ ."generated.");
+
+&add_param('makeindex_opts', 'text', '', '', '=s',
+ 'specify extra options for shell execution of makeindex',
+ 'What additional options for makeindex should be used?',
+ "Sometimes, people would like to pass some extra options over to makeindex. "
+ ."This\nis the right place to do that. Everyone else can leave this empty.");
+
+&add_param('bibtex', 'three', $NIL, '|b', '!',
+ 'set bibtex behavior',
+ 'How should bibtex be used?',
+ "The bibtex usage can be specified.\nPossible values are: '$YES' (always "
+ ."run bibtex), '$NO' (never run bibtex)\nand '$UNDEF' (scan tex file for "
+ ."a bibtex entry and run it if required).");
+
+&add_param('gloss', 'three', $NIL, '', '!',
+ 'set gloss behavior',
+ 'How should gloss be used?',
+ "The gloss usage can be specified.\nPossible values are: '$YES' (always "
+ ."run bibtex on file.gls), '$NO' (never run bibtex on file.gls)\nand '$UNDEF' (scan tex file for "
+ ."a gloss entry and run it if required).");
+
+&add_param('thumbpdf', 'bool', $NO, '|n', '!',
+ 'generate thumbnails for PDF document',
+ 'Should PNG thumbnails be created?',
+ "I can use thumbpdf to include thumbnails of the document pages in the PDF "
+ ."file.\nThis requires Ghostscript 5.50 or higher.");
+
+&add_param('ppower', 'bool', $NO, '|w', '!',
+ 'postprocess PDF document with ppower',
+ 'Should ppower postprocess the PDF document?',
+ "I can use ppower to postprocess the PDF "
+ ."file.\nThis requires ppower 4.0 or higher.");
+
+&add_param('authorindex', 'bool', $NO, '', '!',
+ 'generate author index for PDF document',
+ 'Should authorindex process the PDF document?',
+ "I can use authorindex to process to include an author index in the PDF "
+ ."file.\nThis requires authorindex.");
+
+
+&add_param('mtp_preamble', 'bool', $NO, '|r', '!',
+ "add the file $MTP_PREAMBLE_FILENAME at the current dir to metapost files",
+ "Should the $MTP_PREAMBLE_FILENAME file be added to the metapost files?",
+ "I can add $MTP_PREAMBLE_FILENAME to metapost "
+ ."files.\nThis requires an existing $MTP_PREAMBLE_FILENAME file.");
+
+&add_param('maxrun', 'integer', 6, '', '=i',
+ 'specify maximal number of pdflatex runs if problems are detected',
+ 'What should be the maximum number of runs for pdflatex (1-6)?', "");
+
+&add_param('minrun', 'integer', 2, '', '=i',
+ 'specify minimal number of pdflatex runs if no problems are detected',
+ 'What should be the minimum number of runs for pdflatex (1-6)?', "");
+
+&add_param('verbosity', 'integer', 5, '', '=i',
+ 'set the level of verbosity',
+ 'Which level of verbosity do you want (0-9)',
+ "Different people want different amounts of information about what the "
+ ."script\nactually does. Therefore you can adjust the verbosity to your "
+ ."personal needs\nby setting this parameter to a value from 0 to 9. 0 "
+ ."means no output at all\nand 9 means maximal output.");
+
+&add_param('pdftex_opts', 'text', '', '', '=s',
+ 'specify extra options for shell execution of pdflatex',
+ 'What additional options for pdflatex should be used?',
+ "Sometimes, people would like to pass some extra options over to pdflatex. "
+ ."This\nis the right place to do that. Everyone else can leave this empty.");
+
+&add_param('hyperref_args', 'text', '', '', '=s',
+ 'specify extra arguments for the hyperref package',
+ 'What additional arguments should be passed to the hyperref package?',
+ "Sometimes, people would like to pass some extra options over to hyperref. "
+ ."This\nis the right place to do that. Everyone else can leave this empty.");
+
+# the following parameter types should be set now:
+# 'color' => \@VALUES,
+# 'destination' => \@VALUES,
+# 'paper' => \@VALUES,
+# 'action' => undef,
+# 'three' => undef,
+# 'bool' => undef,
+# 'integer' => undef,
+# 'text' => undef,
+# 'directory' => undef
+
+##### Functions ###########################################
+
+### handle a status report with a given priority level
+# write it to the log file if log file if configuration is done
+# write it to stdout if verbosity is set lower or equal
+#
+# The following priority levels exist:
+# 1: minimal fatal error messages
+# 2: additional information about fatal error
+# 3: non-fatal error message
+# 4: warning
+# 5: major step of the process
+# 6: minor step of the process
+# 7: progress report of minor step
+# 8: long status report from called applications
+# 9: debug info
+#
+# parameter 1: priority level
+# parameter 2: list of output strings
+# return value: none
+
+sub report {
+ my $level;
+ my $verbosity;
+ my $log_verbosity;
+ my @output;
+
+ if (@_ < 2 ) {
+ @output = ( "Oppss! Report function got only 1 argument!" );
+ $level = 9;
+ } else {
+ ($level, @output) = @_;
+ }
+
+ if($CONFIGURED) {
+ if( ¶m_value('debug') eq $NO ) {
+ $verbosity = ¶m_value('verbosity');
+ $log_verbosity = $LOGFILE_VERBOSITY;
+ } else {
+ $verbosity = 9;
+ $log_verbosity = 9;
+ }
+ } else {
+ $verbosity = $PRE_CONFIG_VERBOSITY;
+ $log_verbosity = $LOGFILE_VERBOSITY;
+ }
+
+ if ( $level <= $log_verbosity ) {
+ open LOGFILE, ">> $MYLOGFILE";
+ print LOGFILE @output,"\n";
+ close LOGFILE;
+ }
+
+ if( $level <= $verbosity ) {
+ print @output,"\n";
+ }
+}
+
+### process system command and do the appropriate reports
+# parameter 1: the system command to process
+# parameter 2: flag - TRUE: abort on failure, FALSE: continue on failures
+# parameter 3: priority level for output of system command
+# parameter 4: specific failure message
+# return value: TRUE - success, FALSE - failure
+
+sub system_command {
+ my $command = $_[0];
+ my $fatal_failure= $_[1];
+ my $output_priority = $_[2];
+ my $fail_message = $_[3];
+ my $system_out;
+
+ $system_out = `$command 2>&1`;
+
+ if ($?) {
+ if ($fatal_failure) {
+ &report(2, $system_out) if ($system_out);
+ &abort($fail_message.": $!");
+ } else {
+ &report($output_priority, $system_out) if ($system_out);
+ &report(3, $fail_message.": $!");
+ }
+ return $FALSE;
+ }
+
+ return $TRUE;
+}
+
+### Index of the first occurence of a string in an array
+# parameter 1: text
+# parameter 2: list
+# return value: index or -1 if not element of the array
+
+sub array_index {
+ my ($text, @list) = @_;
+
+ if(!defined($text)) {
+ &report(9, "Oppss! Cannot compare nothing.");
+ return -1;
+ }
+
+ foreach (0..$#list) {
+ if ( $list[$_] eq $text ) { return $_; }
+ }
+
+ return -1;
+}
+
+### extract the last N lines of a text file
+# abort on failures
+# parameter 1: file to read
+# parameter 2: N - number of lines to print (undef/0: all lines)
+# return value: last N lines
+
+sub file_tail {
+ my $file_name = $_[0];
+ my $no_of_lines = defined($_[1]) ? $_[1] : 0;
+ my @cache=();
+
+ &check_file($file_name);
+ open(TAIL_SOURCE, "<$file_name")
+ or &abort("Could not read file $file_name: $!");
+
+ if($no_of_lines == 0) {
+ # use entire file
+ while(<TAIL_SOURCE>) {
+ if(!$_) { $_="\n"; }
+ push(@cache, $_);
+ }
+ } else {
+ # only last N lines
+
+ # fill up cache
+ while(@cache < $no_of_lines and <TAIL_SOURCE>) {
+ if(!$_) { $_="\n"; }
+ push(@cache, $_);
+ }
+
+ # always cache the last N lines up to the end of the file
+ while(<TAIL_SOURCE>) {
+ if(!$_) { $_="\n"; }
+ shift(@cache);
+ push(@cache, $_);
+ }
+ }
+
+ close TAIL_SOURCE;
+
+ return @cache;
+}
+
+### return all lines of FILE which match match regexp EXPR
+# parameter 1: FILE - file to read
+# parameter 2: EXPR - regular expression to match
+# parameter 3: true: exit on first occurence, otherwise get all (default: false)
+# return value: array of matching lines
+
+sub grep_file {
+ my $file_name = $_[0];
+ my $regexp = $_[1];
+ my $first_only = $_[2] ? $TRUE : $FALSE;
+ my @result=();
+
+ ### open file and abort if not possible
+ &check_file($file_name);
+ open(GREP_SOURCE, "<$file_name")
+ or &abort("Could not read file $file_name: $!");
+
+ while(<GREP_SOURCE>) {
+ if(m#$regexp#) {
+ push(@result, $_);
+ if($first_only) { last; }
+ }
+ }
+
+ close GREP_SOURCE;
+ return @result;
+}
+
+### Removing all temporary files
+
+sub clean_up {
+ &report(6, "Removing temporary files ...");
+ foreach (@TMPFILES) {
+ unlink($_) if(-f $_);
+ }
+
+ foreach (@TMP_TEX_FILES) {
+ # make sure that we have a good tex file name in order
+ # to avoid unintended removals
+ if( $_ ne "" and -f $_.'.tex' ) {
+ unlink glob($_.".???");
+ } else {
+ &report(3, "Bad file in temp tex files list: $_");
+ }
+ }
+}
+
+### Output of all temp files
+
+sub print_temp_files {
+ if (scalar @TMPFILES > 0) {
+ print "Stored the following explicit temporary files:\n";
+ foreach (@TMPFILES) {
+ if (-f $_) {
+ print "> ".$_."\n";
+ } else {
+ print "> ".$_." (does not exist)\n";
+ }
+ }
+ print "\n";
+ }
+
+ if (scalar @TMP_TEX_FILES > 0) {
+ print "Stored the following temporary TeX base names:\n";
+ foreach (@TMP_TEX_FILES) {
+ if( $_ ne "" and -f $_.'.tex' ) {
+ print "> ".$_.": ";
+ foreach my $file (glob($_.".???")) {
+ print basename($file)." ";
+ }
+ print "\n";
+ } else {
+ print "> ".$_.": bad file for temp TeX file\n";
+ }
+ }
+ print "\n";
+ }
+}
+
+### exit with an error message
+
+sub abort {
+ &report(1, @_);
+ if ( $CONFIGURED and ¶m_value('clean_on_abort') eq $YES
+ and ¶m_value('debug') eq $NO) {
+ &clean_up;
+ } else {
+ &print_temp_files;
+ }
+ &report(2, "Aborting ...");
+ exit 1;
+}
+
+### Check for required command with 'which'; abort if not found
+# parameter $1: command to check
+# parameter $2: remark if specified command is not found
+
+sub checkCommand {
+ my $command = $_[0];
+ my $message = $_[1];
+ my $which_output;
+
+ $which_output = `which $command 2>&1`;
+ chomp $which_output;
+ $_ = $which_output;
+ s|^(.*/)?([^/]+)$|$2|;
+
+ if ( $_ ne $command ) {
+ &report(2, "\n$which_output");
+ &report(1, "\nRequired command '$command' seems not to be in your path.");
+ if ( defined($message) ) {
+ &report(2, "$message");
+ }
+ &report(2, "Aborting ...");
+ exit 1;
+ }
+}
+
+###################### Generic configuration functions
+
+### interactively answer a question with yes or no
+# parameter 1: question
+# parameter 2: default value (not set means $NIL)
+# parameter 3: yes: allow undefined as third value
+# no : only yes/no allowed (default)
+# return value: the given answer
+
+sub question_ynu {
+ my $user_input;
+ my $question = $_[0];
+ my $default = defined($_[1]) ? $_[1] : $NIL;
+ my $undef_allowed = $_[2];
+ my $response = undef;
+
+ if (defined($undef_allowed) and $undef_allowed eq $YES) {
+ $undef_allowed = $TRUE;
+ } else {
+ $undef_allowed = $FALSE;
+ }
+
+ if( $default =~ /^y(es)?/i ) {
+ $question .= ' [y]: ';
+ $default = $YES;
+ } elsif ( $default eq $NIL and $undef_allowed ) {
+ $question .= ' [u]: ';
+ $default = $NIL;
+ } else {
+ $question .= ' [n]: ';
+ $default = $NO;
+ }
+ while (! defined($response)) {
+ print $question;
+ $user_input = <STDIN>;
+ chomp($user_input);
+
+ if( $user_input =~ /^y(es)?/i ) {
+ $response=$YES;
+ } elsif ( $user_input =~ /^no?/i ) {
+ $response=$NO;
+ } elsif ( $user_input =~ /^u(ndef(ined)?)?/i and $undef_allowed ) {
+ $response=$NIL;
+ } elsif ( $user_input eq "" ) {
+ $response=$default;
+ } else {
+ print "Please respond with y(es)";
+ print ", u(ndefined)" if($undef_allowed);
+ print " or n(o).\n";
+ }
+ }
+ return $response;
+}
+
+### interactively input a positive integer number
+# parameter 1: question
+# parameter 2: default value
+# parameter 3: min value
+# parameter 4: max value
+# return value: the input number
+
+sub input_number {
+ my $question = $_[0];
+ my $default = $_[1];
+ my $min_limit = $_[2];
+ my $max_limit = $_[3];
+ my $response= undef;
+
+ while (! defined($response)) {
+ print "$question [$default]: ";
+ my $user_input = <STDIN>;
+ chomp($user_input);
+
+ if ($user_input eq "") {
+ $response=$default;
+ } else {
+ $_ = $user_input;
+ if (s/^([0-9]+)$/$1/ and $_ >= $min_limit and $_ <= $max_limit ) {
+ $response = $_;
+ } else {
+ print "Invalid input. Please enter a positve integer from $min_limit to $max_limit.\n";
+ }
+ }
+ }
+ return $response;
+}
+
+### interactively choose between several given values
+# parameter 1: question
+# parameter 2: default value
+# parameter 3: reference to an array of possible values arrays
+# return value: the chosen value
+
+sub choose_value {
+ my ($question, $default, $enum_array_ref)=@_;
+ my $default_no=1;
+ my $chosen_no;
+ my @possible_values = @$enum_array_ref;
+ my @value_array;
+ my $value_key;
+ my $value_output;
+
+ print "$question\n";
+ foreach (0..$#possible_values) {
+ my $no = $_ + 1;
+ @value_array = @{$possible_values[$_]};
+ $value_key = $value_array[0];
+ $value_output = $value_array[1];
+
+ print "$no) " . $value_output . "\n";
+ if ( $default eq $value_key ) { $default_no=$no; }
+ }
+
+ $chosen_no=&input_number("Please enter the corresponding number", $default_no, 1, $#possible_values);
+
+ @value_array = @{$possible_values[$chosen_no - 1]};
+ $value_key = $value_array[0];
+ return $value_key;
+}
+
+### interactively answer a question
+# parameter 1: question
+# parameter 2: current value
+# return value: the new value
+
+sub input_text {
+ my $question=$_[0];
+ my $default=$_[1];
+ my $response= undef;
+
+ print "Suggested value: $default\n";
+ if ( &question_ynu("Do you want to keep this value?", $YES) eq $YES ) {
+ $response= $default;
+ } else {
+ print "$question ";
+ my $user_input = <STDIN>;
+ chomp($user_input);
+
+ $response = $user_input;
+ }
+ return $response;
+}
+
+##### Make sure that specified file exists and is readable; abort if missing
+# parameter 1: file to check
+# parameter 2: remark if check fails on specified file
+
+sub check_file {
+ my $file = $_[0];
+ my $message = defined($_[1]) ? $_[1] : "Required file cannot be accessed!";
+
+ if ( ! -f $file ) {
+ &report(2, "\nSorry. I cannot find '$file'.");
+ &abort($message);
+ } elsif ( ! -r $file ) {
+ &report(2, "\nSorry. File '$file' exists, but is not readable.");
+ &abort($message);
+ }
+}
+
+##### Make sure that specified directory exists and is writable
+# parameter 1: directory to check
+# parameter 2: remark if check fails on specified directory
+# parameter 3: if yes, creation is allowed
+# return value: $TRUE - ok; $FALSE - error
+
+sub check_dir {
+ my $directory = $_[0];
+ my $message = defined($_[1]) ? $_[1] : "Not a valid path!";
+ my $allow_creation = defined($_[2]) ? $_[2] : $NO;
+
+ if ( index($directory, "/") != 0 ) {
+ &report(3, "\nSorry. '$directory' is not an absolute path.");
+ &report(3, $message);
+ return $FALSE;
+ } elsif ( ! -d $directory ) {
+ # dir does not exist
+ if ( $allow_creation eq $YES ) {
+ # creation allowed
+ &report(4, "\nI cannot find '$directory'. Try to create it.");
+ if ( mkdir($directory, 0755) ) {
+ &report(7, "Creation of '$directory' was successful.");
+ return $TRUE;
+ } else {
+ &report(3, "Creation of '$directory' failed.");
+ &report(3, $message);
+ return $FALSE;
+ }
+ } else {
+ # creation not allowed
+ &report(3, "\nSorry. Directory '$directory' does not exist.");
+ &report(3, $message);
+ return $FALSE;
+ }
+ } elsif ( ! -w $directory ) {
+ # dir not writable
+ &report(3, "\nSorry. Directory '$directory' exists, but is not writable.");
+ &report(3, $message);
+ return $FALSE;
+ }
+ return $TRUE;
+}
+
+### interactively input a directory for data storage (absolute path)
+# parameter 1: question
+# parameter 2: default dir
+# parameter 3: if 'yes' allow creation of directory
+# return value: the specified directory
+
+sub input_dir {
+ my $question = $_[0];
+ my $default_dir = $_[1];
+ my $allow_creation = defined($_[2]) ? $_[2] : $NO;
+ my $user_input;
+ my $response = undef;
+
+ if ( defined($default_dir) and index($default_dir, "/") == 0
+ and ( (! -d $default_dir and $allow_creation eq $YES)
+ or (-d $default_dir and -w $default_dir) ) ) {
+ $question .= " [$default_dir]: ";
+ } else {
+ $default_dir = undef;
+ $question .= ": ";
+ }
+
+ while (! defined($response)) {
+ print "$question";
+ $user_input = <STDIN>;
+ chomp($user_input);
+
+ if( $user_input eq "" and defined($default_dir) ) {
+ # user has only pressed <ENTER> and thereby confirmed default value
+ if( ! &check_dir($default_dir,"Default value was not valid. Please, give different directory.", $allow_creation ) ) {
+ # default dir does not exist and cannot be created
+ $default_dir = undef;
+ $question = "$_[0]: ";
+ } else {
+ # valid default dir has already existed or has been created
+ $response = $default_dir;
+ }
+ } else {
+ # user has given a directory
+ if( &check_dir($user_input,"This is not a valid directory!", $allow_creation) ) {
+ $response = $user_input;
+ }
+ }
+ }
+ return $response;
+}
+
+#### add a new parameter type with corresponding additional data argument
+#### parameters types
+# parameter 1: type key
+# parameter 2: additonal data for the type
+# e.g. for enum type: reference to list of arrays
+# return value: none
+
+sub add_param_type {
+
+ my ($type, $scalar_argument) = @_;
+
+ $PARAMETER_TYPES{$type} = $scalar_argument;
+}
+
+#### add a new parameter to the adminstrated parameters
+####
+# parameter 1: key
+# parameter 2: type
+# parameter 3: default value
+# parameter 4: alias for command line options
+# parameter 5: specification for command line options
+# parameter 6: short description for help
+# parameter 7: question
+# parameter 8: explanation
+# return value: none
+
+sub add_param {
+
+ my ($key, $type, $def_value, $opt_alias, $opt_spec, $description, $question, $explanation) = @_;
+
+ $CONFIGURATION{$key} = $def_value;
+
+ $PARAMETER_LIST{$key} = [ $type, $opt_alias, $opt_spec, $def_value, $description, $question, $explanation ];
+
+ push(@PARAMETER_ORDER, $key);
+
+ if (! exists $PARAMETER_TYPES{$type}) {
+ $PARAMETER_TYPES{$type} = undef;
+ }
+}
+
+### get the value of an existing parameter
+# parameter 1: a parameter key
+# return value: reference to the array of possible value entries
+# (undef if not valid)
+
+sub type_enum_array {
+ my $key = $_[0];
+ my $values_ref;
+
+ if(! exists($PARAMETER_TYPES{$key})) {
+ &abort("unknown type: $key");
+ }
+
+ $values_ref = $PARAMETER_TYPES{$key};
+
+ if(ref $values_ref ne 'ARRAY') {
+ $values_ref = undef;
+ }
+
+ return $values_ref;
+}
+
+### get the value of an existing parameter
+# parameter 1: a parameter key
+# return value: parameter value
+
+sub param_value {
+ my $key = $_[0];
+ my $current_value;
+
+ exists($CONFIGURATION{$key})
+ or &abort("unknown parameter: $key");
+ $current_value = $CONFIGURATION{$key};
+
+ return $current_value;
+}
+
+### get the type of an existing parameter
+# parameter 1: a parameter key
+# return value: parameter value
+
+sub param_type {
+ my $key = $_[0];
+ my $def_ref;
+ my $type;
+
+ exists($PARAMETER_LIST{$key})
+ or &abort("unknown parameter: $key");
+ $def_ref = $PARAMETER_LIST{$key};
+ $type = @{$def_ref}[$TYPE];
+
+ exists($PARAMETER_TYPES{$type})
+ or &abort("parameter has unknown type: $key (type: $type)");
+
+ return $type;
+}
+
+### determine if the given parameter is a full one (instead of option only)
+# parameter 1: a parameter key
+# return value: $TRUE - full parameter; $FALSE otherwise
+
+sub full_param {
+ my $key = $_[0];
+ my @param_def;
+
+ exists($PARAMETER_LIST{$key})
+ or &abort("unknown parameter: $key");
+ @param_def = @{$PARAMETER_LIST{$key}};
+
+ if ($param_def[$TYPE] ne 'action' and defined ($param_def[$QUESTION])) {
+ return $TRUE;
+ } else {
+ return $FALSE;
+ }
+}
+
+### get the output needed for configuration of this parameter
+# parameter 1: a parameter key
+# return value: array - (description, explanation, question)
+
+sub param_config_output {
+ my $key = $_[0];
+ my @param_def;
+ my $description;
+ my $explanation;
+ my $question;
+
+ exists($PARAMETER_LIST{$key})
+ or &abort("unknown parameter: $key");
+ @param_def = @{$PARAMETER_LIST{$key}};
+ $description = $param_def[$DESCRIPTION];
+ $explanation = $param_def[$EXPLANATION];
+ $question = $param_def[$QUESTION];
+
+ return ($description, $explanation, $question);
+}
+
+### set the value of an existing parameter
+# parameter 1: a parameter key
+# parameter 2: the new value
+# return value: none
+
+sub set_param_value {
+ my $key = $_[0];
+ my $new_value = $_[1];
+
+ exists($CONFIGURATION{$key})
+ or &abort("unknown parameter: $key");
+ $CONFIGURATION{$key}=$new_value;
+}
+
+### get option specifier for getopts
+# parameter 1: option key
+# return value: string - option specifier
+
+sub option_specifier {
+ my $key = $_[0];
+ my $spec;
+ my $def_ref;
+
+ exists($PARAMETER_LIST{$key})
+ or &abort("unknown parameter: $key");
+ $def_ref = $PARAMETER_LIST{$key};
+ $spec = $key . ${$def_ref}[$OPT_ALIAS] . ${$def_ref}[$OPT_SPEC];
+
+ return $spec;
+}
+
+### handle an option
+# parameter 1: a parameter/option key
+# parameter 2: the option value
+# return value: none
+
+sub handle_option {
+ my $key = $_[0];
+ my $value = $_[1];
+ my $type;
+
+ $type = ¶m_type($key);
+
+ if ($type eq 'action') {
+ &handle_action_opt($key, $value);
+ } elsif ( $type eq 'bool' or $type eq 'three') {
+ my $bool_value = $value ? $YES : $NO;
+ &set_param_value($key, $bool_value);
+ } elsif ( $type eq 'directory') {
+ if (! &check_dir($value)) {
+ &report(2, "$key requires an existing writable directory as an absolute path.");
+ &abort("Illegal value: $value");
+ }
+ &set_param_value($key, $value);
+ } elsif (defined(&type_enum_array($type))){
+ &set_enum_param($key, $value);
+ } else {
+ &set_param_value($key, $value);
+ }
+}
+
+### handle all action options
+# parameter 1: a option key
+# parameter 2: the option value
+# return value: none
+
+sub handle_action_opt {
+ my $key = $_[0];
+ my $value = $_[1];
+
+ if ($key eq 'help') {
+ &print_help;
+
+ } elsif ($key eq 'version') {
+ &print_version;
+
+ } elsif ($key eq 'configure') {
+ if ( -f $RC_FILENAME ) {
+ &read_configuration($RC_FILENAME);
+ }
+ &configure;
+ &write_configuration($RC_FILENAME);
+ &print_configuration;
+
+ } elsif ($key eq 'print_config') {
+ if ( -f $RC_FILENAME ) {
+ &read_configuration($RC_FILENAME);
+ }
+ &print_configuration;
+
+ } else {
+ &print_usage;
+ exit 1;
+ }
+ exit 0;
+}
+
+### set a variable by a command line option to a possible values; abort on error
+# parameter 1: parameter key
+# parameter 2: value
+
+sub set_enum_value {
+ my ($key, $value) = @_;
+ my $type;
+ my $enum_array_ref;
+ my @allowed_values=();
+
+ $type = ¶m_type($key);
+ $enum_array_ref = &type_enum_array($type);
+ &abort("Internal error: No value array for parameter $key.")
+ if(!defined($enum_array_ref));
+
+ ### find out if the given value is allowed
+ foreach my $value_array_ref (${$enum_array_ref}) {
+ if(${$value_array_ref}[0] eq $value) {
+ ### found it, so it is okay!
+ &set_param_value($key, $value);
+ return;
+ }
+ }
+
+ ### value is not listed, so not allowed
+ ### make a list of all allowed values
+ foreach my $value_array_ref (${$enum_array_ref}) {
+ push(@allowed_values, ${$value_array_ref}[0]);
+ }
+
+ &report(2, "\n$key allows: " . @allowed_values . ".\n");
+ &abort("Illegal value: $value");
+}
+
+### configure an existing parameter interactively
+# parameter 1: a parameter key
+# return value: none
+
+sub config_param {
+ my $key = $_[0];
+ my $type;
+ my $new_value;
+ my $current_value;
+ my $description;
+ my $explanation;
+ my $question;
+
+ ### get required information about this parameter
+ $type = ¶m_type($key);
+ $current_value = ¶m_value($key);
+ ($description, $explanation, $question) = ¶m_config_output($key);
+
+ ### tell the user the facts
+ print "\n\n--------------------------------------------\n";
+ print "Parameter: ".$key."\n";
+ print $description."\n\n";
+ print $explanation."\n\n" if($explanation ne "");
+
+ ### ask him what he wants
+ if ($type eq 'bool') {
+ $new_value=&question_ynu($question, $current_value, $NO);
+ } elsif ($type eq 'three') {
+ $new_value=&question_ynu($question, $current_value, $YES);
+ } elsif ($type eq 'directory') {
+ $new_value=&input_dir($question, $current_value, $YES);
+ } elsif ($type eq 'text') {
+ $new_value=&input_text($question, $current_value);
+ } elsif ($type eq 'integer') {
+ $new_value=&input_number($question, $current_value,
+ $NUM_PARAM_MIN, $NUM_PARAM_MAX);
+ } else {
+ my $enum_array_ref;
+
+ $enum_array_ref=&type_enum_array($type);
+ if (! defined($enum_array_ref)) {
+ &abort("Do not know how to configure this parameter: $key (type: $type)");
+ }
+
+ $new_value=&choose_value($question,$current_value,$enum_array_ref);
+ }
+
+ ### store his choice
+ &set_param_value($key, $new_value);
+}
+
+### save configuration in rc file
+# parameter 1: file name
+# return value: none
+
+sub write_configuration {
+ my $file_name = $_[0];
+ my $date;
+
+ open(RCFILE, ">$file_name") or
+ &abort("Could not open configuration file for writing ($file_name)");
+ select RCFILE;
+
+ $date = `date`;
+ chomp($date);
+
+ print "# Configuration file for $MYNAME V$MYRELEASE\n";
+ print "# Generated $date by $MYUSER on $MYHOSTNAME\n";
+ print "$RCVERSION_STRING=$MYRCFILE_VERSION\n";
+
+ foreach my $key (@PARAMETER_ORDER) {
+ my $value = $CONFIGURATION{$key};
+ if(&full_param($key)) {
+ print $key.'='.$value."\n";
+ }
+ }
+
+ print "# EOF\n";
+ select STDOUT;
+ close RCFILE;
+}
+
+### print the configuration parameters
+
+sub print_configuration {
+ print "\nConfiguration for $MYNAME V$MYRELEASE\n";
+
+ foreach my $key (@PARAMETER_ORDER) {
+ my $value = $CONFIGURATION{$key};
+ if(&full_param($key)) {
+ print $key.'='.$value."\n";
+ }
+ }
+
+ print "\n";
+}
+
+### load parameters from rc file
+# parameter 1: file name
+# return value: version of read rc file or 0 if no version given
+
+sub read_configuration {
+ my $file_name = $_[0];
+ my $file_version= 0;
+
+ &check_file($file_name, "Could not access configuration file");
+ open(RCFILE, "<$file_name") or
+ &abort("Could not open configuration file for reading ($file_name)");
+
+ while (<RCFILE>) {
+ chomp;
+ if( /^([^#=]+)=(.*)$/ ) {
+ if( exists $CONFIGURATION{$1} ) {
+ $CONFIGURATION{$1} = $2;
+ } elsif ( $1 eq $RCVERSION_STRING ) {
+ $file_version = $2;
+ } else {
+ print "Ignoring unknown parameter in RC file: $1=$2\n";
+ }
+ }
+ }
+ close RCFILE;
+
+ return $file_version;
+}
+
+### print script version
+
+sub print_version {
+ print "\n$MYNAME Version $MYRELEASE\n";
+}
+
+###################### Specific functions (for use with this script only)
+
+### print usage of command
+
+sub print_usage {
+ print "\nUsage: $MYNAME [OPTIONS] DOCUMENT.lyx\n";
+ print " $MYNAME [OPTIONS] DOCUMENT[.tex]\n\n";
+ print " $MYNAME -c | --configure modify/set up configuration\n";
+ print " $MYNAME -h | --help give a short help\n";
+ print " $MYNAME -o | --print_config print current configuration\n";
+ print " $MYNAME -v | --version print my version\n\n";
+}
+
+### print command help
+
+sub print_help {
+ &print_version;
+ &print_usage;
+
+ foreach my $key (@PARAMETER_ORDER) {
+ my @param_def = @{$PARAMETER_LIST{$key}};
+ my $description = $param_def[$DESCRIPTION];
+ my $takes_value = $param_def[$OPT_SPEC] =~ /[=:]/ ? $TRUE : $FALSE;
+ my $negation = $param_def[$OPT_SPEC] eq '!' ? $TRUE : $FALSE;
+ my $alias = $param_def[$OPT_ALIAS];
+
+ $alias =~ s/\|(([a-zA-Z])(\||$))/ | -$1/g;
+ $alias =~ s/\|(([a-zA-Z][a-zA-Z0-9_]+)(\||$))/ | --$1/g;
+
+ print "--";
+ print "[no]" if($negation);
+ print $key.$alias;
+ print " VALUE" if ($takes_value);
+ print ":\n ".$description."\n\n";
+ }
+ print "\n";
+}
+
+### configure all tex2pdf parameters interactively
+# parameters: none
+# return value: none
+
+sub configure {
+
+ print "\n--------------------------------------------------------\n";
+ print "\n***** Configuration for $MYNAME *****\n\n";
+ print "The following answers are considered as defaults in later ";
+ print "executions\n";
+ print "of $MYNAME. You can change these values by using the option ";
+ print "--configure \nagain.";
+ print "Additionally, all command-line options override these settings.\n";
+ print "Many parameters can be set to '$NIL' or '$UNDEF'. This means that NO";
+ print "\nvalue at all (not even an empty value) is passed over to the ";
+ print "called\napplication (e.g. latex package hyperref).\n";
+
+ $NUM_PARAM_MIN=1;
+ $NUM_PARAM_MAX=9;
+
+ foreach my $key (@PARAMETER_ORDER) {
+ if(&full_param($key)) {
+ &config_param($key);
+ }
+ }
+
+ print "\nConfiguration for $MYNAME finished.\n\n";
+}
+
+### check if the most important executables are installed on the system
+# parameters: none
+
+sub check_commands {
+ my $exec_epstopdf;
+ ### check for which command
+ &checkCommand("which","You can switch off all command checks to fix this.");
+
+ ### pdftex executables
+ # Homepage: http://tug.org/applications/pdftex
+ &checkCommand("pdflatex","See pdftex homepage for details: http://tug.org/applications/pdftex");
+ &checkCommand("epstopdf","See pdftex homepage for details: http://tug.org/applications/pdftex");
+ $exec_epstopdf = `which epstopdf`;
+ chomp $exec_epstopdf;
+ if (&grep_file($exec_epstopdf, "-dCompatibilityLevel=1\\.1", $TRUE) > 0) {
+ &report(9, "Good: ghostscript option '-dCompatibilityLevel=1.1' detected "
+ ."in\n'$exec_epstopdf'.");
+ } else {
+ &report(4, "\nWARNING: no ghostscript option '-dCompatibilityLevel=1.1' "
+ ."in\n'$exec_epstopdf'.\n"
+ ."You might run into trouble with the conversions of bitmaps.\n"
+ ."Adjusting epstopdf or setting the environment variable GS_OPTIONS "
+ ."to \n".'"$GS_OPTIONS -dCompatibilityLevel=1.1" before calling this '
+ ."script\nmight help in this case.\n");
+ }
+
+ if ( ¶m_value('thumbpdf') eq $YES ) {
+ &checkCommand("thumbpdf","You can switch off thumbpdf support to fix this.");
+ }
+
+ if ( ¶m_value('ppower') eq $YES ) {
+ &checkCommand("ppower","You can switch off ppower support to fix this.");
+ }
+
+ ### authorindex perl script
+ if ( ¶m_value('authorindex') eq $YES ) {
+ &checkCommand("authorindex","You can switch off authorindex support to fix this.");
+ }
+
+ ### bibtex executable
+ if ( ¶m_value('bibtex') ne $NO or ¶m_value('gloss') ne $NO) {
+ &checkCommand("bibtex","You can switch off BibTeX support to fix this.");
+ }
+}
+
+#### generate the tmp file name from the original tex filename
+#### and make sure that they are not the same
+# parameter 1: orignal filename (with or without a path or .tex)
+# parameter 2: path for the tmp file (default: doc path)
+# return value: tmp name
+
+sub reserve_tmp_texname {
+ my $original_name = $_[0];
+ my $tmp_path = $_[1];
+ my $tmp_base_suffix = ¶m_value('tmp_base_suffix');
+ my $overwrite = ¶m_value('overwrite');
+ my $original_path;
+ my $original_base;
+ my $suffix;
+ my $pathed_tmp_base;
+ my @existing_files;
+
+ # separate path, base and suffix
+ ($original_base,$original_path,$suffix) = fileparse($original_name, '\.tex');
+
+ # set the path of the tmp file
+ if(!$tmp_path) {
+ $tmp_path=$original_path;
+ } else {
+ $tmp_path .= '/' if( $tmp_path ne "" and ! ($tmp_path =~ m#/$#) );
+ }
+
+ # abort if no absolute path is given
+ if( index($tmp_path, "/") != 0 ) {
+ &abort("Internal error: Illegal argument for reserve_tmp_texname:".
+ "Given file has no absolute path: $original_name");
+ }
+
+ # make sure that tmp_base_suffix is set correctly
+ if($tmp_base_suffix eq "") {
+ &abort("Temporary filename base suffix is empty.");
+ }
+
+ $pathed_tmp_base = $tmp_path.$original_base.$tmp_base_suffix;
+
+ # make sure no file with this base exists in this directory
+ @existing_files = glob "$pathed_tmp_base.*";
+ if (@existing_files != 0) {
+ &report(3, "Problems detected while reserving temporay file name!\n",
+ "In this directory are already files with this basename.\n",
+ "A list of the conflicting, existing files:\n",
+ join("\n", @existing_files), "\n");
+ if ($overwrite eq $YES) {
+ &report(4, "As you have activated the parameter 'overwrite' I will "
+ ."continue.\n",
+ "However, in order to protect the existing files I will not\n",
+ "delete any files with this basename at the final clean-up.");
+ } else {
+ &report(2, "You could activate the parameter 'overwrite' or remove ",
+ "the\n corresponding files in order to avoid these problems.");
+ &abort("No temporary name found for $original_name.");
+ }
+ } else {
+ push(@TMP_TEX_FILES, $pathed_tmp_base);
+ }
+
+ return $pathed_tmp_base.$suffix;
+}
+
+### generate LaTeX file from LyX document with LyX itself
+# parameter ($1): Lyx document
+# parameter ($2): Latex document
+
+sub generate_tex_file {
+ my $lyx_doc = $_[0];
+ my $tex_doc = $_[1];
+ my $lyx_dir;
+ my $lyx_output;
+ my $lyx_exec=¶m_value('lyx_exec');
+
+ $lyx_dir = ¶m_value('lyxrc_path');
+ $lyx_dir .= '/' if( ! ($lyx_dir =~ m#/$#) );
+ $lyx_dir .= '/' if( ! ($lyx_dir =~ m#/$#) );
+
+ ### Check if LyX file can be accessed
+ &check_file($lyx_doc,"Cannot read the specified LyX document!");
+
+ ### Check if LaTeX file exists and is newer than the LyX file
+ if ( -f $tex_doc and -M $tex_doc < -M $lyx_doc ) {
+ &report(4, "\nLaTeX file is newer than LyX document ($lyx_doc).\n",
+ "Using existing TeX file: $tex_doc\n",
+ "Remove it to force its new generation.");
+ } else {
+ ### export LaTeX file with LyX (needs a display!)
+ &checkCommand($lyx_exec, "Cannot generate LaTeX document without LyX!");
+ &report(6, "\nExporting LaTeX file");
+
+ ### move some files out of the way that stop LyX from exporting
+ foreach my $file ($lyx_dir."lyxpipe.out",$lyx_dir."lyxpipe.in",$tex_doc) {
+ if ( -f $file ) { rename($file, $file.'~'); }
+ }
+
+ $lyx_output = `$lyx_exec --export latex $lyx_doc 2>&1`;
+
+ ### check if LaTeX file now really exists
+ if ( ! -f $tex_doc ) {
+ &report(2, "Lyx Output:\n$lyx_output");
+ &report(2, "\nSorry. I cannot find '$tex_doc'.");
+ &abort("The LaTeX document was not generated by LyX!");
+ } else {
+ &report(8, "Lyx Output:\n$lyx_output");
+ }
+ }
+}
+
+#### search TeX document for a certain text tag (e.g. author, title)
+# parameter 1: file to parse
+# parameter 2: full TeX tag name
+# return value: list of the contents strings of all matching tags
+
+sub extract_tag_contents {
+ my $source=$_[0];
+ my $tag_name=$_[1];
+ my $contents;
+ my @results=();
+ my $error_message="Could not read TeX document to extract $tag_name";
+
+ &check_file($source, $error_message.'.');
+ open(EXTRACT_SOURCE, "<$source") or
+ &abort($error_message." ($source).");
+
+
+ while(<EXTRACT_SOURCE>) {
+ ### ignore comments
+ s/(^|[^\\])%.*/$1/;
+ # ignore \thanks{}
+ s/\\thanks\{.*?\}//g;
+ # change \and to and
+ s/\\and/ and/g;
+
+ $contents .= $_;
+ }
+
+ close EXTRACT_SOURCE;
+
+ $_ = $contents;
+
+ # add contents of all occurences of this tag in a line to result list
+ while ( /\\($tag_name)(\[[^]]*?\])*?{+([^{}]*?)}/s ) {
+ my $text = $3;
+ $_ = $';
+ # remove newlines
+ $text =~ s/\n//g;
+ $text="" if (!defined($text));
+ push(@results, $text);
+ }
+
+ return @results;
+}
+
+#### search for filenames in given TeX Tag in entire document
+### skip all comments and duplicates while parsing
+# parameter 1: file to parse
+# parameter 2: full TeX tag name
+# parameter 3: reference to a list of possible filename suffixes (without '.')
+# parameter 4: regexp for suffix to ignore when specified in TeX file
+# (undef if not used)
+# return value: list of identified files
+
+sub identify_files {
+ my $source=$_[0];
+ my $tag_name=$_[1];
+ my @suffixes=@{$_[2]};
+ my $ignore_suffix=$_[3];
+ my @matched_tags;
+ my @found_files=();
+ my $regexp_suffixes;
+
+ # create one large regexp from given suffixes and escape dots in them
+ $regexp_suffixes= '.('.join('|', @suffixes).')';
+ $regexp_suffixes =~ s/\./\\./g;
+
+ @matched_tags = &extract_tag_contents($source, $tag_name);
+
+ foreach my $tag_contents (@matched_tags) {
+ my $path;
+ my $base;
+ my $suffix;
+ my $kpse_result;
+ my $working_dir = cwd."/";
+
+ ($base,$path,$suffix) = fileparse($tag_contents, $regexp_suffixes);
+
+ # if a suffix is specified in the tag_contents handle it as requested
+ #
+ # 1. $suffix: TRUE if $suffix is defined and not of zero length
+ # means: a valid suffix has been found in the filename
+ # 2. defined($ignore_suffix): TRUE if $ignore_suffix is defined
+ # means: a regexp for suffixes to be ignored has been specified as
+ # parameter4
+ # 3. $suffix =~ /$ignore_suffix/: TRUE if $suffix matches the regexp
+ # means: the suffix in the filename is wanted to be ignored
+ #
+ # The IF statement will be executed when:
+ # a valid suffix has been found in the filename (1)
+ # AND regexp for suffixes to be ignored has NOT been specified (not 2)
+ # OR
+ # a valid suffix has been found in the filename (1)
+ # AND regexp for suffixes to be ignored has been specified (2)
+ # AND the suffix in the filename is NOT wanted to be ignored (not 3)
+ #
+ # The stuff that is executed if the entire IF statement is TRUE does the
+ # following: accept the found suffix and consider it as the only possible
+ # file name.
+ if($suffix and not (defined($ignore_suffix) and $suffix =~ /$ignore_suffix/)){
+ $kpse_result=`kpsewhich $tag_contents`;
+ # print warning and skip this tag if kpsewhich could not find it
+ if (!$kpse_result) {
+ &report(4, "WARNING - Could not identify referenced file:\n",
+ " Ignoring '$tag_contents'.");
+ next;
+ }
+ } else {
+ # if there is a '.' in the basename assume that this is a reference
+ # to a file of another type and skip it
+ if( $base =~ /\./ ) {
+ &report(9, "Found an unknown extension. Ignoring '$tag_contents'.");
+ next;
+ }
+
+ # search for all possible files with allowed suffixes
+ foreach my $allowed_suffix (@suffixes) {
+ if (not $allowed_suffix =~ /[\]\)\(\|\[\\]/ ) {
+ # suffix is not a regexp, but a real extension
+ my $possible_file= $path.$base.'.'.$allowed_suffix;
+ $kpse_result=`kpsewhich $possible_file`;
+ if ($kpse_result) {
+ last;
+ }
+ }
+ }
+ }
+
+ # if kpsewhich could not find any file with an allowed suffix
+ # assume that this reference is of a different type and skip it
+ # quietly
+ if (!$kpse_result) {
+ &report(9, "No suitable file found. Ignoring '$tag_contents'.");
+ next;
+ }
+
+ # expand '.' in kpsewhich output to the current path
+ $kpse_result =~ s#^\./#$working_dir#;
+
+ # remove trailing newline
+ chomp($kpse_result);
+
+ # add file to the found file list if it is not already on it
+ if( &array_index($kpse_result, @found_files) < 0 ) {
+ push(@found_files, $kpse_result);
+ }
+ }
+
+ return @found_files;
+}
+
+### Build a list of all files which are included from the root file.
+# This function recurses, and is maybe smart enough to detect cycles.
+# Be sure to set REF_DOCS to the empty string prior to calling this.
+# parameter 1: tex file to start with
+# no return value
+# result is appended to global variable @REF_DOCS
+
+sub get_file_list {
+ my $source = $_[0];
+ my @imports = ();
+
+ # This is the cycle avoidance logic.
+ if ( &array_index($source, @REF_DOCS) < 0 ) {
+ # Make sure the file can be accessed
+ &check_file($source, "Included TeX file seems not to be available. Path problem?");
+
+ # Save the argument in the list of files.
+ push(@REF_DOCS, $source);
+
+ # Get the list of files included by the argument.
+ @imports=&identify_files($source, 'include|input', ['tex']);
+
+ # Recurse.
+ foreach my $file (@imports) {
+ if( ! ($file =~ /\.tex$/) ) { $file .= '.tex'; }
+ &get_file_list($file);
+ }
+ }
+}
+
+### do the required modifications in the LaTeX preamble
+# parameter 1: original preamble from the source file
+# lines before \begin{document} tag (without this tag)
+# parameter 2: reference to hyperref parameter list
+# return value: adjusted preamble
+
+sub adjust_preamble {
+ my $preamble = $_[0];
+ my $hyperref_params_ref = $_[1];
+ my $extra_code;
+ my $result;
+
+ $_ = $preamble;
+
+ # protect pdflatex execution mode
+ s/^(\\batchmode)$/% $1/m;
+
+ # insert a4paper in the documentclass when a4wide is used
+ # fixes problem that hyperref defaults to letter otherwise
+ if ( /^[^%]*\\usepackage(\[widemargins\])?\{(a4|a4wide)\}/m ) {
+ # check if package parameters with [] brackets are present
+ if ( not s/^(\\documentclass\[.*?)\]/$1,a4paper]/m ) {
+ s/^\\documentclass/$&\[a4paper\]/m;
+ }
+ }
+
+ ### collect additional LaTeX code
+
+ $extra_code = "\n" . '\usepackage{pslatex}' . "\n";
+
+ if ( ¶m_value('thumbpdf') eq $YES ) {
+ $extra_code .= '\usepackage{thumbpdf}' . "\n";
+ } else {
+ $extra_code .= "% no thumbpdf support\n";
+ }
+
+# if ( ¶m_value('ppower') eq $YES ) {
+# $extra_code .= '\usepackage{mpmulti}' . "\n";
+# } else {
+# $extra_code .= "% no ppower support\n";
+# }
+
+ if ( ¶m_value('authorindex') eq $YES ) {
+ $extra_code .= '\usepackage[pages]{authorindex}' . "\n";
+ $extra_code .= '\let\cite=\aicite' . "\n";
+ } else {
+ $extra_code .= "% no authorindex support\n";
+ }
+
+ $extra_code .= '\makeatletter' . "\n";
+ $extra_code .= '\usepackage[' . join(',', @$hyperref_params_ref)
+ . ']{hyperref}' . "\n";
+ $extra_code .= '\makeatother' . "\n";
+
+ ### insert the extra LaTeX code directly after documentclass
+ m/^(\\documentclass)(\[[^]]*\])?(\{.*\})/m;
+ return $` . $& . $extra_code . $';
+}
+
+### adjust all filenames in the LaTeX code to the tmp files
+# parameter 1: original LaTeX code from the source file
+# return value: adjusted code
+
+sub adjust_filenames {
+ my $code = $_[0];
+ my $tmp_suffix = ¶m_value('tmp_base_suffix');
+ my $result;
+
+ $_ = $code;
+
+ # cut off the suffix of eps, ps, *.gz and pstex graphics
+ s/((\\includegraphics)(\[[^]]*?\])?(\{[^}]+?))\.(e?ps|pstex|e?ps\.gz)\n?\}/$1}/sg;
+
+ # replace the suffix 'pstex_t' with 'pdf_t'
+ s/(\\input\{[^}]+?\.)pstex_t\n?\}/$1pdf_t}/sg;
+
+ if ( ¶m_value('mtp_preamble') eq $NO ) {
+ # cut off the suffix of mmp graphics
+ s/(\\multiinclude(\[[^]]*?\])?\{[^}]+?)\.mmp\n?\}/$1}/sg;
+ } else {
+ # replace the suffix '.#' with '-mp.#'
+ s/(\\includegraphics(\[[^]]*?\])?\{[^}]+?)\.(\d+?)\n?\}/$1$MTP_TMP_BASESUFFIX\.$3}/sg;
+
+ # replace the suffix '.#' with '-mp.#'
+ s/(\\convertMPtoPDF(\[[^]]*?\])?\{[^}]+?)\.(\d+?)\n?\}/$1$MTP_TMP_BASESUFFIX\.$3}/sg;
+
+ # cut off optional suffix '.mmp' and append '-mp' in any case
+ s/(\\multiinclude(\[[^]]*?\])?\{[^}]+?)(\.mmp)?\n?\}/$1$MTP_TMP_BASESUFFIX}/sg;
+ }
+
+ # insert the tmp_suffix in tex filenames
+ # I assume that files with no extension are TeX files as well; correct?
+ s#(\\(input|include)\{([^}]*?/)?[^}/.]+?)((\.tex)?\n?\})#$1$tmp_suffix$4#sg;
+
+ return $_;
+}
+
+### Convert given tex file to the temp tex file we need for pdftex
+### major task is to change the reference in the tex files to the
+### corresponding tmp files
+# parameter 1: tex source file
+# parameter 2: tex tmp file
+# parameter 3: reference to hyperref parameter list or
+# 'undef' if preamble should not be changed
+
+sub convert_tex2tmp {
+ my $source = $_[0];
+ my $target = $_[1];
+ my $hyperref_params_ref = $_[2];
+ my $contents;
+ my $preamble;
+ my $body;
+ my $adjust_preamble = defined($hyperref_params_ref) ? $YES : $NO;
+ my $read_err_msg = "Could not read original TeX document to generate temporary document";
+
+ ### open source and target file
+ &check_file($source, $read_err_msg . '.');
+ open(SOURCE_FILE, "<$source") or
+ &abort($read_err_msg . " ($source).");
+
+ ### read in the LaTeX source file
+ $contents = "";
+ while(<SOURCE_FILE>) {
+ $contents .= $_;
+ }
+
+ close SOURCE_FILE;
+
+ ### prepare the LaTeX code for PDF generation
+ if ( $adjust_preamble eq $YES ) {
+ $contents =~ m/^ *\\begin\{document\} *$/m;
+ $preamble = $`;
+ $body = $&.$';
+ $preamble = &adjust_preamble($preamble, $hyperref_params_ref);
+ $preamble = &adjust_filenames($preamble);
+ } else {
+ $preamble = "";
+ $body = $contents;
+ }
+
+ $body = &adjust_filenames($body);
+
+ ### write the new LaTeX target file
+ open(TARGET_FILE, ">$target") or
+ &abort("Could not open file to write temporary TeX document ($target).");
+
+ print TARGET_FILE $preamble.$body;
+
+ close TARGET_FILE;
+}
+
+### Convert the given EPS image to PDF
+# parameters $1: EPS image filename with absolute path
+# return value: none
+
+sub convert_eps2pdf {
+ my $image = $_[0];
+ my $image_path;
+ my $image_base;
+ my $image_name;
+ my $suffix;
+ my $image_target;
+ my $zipped = 0;
+ my $dummy;
+
+ ($image_base,$image_path,$suffix) = fileparse($image, '\.eps', '\.ps', '\.pstex', '\.gz');
+ if ($suffix eq "\.gz") {
+ $zipped = 1;
+ ($image_base,$dummy,$suffix) = fileparse($image_base, '\.eps', '\.ps', '\.pstex');
+ }
+ $image_name = $image_base . $suffix;
+ $image_target = $image_path . $image_base . '.pdf';
+
+ #### check if image file really exists
+ #&check_file($image, "Could not convert referenced image.");
+
+ ### return if image directory is not writeable
+ if (! -w $image_path) {
+ &report(4, "WARNING - Image directory not writable: $image_path\n",
+ " Skipping '$image_name', assume you have converted it manually.");
+ return;
+ }
+
+ if ( ! -f $image_target or -M $image_target > -M $image ) {
+ &report(7, "Converting image $image_name to $image_target ...\n");
+ if ($zipped > 0) {
+ &system_command("gunzip -c $image | epstopdf -f -outfile=$image_target",
+ $TRUE, 8, "epstopdf failed on $image_name");
+ } else {
+ &system_command("epstopdf -outfile=$image_target $image",
+ $TRUE, 8, "epstopdf failed on $image_name");
+ }
+ if (¶m_value('delete_pdf_images') eq $YES) {
+ push(@TMPFILES, $image_target);
+ }
+ } else {
+ &report(7, "$image_base.pdf newer than $image_name, conversion skipped...");
+ }
+}
+
+### Convert the given PSTEX_T file to PDF_T
+# parameters 1: PSTEX_T filename with absolute path
+# return value: none
+
+sub convert_pstex2pdf {
+ my $pstex_file = $_[0];
+ my $pstex_path;
+ my $pstex_base;
+ my $pstex_name;
+ my $suffix;
+ my $pstex_target;
+ my @eps_images;
+
+ ($pstex_base,$pstex_path,$suffix) = fileparse($pstex_file, ('\.pstex_t'));
+ $pstex_name = $pstex_base . $suffix;
+ $pstex_target = $pstex_path . $pstex_base . '.pdf_t';
+
+ #### check if image file really exists
+ #&check_file($pstex_file, "Could not convert referenced file.");
+
+ ### return if directory is not writeable
+ if (! -w $pstex_path) {
+ &report(4, "WARNING - Directory not writable: $pstex_path\n",
+ " Skipping '$pstex_name', assume you have converted it manually.");
+ return;
+ }
+
+ # descend into file
+ &report(7, "Converting file $pstex_name ...\n");
+
+ # find included EPS image(s)
+ @eps_images=&identify_files($pstex_file, 'includegraphics',
+ ['pstex', 'pstex\.gz']);
+
+ # create .pdf_t file
+ &convert_tex2tmp($pstex_file, $pstex_target, undef);
+
+ # put tmp file in the tmp file list
+ push(@TMPFILES, $pstex_target);
+
+ # convert image(s) to pdf
+ foreach my $image (@eps_images) {
+ &convert_eps2pdf($image);
+ }
+}
+
+### Convert the given MP image to PDF
+# parameters $1: MP image filename with absolute path
+# return value: none
+
+sub convert_mp2pdf {
+ my $image = $_[0];
+ my $image_path;
+ my $image_base;
+ my $image_name;
+ my $suffix;
+ my $image_target;
+ my $image_src;
+ my @mps_fig=();
+ my $mp_fig;
+
+ ($image_base,$image_path,$suffix) = fileparse($image, '\.mp|\.mmp');
+ $image_name = $image_base . $suffix;
+ $image_src=$image_path . $image_base . $suffix;
+
+ @mps_fig= &grep_file($image_path.$image_name,'beginfig',$TRUE);
+ $_=$mps_fig[0];
+ /(\d)/;
+ $mp_fig=$1;
+ if (¶m_value('mtp_preamble') eq $YES) {
+ $image_target = $image_path . $image_base . $MTP_TMP_BASESUFFIX . '.' . $mp_fig;
+ $image_name=$image_base.$MTP_TMP_BASESUFFIX.$suffix;
+ } else {
+ $image_target = $image_path . $image_base . '.' . $mp_fig;
+ }
+
+ #### check if image file really exists
+ #&check_file($image, "Could not convert referenced image.");
+
+ ### return if image directory is not writeable
+ if (! -w $image_path) {
+ &report(4, "$MYNAME: WARNING - Image directory not writable: $image_path\n",
+ " Skipping '$image_name', assume you have converted it manually.");
+ return;
+ }
+
+ if ( ! -f $image_target
+ or (-M $image_target > -M $image_src)
+ or ( ( ¶m_value('mtp_preamble') eq $YES)
+ and (-M $image_target > -M $image_path.$MTP_PREAMBLE_FILENAME) ) ) {
+ &report(7, "Converting image $image_name ...\n");
+ my $working_dir = cwd."/";
+ chdir("$image_path") or &abort("cannot cd to $image_path($!)");
+ if ( ¶m_value('mtp_preamble') eq $YES ) {
+ &modify_mp_file($image_base,$suffix);
+ }
+ &system_command("mpost $image_name",
+ $TRUE, 8, "mpost failed on $image_name");
+ chdir("$working_dir") or &abort("cannot cd to $working_dir($!)");
+ if (¶m_value('delete_pdf_images') eq $YES) {
+ push(@TMPFILES, $image_target);
+ }
+ } else {
+ if ( ¶m_value('mtp_preamble') eq $YES ) {
+ &report(7, "$image_base$MTP_TMP_BASESUFFIX.$mp_fig newer than $image_base$suffix, conversion skipped...");
+ } else {
+ &report(7, "$image_base.$mp_fig newer than $image_base$suffix, conversion skipped...");
+ }
+ }
+}
+
+### Convert the given MP image to PDF
+# parameters $1: MP image filename with absolute path
+# return value: none
+
+sub modify_mp_file {
+ my $base=$_[0];
+ my $suffix=$_[1];
+ my $preamble_file=$MTP_PREAMBLE_FILENAME;
+
+ my $mp_source=$base.$suffix;
+ my $mp_target=$base.$MTP_TMP_BASESUFFIX.$suffix;
+
+ ### open source and target file
+ open(SOURCE_FILE, "<$mp_source") or
+ &abort("Could not open $mp_source to add $preamble_file ($mp_source).");
+
+ open(TARGET_FILE, ">$mp_target") or
+ &abort("Could not open $mp_target to add $preamble_file ($mp_source).");
+
+ open(PREAMBLE_FILE, "<$preamble_file") or
+ &abort("Could not open $preamble_file to be added to metapost files ($mp_source).");
+
+ ### set target file as stdout
+ select TARGET_FILE;
+ print 'verbatimtex' . "\n";
+ print '%&latex' . "\n"; # This forces metapost to use latex in the compilation
+ print '\documentclass[english]{article}' . "\n"; # we have to decide if this sentence goes in preamble.cfg or here
+ # english must be added
+ # to preamble in order to
+ # make work mpost, why ???
+ while(<PREAMBLE_FILE>) {
+ print $_
+ }
+ print '\begin{document}' . "\n"; # we have to decide if this sentence goes in preamble.cfg or here
+ print 'etex' . "\n";
+ while(<SOURCE_FILE>) {
+ print $_
+ }
+ print 'verbatimtex' . "\n";
+ print '\end{document}' . "\n";
+ print 'etex' . "\n";
+
+ ### set STDOUT as stdout again
+ select STDOUT;
+
+ ### close files
+ close SOURCE_FILE;
+ close TARGET_FILE;
+ close PREAMBLE_FILE;
+
+}
+
+
+### Convert included images to pdf
+# parameter 1: tex source file
+# no return value
+
+sub convert_images {
+ my $tex_source=$_[0];
+ my @pstex_file_list;
+ my @image_list;
+ my @mp_image_list;
+ my @mmp_image_list;
+ my @major_suffixes;
+ my $ignore_regexp;
+
+ &report(6, "\nConverting images referenced in $tex_source.");
+
+ ##### Get images of major type from the source file
+ @major_suffixes = (@BITMAP_SUFFIXES, $PDF_ORIG_SUFFIX, @EPS_SUFFIXES);
+ $ignore_regexp = '.('.join('|',@EPS_SUFFIXES).')';
+ $ignore_regexp =~ s/\./\\./g;
+
+ &report(6, "\nScanning for major image types (".join(', ',@major_suffixes)."):");
+ @image_list = &identify_files($tex_source,'includegraphics',
+ \@major_suffixes, $ignore_regexp );
+
+ if ( @image_list > 0 ) {
+ &report(7, join("\n", @image_list));
+ } else {
+ &report(7, "None.");
+ }
+
+ ##### Get PSTEX_T files from the source file
+ &report(6, "\nScanning for PSTEX_T files (.pstex_t):");
+ @pstex_file_list=&identify_files($tex_source, 'input', ['pstex_t']);
+ if ( @pstex_file_list > 0 ) {
+ &report(7, join("\n", @pstex_file_list));
+ } else {
+ &report(7, "None.");
+ }
+
+ ##### Get MP images from the source file
+ &report(6, "\nScanning for MP images (.mp):");
+ @mp_image_list=&identify_files($tex_source,
+ 'convertMPtoPDF|includegraphics',['mp','(\d+)'],'\.(\d+)');
+ # FIXME
+ # fixed for now by ignoring strange extension in identify_files
+ #
+ # the above could cause problems as identify_files is expecting a list of
+ # real extensions and not of regexps
+ # maybe the only way to fix this is to adjust identify_files to ignore
+ # invalid extension when testing them with kpsewhich
+ # ALTERNATIVE: design identify_files to use preffered_suffixes instead
+ # of ignore_suffixes
+
+ if ( @mp_image_list > 0 ) {
+ &report(7, join("\n", @mp_image_list));
+ } else {
+ &report(7, "None.");
+ }
+
+ ##### Get MMP images from the source file
+ &report(6, "\nScanning for MMP images (.mmp):");
+ @mmp_image_list=&identify_files($tex_source,'multiinclude',['mmp']);
+ if ( @mmp_image_list > 0 ) {
+ &report(7, join("\n", @mmp_image_list));
+ } else {
+ &report(7, "None.");
+ }
+
+ ### Convert EPS images to PDF, copy pdf.orig image files to pdf,
+ ### and simply ignore all other
+ if ( @image_list > 0) {
+ my $handled_suffixes;
+
+ &report(6, "\nProcessing images of major types:");
+
+ # create one large regexp from suffixes and escape dots in them
+ $handled_suffixes = '.('.join('|',(@EPS_SUFFIXES, $PDF_ORIG_SUFFIX)).')';
+ $handled_suffixes =~ s/\./\\./g;
+
+ foreach my $image (@image_list) {
+ my $path;
+ my $base;
+ my $suffix;
+ ($base,$path,$suffix) = fileparse($image, $handled_suffixes);
+ if (not $suffix) {
+ &report(7, "No special handling required for image: $base$suffix");
+ } elsif ($suffix eq ('.'.$PDF_ORIG_SUFFIX) ) {
+ my $image_target = $path.$base.'.pdf';
+
+ if ( ! -f $image_target or -M $image_target > -M $image ) {
+ &report(7, "Create temporary PDF file from original: $base$suffix");
+ copy($image, $image_target)
+ or &abort("Could not create tmp file: $!");
+ if (¶m_value('delete_pdf_images') eq $YES) {
+ push(@TMPFILES, $image_target);
+ }
+ } else {
+ &report(7, "$base.pdf newer than $base$suffix, copy skipped ...");
+ }
+ } else {
+ &convert_eps2pdf($image);
+ }
+ }
+ }
+
+ ### Convert all PSTEX_T files to PDF_T
+ if ( @pstex_file_list > 0 ) {
+ &report(6, "\nConverting pstex_t docs to pdf_t docs");
+ foreach my $image (@pstex_file_list) {
+ &convert_pstex2pdf($image);
+ }
+ }
+
+ ### Convert all MP images to PDF
+ if ( @mp_image_list > 0) {
+ &report(6, "\nConverting MP images to PDF");
+ foreach my $image (@mp_image_list) {
+ &convert_mp2pdf($image);
+ }
+ }
+
+ ### Convert all MMP images to PDF
+ if ( @mmp_image_list > 0) {
+ &report(6, "\nConverting MMP images to PDF");
+ foreach my $image (@mmp_image_list) {
+ &convert_mp2pdf($image);
+ }
+ }
+
+ &report(6, "\nFinished converting for ${tex_source}.");
+}
+
+### run pdflatex
+# parameter 1: LaTeX file without extension
+# parameter 2: log-file where the full out put is stored
+# return value: 0 - no errors (no rerun); 1 - errors (rerun required)
+
+sub run_pdflatex {
+ my $texfile=$_[0];
+ my $logfile=$_[1];
+ my @errors=();
+ my $exit_status=0;
+ my $extra_options=¶m_value('pdftex_opts');
+
+ if( !defined($extra_options) or $extra_options eq $NIL ) {
+ $extra_options = "";
+ }
+
+ &report(7, "Running pdflatex. This may take a while.\n");
+ system("pdflatex --interaction nonstopmode $extra_options $texfile > $logfile 2>&1");
+ $exit_status=$?;
+ &report(7, "Pdflatex finished. Errors:");
+
+ ### extract all errors and warnings from the log file
+ @errors = &grep_file($logfile, '(Emergency stop|Error|Warning).*:');
+
+ ### make sure thumbpdf package does not spoil rerun detection
+ ### as it will be processed very last
+ if(grep(/Package thumbpdf/, @errors) == @errors) { @errors=(); }
+
+ if ( @errors != 0 or $exit_status != 0 ) {
+ if ( grep(/Emergency stop/, @errors) != 0 ) {
+ &report(2, &file_tail($logfile,10));
+ &report(2, "\nSee $logfile for details.");
+ &abort("Fatal error occured. I am lost.");
+ }
+ if( @errors != 0 ) {
+ &report(8, @errors);
+ } else {
+ &report(8, &file_tail($logfile,10));
+ }
+ &report(7, "\nSee $logfile for details.");
+ return $FALSE;
+ } else {
+ &report(7, "None detected (log file: $logfile).");
+ return $TRUE;
+ }
+}
+
+#### run bibtex if BIBTEX=$YES or a bibliography tag is found
+# included tex files are not parsed for a bibliography
+# parameter 1: filename of the aux file without .aux suffix
+# parameter 2: log-file where the full out put is stored
+
+sub handle_bibtex {
+ my $auxfile=$_[0];
+ my $logfile=$_[1];
+ my $run_bibtex=$FALSE;
+ my $bibtex_param=¶m_value('bibtex');
+
+ if ( $bibtex_param eq $YES ) {
+ $run_bibtex=$TRUE;
+ &report(7, "BibTeX parameter set to '$YES':");
+ } else {
+ &report(7, "Checking for BibTeX bibliography in main document: ");
+ if( &grep_file($auxfile.'.tex', '^[^%]*\\\\bibliography{') != 0) {
+ $run_bibtex=$TRUE;
+ &report(7, "Bibliography detected.");
+ } else {
+ if ( @REF_DOCS > 0 ) {
+ &report(7, "Checking for BibTeX bibliography in included documents:");
+ foreach my $file (@REF_DOCS) {
+ if( &grep_file($file, '^[^%]*\\\\bibliography{') != 0) {
+ $run_bibtex=$TRUE;
+ &report(7, "Bibliography detected.");
+ } else {
+ &report(7, "No bibliography detected in $file.");
+ }
+ }
+ } else {
+ &report(7, "No bibliography detected.");
+ }
+ }
+ }
+
+ if ( $run_bibtex ) {
+ my @errors=();
+ my $exit_status=0;
+
+ &report(7, "Running bibtex. This may take a while.\n");
+ system "bibtex $auxfile > $logfile";
+ $exit_status=$?;
+ &report(7, "Bibtex finished. Errors:");
+
+ ### extract all errors and warnings from the log file
+ @errors=&grep_file($logfile, 'error message');
+
+ if ( @errors != 0 or $exit_status != 0 ) {
+ &report(4, &file_tail($logfile));
+ &report(4, "\nYou can switch off BibTeX support by setting the bibtex parameter accordingly.");
+ } else {
+ &report(7, "None detected (log file: $logfile).");
+ }
+ }
+}
+
+#### run bibtex on file.gls if BIBTEX=$YES or a bibliography tag is found
+# included tex files are not parsed for a bibliography
+# parameter 1: filename of the aux file without .aux suffix
+# parameter 2: log-file where the full out put is stored
+
+sub handle_gloss {
+ my $auxfile=$_[0];
+ my $logfile=$_[1];
+ my $run_gloss=$FALSE;
+ my $gloss_param=¶m_value('gloss');
+ my $glsfile=$auxfile.'.gls';
+
+ if ( $gloss_param eq $YES ) {
+ $run_gloss=$TRUE;
+ &report(7, "Gloss parameter set to '$YES':");
+ } else {
+ &report(7, "Checking for Gloss bibliography in main document: ");
+ if( &grep_file($auxfile.'.tex', '^[^%]*\\\\printgloss{') != 0) {
+ $run_gloss=$TRUE;
+ &report(7, "Gloss bibliography detected.");
+ } else {
+ if ( @REF_DOCS > 0 ) {
+ &report(7, "Checking for Gloss bibliography in included documents:");
+ foreach my $file (@REF_DOCS) {
+ if( &grep_file($file, '^[^%]*\\\\printgloss') != 0) {
+ $run_gloss=$TRUE;
+ &report(7, "Gloss bibliography detected.");
+ } else {
+ &report(7, "No gloss database detected in $file.");
+ }
+ }
+ } else {
+ &report(7, "No gloss database detected.");
+ }
+ }
+ }
+ if ( $run_gloss ) {
+ my @errors=();
+ my $exit_status=0;
+
+ &report(7, "Running bibtex on $glsfile. This may take a while.\n");
+ system "bibtex $glsfile > $logfile 2>&1";
+ $exit_status=$?;
+ &report(7, "Bibtex finished. Errors:");
+
+ ### extract all errors and warnings from the log file
+ @errors=&grep_file($logfile, 'error message');
+
+ if ( @errors != 0 or $exit_status != 0 ) {
+ &report(4, &file_tail($logfile));
+ &report(4, "\nYou can switch off Gloss support by setting the gloss parameter accordingly.");
+ } else {
+ &report(7, "None detected (log file: $logfile).");
+ }
+ }
+}
+
+#### run thumbpdf command to make thumbnails
+# more informations: /usr/share/texmf/doc/pdftex/thumbpdf/readme.txt
+# parameter 1: LaTeX file without extension
+# parameter 2: log-file where the full out put is stored
+
+sub run_thumbpdf {
+ my $texfile=$_[0];
+ my $logfile=$_[1];
+ my $exit_status=0;
+
+ &report(7, "\nCreating thumbnails with 'thumbpdf'\n");
+ &system_command("thumbpdf $texfile", $FALSE, 8,
+ "thumbpdf failed.\n"
+ ."I will continue, but maybe there will not be thumbs in the PDF doc.");
+
+ if ( -f 'thumbpdf.log' ) {
+ move('thumbpdf.log', $logfile);
+ &report(7, "\nSee $logfile for details.");
+ }
+
+ ### store possible tmp files
+ push(@TMPFILES, glob 'thumb???.png');
+ push(@TMPFILES, 'thumbpdf.pdf');
+ push(@TMPFILES, 'thumbdta.tex');
+ push(@TMPFILES, $texfile.'.tpt');
+}
+
+
+#### run ppower command to make presentations
+# more informations:
+# parameter 1: LaTeX file without extension
+# parameter 2: log-file where the full out put is stored
+
+sub run_ppower {
+ my $texfile=$_[0];
+ my $logfile=$_[1];
+ my $exit_status=0;
+ my $infile;
+ my $outfile;
+ my $texfile_base;
+ my $texfile_path;
+ my $texfile_suffix;
+
+ ##### Getting document name, suffix and path
+ ($texfile_base,$texfile_path,$texfile_suffix) = fileparse($texfile,¶m_value('tmp_base_suffix'));
+
+ $infile=$texfile_base.'.pdf';
+ $outfile=$texfile_base.'_p4.pdf';
+
+ &report(7, "\nPostprocessing PDF file with 'ppower'\n");
+ if(&system_command("ppower $infile $outfile", $FALSE, 8,
+ "ppower failed.\nI will continue, "
+ ."but maybe there will not be pause effects in the PDF doc.")) {
+ &report(7, "\nThe postprocessed pdf file is: $outfile\n");
+ }
+
+ if ( -f 'ppower.log' ) {
+ move('ppower.log', $logfile);
+ &report(7, "See $logfile for details.");
+ }
+}
+
+#### run authorindex command to obtain an author index
+# more informations:
+# parameter 1: LaTeX file without extension
+# parameter 2: log-file where the full out put is stored
+
+sub run_authorindex {
+ my $texfile=$_[0];
+ my $logfile=$_[1];
+ my $exit_status=0;
+
+ &report(7, "\nProcessing file with 'authorindex'\n");
+ &system_command("authorindex $texfile", $FALSE, 8,
+ "authorindex failed.\nI will continue, "
+ ."but maybe there will not be an author index in the PDF doc.");
+
+ if ( -f 'authorindex.log' ) {
+ move('authorindex.log', $logfile);
+ &report(7, "\nSee $logfile for details.");
+ }
+
+}
+
+
+##### read and analyse configuration and options and adjust basic variables
+##### accordingly
+#### The following sources are considered (last value overrides previous)
+## 1. general configuration (global variables in the script)
+## 2. private configuration (in user's RC file)
+## 3. command line options
+# parameters: none
+# return value: given document argument
+
+sub adjust_configuration {
+ my $valid_rcfile = $FALSE;
+ my %opt_specs =();
+
+ ### Check number of arguments
+ if ( @ARGV == 0 ) {
+ &report(1, "\nI need at least one argument!");
+ &print_usage;
+ exit 1;
+ }
+
+ ##### command line options and private configuration files handling
+
+ ### set parameters from rc file
+ if ( -f $RC_FILENAME ) {
+ my $rcfile_version;
+ $rcfile_version = &read_configuration($RC_FILENAME);
+ if( $rcfile_version == $MYRCFILE_VERSION ) {
+ $valid_rcfile = $TRUE;
+ } elsif ( $rcfile_version == 0 ) {
+ &report(4, "Could not determine version of read RC file.");
+ } else {
+ &report(4, "Version of read RC file ($rcfile_version) and ",
+ "this script ($MYRCFILE_VERSION) differs.");
+ }
+ }
+
+ ### scan parameters
+ foreach (keys %PARAMETER_LIST) {
+ $opt_specs{&option_specifier($_)} = \&handle_option;
+ }
+ if(! GetOptions(%opt_specs)) {
+ &print_usage;
+ &abort("An error occured while processing command line options");
+ }
+
+ if( ! $valid_rcfile ) {
+ &report(3,"No valid configuration file found. Please run '$MYNAME "
+ ."--configure'.\nUsing default values for missing parameters in this "
+ ."session.");
+ }
+
+ ### As the configuration process is done now, it is time to set the
+ # global configuration flag
+ $CONFIGURED = $TRUE;
+
+ #### do some test in order to secure as good as possible that we will
+ #### succeed before to much work was done and maybe some data as damaged
+
+ ### make sure that tmp_base_suffix is not empty
+ if ( ¶m_value('tmp_base_suffix') eq "" ) {
+ &report(2, "\nCAUTION: Empty tmp_base_suffix would destroy the original files!");
+ &abort("Parameter tmp_base_suffix is not set.");
+ }
+
+ ##### check for required commands
+ if (¶m_value('check_commands') ne $NO ) {
+ &check_commands;
+ }
+
+ ### Check number of arguments
+ if ( @ARGV != 1 ) {
+ &report(1, "\nWrong number of arguments. I need exactly one file.");
+ &print_usage;
+ exit 1;
+ }
+
+ return $ARGV[0];
+}
+
+#### prepare the logdir for the log files of the various called appplications
+
+sub prepare_logdir {
+ my $log_dir= ¶m_value('logdir');
+ my $my_new_log;
+
+ ##### Preparing the LOGDIR
+ if (! &check_dir($log_dir, "Could not create log directory", $YES)) {
+ &abort("Please, set a different path and restart");
+ }
+
+ # make sure there is a slash at the end of the path
+ $log_dir .= '/' if( ! ($log_dir =~ m#/$#) );
+
+ if( <$log_dir/*.log> and ¶m_value('clean_logs') eq $YES ) {
+ &report(6, "\nRemoving old log files ($log_dir).");
+ unlink (<$log_dir/pdflatex-*.log>, <$log_dir/bibtex-*.log>,
+ <$log_dir/gloss-*.log>, <$log_dir/thumbpdf-*.log>,
+ <$log_dir/ppower-*.log>, <$log_dir/authorindex-*.log>,
+ <$log_dir/tex2pdf-*.log>);
+ } else {
+ &report(6, "\nAll log files will be stored in ($log_dir).");
+ }
+
+ ### move my pre-configuration log file to specified log directory
+ $my_new_log = "$log_dir/tex2pdf-$$.log";
+ if ( move($MYLOGFILE, $my_new_log) ) {
+ $MYLOGFILE = $my_new_log;
+ } else {
+ &report(3, "Could not move '$MYLOGFILE' to logdir: $!");
+ }
+}
+
+##### analyse document argument
+#### process the one and only argument (besides the options) which specifies
+#### which LaTeX document the user wants to translate to PDF
+#### a lyx file will be translated to LaTeX first
+# parameter 1: argument
+
+sub process_doc_argument {
+ my $argument = $_[0];
+ my $doc_base;
+ my $doc_path;
+ my $arg_suffix;
+
+ ##### Getting document name, suffix and path
+ ($doc_base,$doc_path,$arg_suffix) = fileparse($argument, ('\.tex', '\.lyx'));
+
+ if (! defined($arg_suffix) or $arg_suffix eq "") {
+ $arg_suffix = '.tex';
+ }
+
+ ###### change working directory to document directory
+ if ( $doc_path ne "" ) {
+ chdir $doc_path;
+ }
+
+ ###### make DOCPATH an absolute path
+ $doc_path = cwd.'/';
+
+ ###### Cut off suffix and do lyx or tex specific stuff
+ if ( $arg_suffix eq '.lyx' ) {
+ # Lyx document argument: generate Latex document if required
+ &generate_tex_file($doc_base.'.lyx', $doc_base.'.tex');
+ } else {
+ # LaTeX document argument: check access to given LaTeX document
+ &check_file($doc_base.'.tex', "Cannot read the specified LaTeX document!");
+ }
+
+ return $doc_path.$doc_base.'.tex';
+}
+
+#### handle the dir of the input path if the document has one and
+# parameter 1: main tex doc
+# return value: absolute input path
+
+sub process_inputpath {
+ my $texdoc = $_[0];
+ my $doc_base;
+ my $doc_path;
+ my $doc_suffix;
+ my $input_path;
+ my @matches;
+
+ ### Maybe the user has given us a different inputpath
+ $input_path = ¶m_value('input_path');
+ if(defined($input_path) and $input_path ne "") {
+ &report(6, "Setting input path to specified directory: $input_path");
+
+ &report(7, "Change working directory to input path.");
+ chdir $input_path;
+
+ return $input_path;
+ }
+
+ ##### Getting document name, suffix and path
+ ($doc_base,$doc_path,$doc_suffix) = fileparse($texdoc, ('\.tex'));
+
+ ###### change working directory to input_path if set
+ # When the files' path (images, included documents, etc.) in your document is
+ # relative to another directory than the PASSED document's directory.
+ # This is useful when the calling application (e.g. LyX) generates a
+ # temporary
+ # TeX file and calls the tex2pdf with it instead of the original file.
+
+ @matches=&extract_tag_contents($texdoc, 'def\\\\input@path');
+ $input_path=$matches[0];
+
+ ## check if input_path is ok
+ if ($input_path) {
+ &report(7, "Found an input path in the latex document: $input_path");
+ if( &check_dir($input_path, 'The retrieved input@path seems not to be valid.', $NO)) {
+ &set_param_value('input_path', $input_path);
+ &report(7, "Change working directory to input path.");
+ chdir $input_path;
+ } else {
+ &abort ('I am lost.');
+ }
+ } else {
+ &report(4, "No input path in the latex document found.");
+ &report(7, "Resources are expected to be relative to document's location: $doc_path");
+ $input_path=$doc_path;
+ }
+
+ return $input_path;
+}
+
+#### set the working dir to the input path if the document has one and
+#### and determine the path for the result
+# parameter 1: main tex doc
+# parameter 2: absolute input path
+# return value: absolute path were the resulting pdf doc should be stored
+
+sub get_target_name {
+ my $texdoc = $_[0];
+ my $input_path=$_[1];
+
+ my $doc_base;
+ my $doc_path;
+ my $doc_suffix;
+ my $destination;
+ my $pdf_path;
+
+ ##### Getting document name, suffix and path
+ ($doc_base,$doc_path,$doc_suffix) = fileparse($texdoc, ('\.tex'));
+
+ ##### set the directory where the final pdf will be stored
+ $destination=¶m_value('destination');
+ $pdf_path=undef;
+
+ if ($destination eq 'custom' ) {
+ $pdf_path=¶m_value('custom_path');
+ } elsif ($destination eq 'input') {
+ $pdf_path=$input_path;
+ } else {
+ $pdf_path=$doc_path;
+ }
+
+ if( ! defined($pdf_path) or $pdf_path eq "" or ! &check_dir($pdf_path,
+ 'The specified destination directory for the final PDF documents is not valid.', $NO)) {
+ &report(7, "Using document's instead of destination path: $doc_path");
+ $pdf_path=$doc_path;
+ }
+
+ # make sure there is a slash at the end of the path
+ $pdf_path .= '/' if( ! ($pdf_path =~ m#/$#) );
+
+ return $pdf_path.$doc_base.'.pdf';
+}
+
+### generate hyperref parameters from given settings
+# parameter 1: main tex doc
+# return_value: result
+
+sub generate_hyperref_params {
+ my $texdoc = $_[0];
+ my $para;
+ my @params = ('pdftex');
+
+ ##### Set title and author from main LaTeX document or parameters
+ foreach my $info (('title', 'author')) {
+ my $value;
+
+ $value=¶m_value("$info");
+ if (! defined($value) ) {
+ my @matches=&extract_tag_contents($texdoc, $info);
+ $value= $matches[0];
+ if (! defined($value) ) {
+ &report(4, "\nWARNING: Could not identify document's $info correctly.");
+ &report(7, "Maybe you have used a LaTeX tag inside the $info which confuses me.\n",
+ "Adjust the $info of the LaTeX file in order to avoid the problem or\n",
+ "you could set the $info parameter manually.");
+ $value= ¶m_value("default_$info");
+ &report(7, "Using default-$info: $value");
+ }
+ }
+ if (! defined($value) or $value eq $NIL ) {
+ &report(7, "$info field set to $NIL - no value will be passed.");
+ } else {
+ &report(7, "Document's $info: $value");
+ push(@params, "pdf$info={$value}");
+ }
+ }
+
+ $para=¶m_value('paper');
+ if ( $para ne $NIL ) { push(@params, $para); }
+
+ $para=¶m_value('link_toc_page');
+ if ( $para eq $YES ) { push(@params, 'linktocpage'); }
+
+ $para=¶m_value('colorlinks');
+ if ( $para ne $NIL ) {
+ $para= $para eq $YES ? 'true' : 'false';
+ push(@params, "colorlinks=$para");
+ }
+
+ if ( $para ne 'false' ) {
+ foreach (('linkcolor', 'pagecolor', 'urlcolor', 'citecolor')) {
+ $para=¶m_value($_);
+ if ( $para ne $NIL ) { push(@params, "$_={$para}"); }
+ }
+ }
+
+ $para=¶m_value('hyperref_args');
+ if(defined($para) and $para ne "" and $para ne $NIL) {
+ push(@params, $para);
+ }
+
+ return @params;
+}
+
+#### Prepare the main document and all referenced ones for the generation
+#### of the PDF document (including referenced images)
+# parameter 1: top level tex document
+# parameter 2: parameter list of hyperref parameters
+
+sub prepare_documents {
+ my ($main_tex_doc, $input_path, @hyperref_params) = @_;
+ @REF_DOCS=();
+
+ ## get a name for the tmp tex file
+ my $main_tmp_doc = &reserve_tmp_texname($main_tex_doc, $input_path);
+
+ ## Get the list of imported files from the tex file
+ &get_file_list($main_tex_doc);
+
+ ## remove main file from list (first element; needs special handling)
+ shift @REF_DOCS;
+
+ ## tell user about the identified refereneced docs
+ if ( @REF_DOCS > 0 ) {
+ &report(7, "\nFound the following referenced TeX files:");
+ foreach my $file (@REF_DOCS) {
+ &report(7, ">>>>> $file");
+ }
+ } else {
+ &report(7, "\nFound no referenced TeX files.");
+ }
+
+ ##### Generate adjusted temp tex files and convert all their images
+ ## main doc
+ &report(6, "\nGenerating main temporary LaTeX document: $main_tmp_doc");
+ &convert_tex2tmp($main_tex_doc, $main_tmp_doc, \@hyperref_params);
+ &convert_images($main_tex_doc);
+
+ ## referenced docs
+ foreach my $file (@REF_DOCS) {
+ my $tmp_file = &reserve_tmp_texname($file);
+
+ ### Insert pdf conversation tags in tex file and write it to tmp_file
+ &report(7, "\nGenerating temporary LaTeX document: $tmp_file");
+ &convert_tex2tmp($file, $tmp_file, undef);
+ &convert_images($file);
+ }
+
+ return $main_tmp_doc;
+}
+
+##### Generate the final PDF document
+# parameter 1: filename of the source LaTeX document (with extension)
+
+sub generate_pdf_doc {
+ my $source = $_[0];
+ my $runno=1;
+ my $rerun=$TRUE;
+ my $doc;
+ my $pdf_doc;
+ my $base;
+ my $path;
+ my $suffix;
+
+ my $max_run_no= ¶m_value('maxrun');
+ my $min_run_no= ¶m_value('minrun');
+ my $log_dir= ¶m_value('logdir');
+ $log_dir .= '/' if( ! ($log_dir =~ m#/$#) );
+ my $makeindex_options=¶m_value('makeindex_opts');
+
+ # setting the log files for the output of pdflatex, bibtex, gloss,
+ # thumbpdf, ppower and authorindex
+ my $pdflog_base = $log_dir."pdflatex-$$-";
+ my $bibtex_log = $log_dir."bibtex-$$.log";
+ my $gloss_log = $log_dir."gloss-$$.log";
+ my $thumbpdf_log = $log_dir."thumbpdf-$$.log";
+ my $ppower_log = $log_dir."ppower-$$.log";
+ my $authorindex_log = $log_dir."authorindex-$$.log";
+
+ ##### Getting document name, suffix and path
+ ($base,$path,$suffix) = fileparse($source, ('\.tex'));
+ $doc = $path.$base;
+ $pdf_doc = $base.'.pdf';
+
+ ### run pdflatex until no more errors are reported (max MAXRUNNO)
+ while ( $rerun and $runno <= $max_run_no )
+ {
+ &report(6, "\n************ Pdflatex run no. $runno *************");
+ if ( &run_pdflatex($doc, $pdflog_base.$runno.'.log') == $TRUE
+ and ( $min_run_no <= $runno )) {
+ # no errors detected and min. no. of runs are done
+ $rerun=$FALSE;
+ } else {
+ # errors appeared or max run no. has not been reached
+ $rerun=$TRUE;
+ }
+
+ ### Execute BibTeX after first run if set (and required)
+ if ( $runno == 1 and ¶m_value('bibtex') ne $NO ) {
+ &report(6, "\n****************** BibTeX handling ***********************");
+ &handle_bibtex($doc, $bibtex_log);
+ }
+
+ ### Execute BibTeX on file.gls after first run if set (and required)
+ if ( $runno == 1 and ¶m_value('gloss') ne $NO ) {
+ &report(6, "\n****************** Gloss handling ***********************");
+ &handle_gloss($doc, $gloss_log);
+ }
+
+ ### generated index file exists
+ if ( $runno == 1 and -f $doc.'.idx' and ¶m_value('force_index') ne $NO ) {
+ if( !defined($makeindex_options) or $makeindex_options eq $NIL ) {
+ $makeindex_options = "";
+ }
+ &report(6, "\n****************** Extra index generation ***************");
+ &report(7, "Document seems to have an index. Generating ...\n");
+ &system_command("makeindex $makeindex_options $doc.idx", $FALSE, 8,
+ "makeindex failed.\nI will continue, "
+ ."but maybe there will not be an index in the PDF doc.");
+ }
+
+ $runno += 1;
+ }
+
+ $rerun = $FALSE;
+
+ ### if the authorindex option is switched on then run authorindex
+ if ( ¶m_value('authorindex') eq $YES ) {
+ &report(6, "\n****************** authorindex generation *****************");
+ &run_authorindex($doc, $authorindex_log);
+ }
+
+ ### generated index file exists
+ if ( -f $doc.'.idx' and ¶m_value('force_index') ne $NO ) {
+ if( !defined($makeindex_options) or $makeindex_options eq $NIL ) {
+ $makeindex_options = "";
+ }
+ &report(6, "\n****************** Extra index generation ***************");
+ &report(7, "Document seems to have an index. Generating ...\n");
+ &system_command("makeindex $makeindex_options $doc.idx", $FALSE, 8,
+ "makeindex failed.\nI will continue, "
+ ."but maybe there will not be an index in the PDF doc.");
+ $rerun=$TRUE;
+ }
+
+ ### if the thumbpdf option is switched on then make thumbnails
+ if ( ¶m_value('thumbpdf') eq $YES ) {
+ &report(6, "\n****************** Thumbnail generation *****************");
+ &run_thumbpdf($doc, $thumbpdf_log);
+ $rerun=$TRUE;
+ }
+
+ ### One final pdflatex run if requested
+ if ( $rerun ) {
+ &report(6, "\n************ One final pdflatex run no. $runno *************");
+ &run_pdflatex($doc, $pdflog_base.$runno.'.log');
+ }
+
+ ### if the ppower option is switched on then run ppower
+ if ( ¶m_value('ppower') eq $YES ) {
+ &report(6, "\n****************** ppower postprocess *****************");
+ &run_ppower($doc, $ppower_log);
+ }
+
+ if ( ! -f $pdf_doc ) {
+ &abort("\nThe new PDF file could not be generated: ".$pdf_doc);
+ }
+
+ return $pdf_doc;
+}
+
+################## Lift off !!!! (main part) ##################
+
+my $texdoc;
+my $doc_argument;
+my $input_path;
+my $target_name;
+my @hyperref_params;
+my $new_pdf_doc;
+my $tmp_tex_doc;
+
+&report(5, "\nScript starts ($MYRELEASE)");
+
+##### read and analyse configuration and options and adjust basic variables
+##### accordingly
+##### write RC file on config request
+#### use the finished configuration to get all further settings before we
+#### actually start doing something
+
+&report(5, "\nProcessing given parameters and arguments.");
+$doc_argument = &adjust_configuration;
+
+#### prepare the script to write some information to specified log files
+
+&report(5, "\nPreparing directory for log files.");
+&prepare_logdir;
+
+#### process the one and only argument (besides the options) which specifies
+#### which LaTeX document the user wants to translate to PDF
+#### a lyx file will be translated to LaTeX first
+
+&report(5, "\nAnalysing your document argument.");
+$texdoc = &process_doc_argument($doc_argument);
+
+#### we would like to get some more information from the actual
+#### main LaTeX document before we really start
+#### parse the document and try to get the info
+
+## translate hyperref settings to the actual package parameters
+
+&report(5, "\nSetting up parameters for hyperref.");
+@hyperref_params = &generate_hyperref_params($texdoc);
+
+## set the working dir to the input path if the document has one and
+
+&report(5, "\nProcessing input path for main tex document.");
+$input_path = &process_inputpath($texdoc);
+
+## determine the name for the result
+
+&report(5, "\nSetting the correct name for the result.");
+$target_name = &get_target_name($texdoc, $input_path);
+
+## as much as possible is prepared in advance at this point
+## so hopefully we will succeed in generating the PDF document
+
+##### real work starts NOW
+
+##### Generate adjusted temp tex files and convert all their images
+
+&report(5, "\nPreparing all documents and images.");
+$tmp_tex_doc = &prepare_documents($texdoc, $input_path, @hyperref_params);
+
+##### Generate the final PDF document
+
+&report(5, "\nProcessing the actual generation of the PDF document.");
+$new_pdf_doc = &generate_pdf_doc($tmp_tex_doc);
+
+##### Finalize
+move($new_pdf_doc, $target_name) or &abort("Could not move PDF file to final destination: $!");
+
+if ( ¶m_value('debug') eq $NO ) {
+ &clean_up;
+} else {
+ &print_temp_files;
+}
+
+&report(5, "\nThe new pdf file is: $target_name\n");
+