#!/usr/local/bin/perl
# Accompanies LaTeX2HTML Version 0.6.4
# Rewrite of texexpand. Handles style files and \endinput at least
# approximately right.
# Copyright Robert Thau, MIT AI lab, 1993.
# Unlimited reproduction is permitted as long as this notice is preserved.
# Mon Nov 22 1993
# Modified by Franz Vojik to search
# for TeX-files in subdirectories of the given directories.
# Modified by Nikos Drakos to look for
# as well as .tex when processing input and include commands.
# Tue Nov 23
# Modified by Nikos Drakos to take an extra command line
# argument -save_styles which instructs it to save in the names
# of any style files or other included files.
# Tue Dec 7
# Modified by Nikos Drakos to ignore comments!
# Also modified so that \input and \include do not have to be in the
# beginning of a line. Text before or after such commands is preserved.
# Thu Dec 9
# Modified by Nikos Drakos to fix bug in the
# mechanism for ignoring comments!
# Wed Jan 5 1994
# Modified by Sebastian Rahtz
# to recognise the documentclass and usepackage commands of LaTeX2e
# Also, modified by Nikos Drakos to print messages to STDERR.
# Jan 27 1994 - Nikos Drakos - Modified to strip spaces out of $styles
# Jan 28 1994 - Maximilian Ott - added test that
# checks for %'s before inluding|inputing files in include_line (otherwise
# input|include statements in .sty files cause infinite loops)
# Feb 14 1994 - Nikos Drakos - Fixed bug in code for checking for %'s
# which caused \input and \include commands NOT to work!
# Also added support for \include'ing undelimited filenames.
# Mar 1 1994 - Sebastian Rahtz - Modified it to regard the main document style
# (eg book, report etc) as just another style that may have a corresponding
# perl translation module.
# June 11 1994 - Nikos Drakos - Special characters in names of style files
# used in regular expressions are now escaped (eg c++.sty) and now (20 June)
# are not escaped because this causes problems when reading other style files
# July 27 1994 - Nikos Drakos - Changed it so that the arguments of
# documentclass and usepackage are processed correctly without being lost.
# Also modified do_include to return success or failure. If there is a failure
# then the corrsponding style file is added back in the options lists.
# Also changed it TO AUTOMATICALLY EXCLUDE any .sty and any .cls files
@texinputs = (".");
foreach $dir (split(/:/,$ENV{'TEXE_INPUTS'})) { push (@texinputs, $dir); }
foreach $dir (split(/:/,$ENV{'TEXINPUTS'})) { push (@texinputs, $dir); }
$homeDir = (getpwuid($<))[7];
grep(s|^~/|$homeDir/|, @texinputs);
grep((m|^~([^/]+)/|) && ($homeDir = (getpwnam($1))[7]) && (s||$homeDir/|), @texinputs);
@dont_include = split(/:/,$ENV{'TEXE_DONT_INCLUDE'});
while ($ARGV[0] =~ /^-/ && (! ($ARGV[0] =~ /^--$/)))
{
$_ = shift;
if (/^-dont_include$/) { push(@dont_include, shift); }
elsif (/^-w$/) {} ### Compatibility hack.
elsif (/^-auto_exclude$/) { $auto_exclude++}
elsif (/^-save_styles$/) {$style_file = shift}
elsif (/^-debug$/) { $debug++; }
else { print STDERR "% --- WARNING: Unrecognized option: $_ \n"; }
}
if ($debug)
{
print STDERR "%TeX inputs are in:\n";
foreach $dir (@texinputs) { print STDERR "%--- $dir\n"; }
print STDERR "\n%Special names (not to be input or included):\n";
foreach $name (@dont_include) { print STDERR "%--- $name\n"; }
print STDERR "\n%Args:\n";
foreach $arg (@ARGV) { print STDERR "%--- $arg\n"; }
print "\n";
}
while (<>)
{
$comments = '';
s/(^%.*\n|([^\\])%.*\n)/do {$comments = $1;''}/eo;
if (/\\(input|include)\W/)
{
print STDERR ("%Found include at top-level: $_") if $debug;
&include_line ($_);
}
elsif (/(\\document(style|class)\s*\[)(.*)(\]\s*\{)(.*)}/) { local ($before, $styles, $after) = ($`.$1, $3, $4.$5."}".$'); $styles =~ s/\s//go; # Strip spaces
&should_include ($5 . ".sty");
&include_styles($before, $styles, $after, ".sty");
}
# Package files are more complicated. we need to textually include them,
# to get the definitions, but how do we process the options?
# for now, we'll just lose the options. sorry 'bout that.
#
elsif (/(\\usepackage.*\{)(.*)(\})/)
{
local ($before, $packages, $after) = ($`.$1, $2, $3.$');
print STDERR "%Found package(s): --- $packages \n" if $debug;
&include_styles($before, $packages, $after, ".sty");
}
else
{
print;
}
print "$comments";
}
sub include_styles
{
local ($before, $styles, $after, $ext) = @_;
local ($style, @styles, @print_styles, @inc_styles);
@styles = split(/,/, $styles);
print STDERR "%Found styles: --- $styles \n" if $debug;
foreach $style (@styles)
{
if (&should_include ($style . $ext)) { push (@inc_styles, $style); }
else { push (@print_styles, $style); }
}
foreach $style (@inc_styles) {
push (@print_styles, $style) unless &do_include ($style . $ext);
}
print $before . (join (',', @print_styles)) . $after;
}
sub include_line {
local ($_) = @_;
local ($filename, $found, $before, $after);
if (/\\input\s*\{([^}]*)\}/) {($filename,$before,$after) = ($1, $`, $') }
elsif (/\\input\s+(\S*)\s/) { ($filename,$before,$after) = ($1, $`, $') }
elsif (/\\include\s*\{([^}]*)\}/) {($filename,$before,$after) = ($1, $`, $') }
elsif (/\\include\s+(\S*)\s/) { ($filename,$before,$after) = ($1, $`, $') }
else { print STDERR "texexpand --- COULDN'T FIND FILENAME in $_" };
$filename =~ s/^\s*(\S*)\s*$/\1/;
print $_ unless ((! ($before =~ /\s*[%]+\s*/)) &&
$filename && &should_include($filename) &&
&do_include ($filename, $before,$after))
}
# Returns success or failure
sub do_include
{
local ($filename,$before,$after) = @_;
local ($fname);
if ($auto_exclude && ($filename =~ /\.(sty|cls)$/)) {
print STDERR "%--- ignoring $filename: $_\n" if $debug;
return(0);
}
print STDERR "%--- including $filename: $_\n" if $debug;
$found = 0;
if ($filename =~ "^/")
{
$fname = $filename; $found = 1;
}
else
{
DIR:foreach $dir (@texinputs)
{
$fname = join ('/', $dir, $filename);
print STDERR "%--- checking for $fname\n" if $debug;
if (&file_or_ext) { $found = 1; last DIR; }
# Check Subdirs of texinputs
else
{ opendir(SUBDIR,$dir); # open directory
while ($_=readdir(SUBDIR)) # read dir-entries
{ (/\./ || /\.\./) && (next); # do not check . and ..
{ $dname = join ('/', $dir, $_);
if (-d $dname ) # check subdirs
{ $fname = join ('/', $dname, $filename);
print STDERR "%--- checking for $fname\n" if $debug;
if (&file_or_ext) { $found = 1; last DIR; }
}
}
}
}
}
}
if (! $found)
{
print STDERR "texexpand --- COULDN'T FIND $filename!!!\n";
}
else
{
local (*incfile, $_);
if (!open (incfile, $fname))
{
print STDERR "texexpand --- COULDN'T OPEN $fname --- $! !!!\n"
}
else
{
local($comments);
print "$before";
while ()
{
$comments='';
s/(^%.*\n|([^\\])%.*\n)/do {$comments = $1;''}/eo;
last if /\\endinput/;
if (/\\(input|include)\W/) { &include_line ($_); }
else { print }
print $comments;
}
print "$after";
close (incfile);
}
}
$found;
}
sub should_include
{
local ($_) = @_;
# Recognize standard style options ...
print STDERR "% --- Checking $_ for standard style\n" if $debug;
#$_ = &escape_rx_chars($_);
s/.*\///; s/\.(sty|cls|tex)//; ### Get base name ...
print STDERR "% --- Checking $_ for special style\n" if $debug;
do {
open (STYLES, ">>$style_file") ||
print STDERR "Cannot open $style_file $!\n";
print STYLES "$_\n";
close(STYLES)
} if $style_file;
if (/^(twoside|twocolumn|titlepage|openbib|leqno|fleqn|\d+pt)\.sty$/)
{ return 0; }
local ($name) = $_;
return ((!grep (/^$name$/, @dont_include))
);
}
sub file_or_ext {
# Modifies $fname
# if $fname exists return success otherwise
# if $fname.tex exists, then bind $fname to $fname.tex and return success
# else fail
((-f $fname) || ( (-f "$fname.tex") ? $fname = "$fname.tex" : 0));
}
# When part of the input text contains special perl characters and the text
# is to be used as a pattern then these specials must be escaped.
sub escape_rx_chars {
local($_) = @_;
s/(\W)/\\$1/g;
$_;
}