texlive[44713] trunk: texdirflatten (27jun17)
commits+karl at tug.org
commits+karl at tug.org
Tue Jun 27 23:56:44 CEST 2017
Revision: 44713
http://tug.org/svn/texlive?view=revision&revision=44713
Author: karl
Date: 2017-06-27 23:56:44 +0200 (Tue, 27 Jun 2017)
Log Message:
-----------
texdirflatten (27jun17)
Modified Paths:
--------------
trunk/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten
trunk/Master/texmf-dist/doc/man/man1/texdirflatten.1
trunk/Master/texmf-dist/doc/man/man1/texdirflatten.man1.pdf
trunk/Master/texmf-dist/scripts/texdirflatten/texdirflatten
trunk/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc
Added Paths:
-----------
trunk/Master/texmf-dist/doc/support/texdirflatten/
trunk/Master/texmf-dist/doc/support/texdirflatten/README
Modified: trunk/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten 2017-06-27 21:56:10 UTC (rev 44712)
+++ trunk/Build/source/texk/texlive/linked_scripts/texdirflatten/texdirflatten 2017-06-27 21:56:44 UTC (rev 44713)
@@ -1,5 +1,10 @@
-#! /usr/bin/perl
+#! /usr/bin/env perl
+# Use:
+# $ perldoc texdirflatten
+# to see embedded documentation. Alternatively, you can create manual
+# or HTML pages using pod2man and pod2html.
+
=pod
=head1 NAME
@@ -9,7 +14,7 @@
=head1 SYNOPSIS
-texdirflatten -f input.tex [-o outputdir]
+texdirflatten [-1|--onetex] [-f|--file input.tex] [-o outputdir] [-?|--help]
=head1 DESCRIPTION
@@ -24,16 +29,25 @@
=over
-=item B<-f> I<input.tex>
+=item B<--file>, B<-f> I<input.tex>
Specifies input (La)TeX file.
-=item B<-o> I<outputdir>
+=item B<--onetex>, B<-1>
+If specified, produces a single TeX file by expanding all \input and
+\include commands in place.
+
+=item B<--output>, B<-o> I<outputdir>
+
Directory to collect all files. B<texdirflatten> will copy each source
file, graphics and bibliography file to this directory. It will be
created if it is unexistent. If unspecified, it defaults to C<flat/>.
+=item B<--help>, B<-?>
+
+Show this manual page.
+
=back
=head1 EXAMPLES
@@ -48,6 +62,10 @@
Please take backups before running this command. No warranties
whatsoever provided.
+You may need to run C<epstopdf> on EPS files if you are using C<pdflatex>:
+
+ $ for i in *.eps; do epstopdf $i; done
+
=head1 BUGS
Bug reports and patches are welcome.
@@ -58,7 +76,7 @@
=head1 COPYRIGHT AND LICENSE
-Copyleft 2003-2009, Cengiz Gunay
+Copyleft 2003-2017, Cengiz Gunay
This library is free software; you may redistribute it and/or modify
it under the same terms as Perl itself.
@@ -65,8 +83,6 @@
=cut
-# $Id: texdirflatten,v 1.1 2009/04/17 14:15:39 cengiz Exp $
-
# TODO:
#
# - parse BIBINPUTS environment variable and search figures and such
@@ -77,10 +93,13 @@
use Getopt::Long qw(GetOptions);
use Pod::Usage;
use strict;
+use warnings;
+use re 'eval';
# Global
-my $outputdir = "flat";
-my $file;
+my $outputdir = "flat"; # Output directory
+my $file = ""; # File to read
+my $onetex = 0; # Indicates all input and include commands be expanded
my $help;
# parse helpers
@@ -88,35 +107,41 @@
# GetOpt::Long::
my $result = GetOptions ("output|o=s" => \$outputdir,
- "file|f=s" => \$file,
- "help|?" => \$help );
+ "onetex|1" => \$onetex,
+ "file|f=s" => \$file,
+ "help|?" => \$help );
+# regexp for none or an even number of backslashes (\):
+my $unescaped =
+ '(?<! \\\\)(?(?= \\\\) (?: \\\\\\\\)* )?';
-#print "help: $help, file: $file\n";
+# counter for files translated (like LyX does)
+$::filecount = 0;
+my $DEBUG = 1;
-#print "poop: " . popfile('slkjs/lkjlsjd/saa.abc');
-#{
-# print ;
-#}
+pod2usage( -verbose => 2 ) if ($help);
-pod2usage( -section => "SYNOPSIS") if ($file eq "" || $help);
+pod2usage( -section => "SYNOPSIS") if ($file eq "");
system "mkdir $outputdir" if (not -d $outputdir);
# start recursing
-parseTeX($file, "");
+parseTeX($file, "", popfile($file), 0);
sub parseTeX {
my $file = shift;
my $inputdir = shift;
+ my $outfile = "$outputdir/" . shift;
+ my $level = shift;
+ # Add a proper TeX suffix if it's missing
+ $outfile .= '.tex' if ! ($outfile =~ /\.tex\s*$/i );
+
my @flats;
my @longs;
my $popped;
open my $FILE, $file or die "Cannot find file to read $file\n";
- my $outfile = "$outputdir/" . popfile($file);
- open my $COPY, ">$outfile" or die "Cannot write file $outfile\n";
# Read to whole file first, and then scan for regexps
my $contents = "";
@@ -125,12 +150,20 @@
}
close $FILE;
+ ## First, remove comments so that input commands inside are ignored.
+ # Also remove trailing newline and all whitespace at the beginning
+ # of the following line like TeX does it. Only for %'s following
+ # the proper backslash pattern.
+ $contents =~ s/( $unescaped )\%.*?\n[ \t]*/$1/gx;
+
# Look for graphics include statement
- if ($contents =~ /\\input\@path{{([^}]*)}}/) {
+ if ($contents =~ /\\input\@path\{\{([^}]*)\}\}/) {
$inputdir = $1;
print "Found input directory: $inputdir\n";
}
+ print "Parsing '$file' in directory '$inputdir'\n";
+
# Default value
#$inputdir = './' if (-z $inputdir);
@@ -137,59 +170,50 @@
# three cases: graphics, inputs and bibs
# an \includegraphics statement
- @flats = ();
- @longs = ();
+ @::flats = ();
+ @::longs = ();
+ #$::popped = "";
- $contents =~
- s/\\includegraphics(\[[^\]]*\])?\{([^}]*)\}/"\\includegraphics" . $1 .
- "{" . ($popped = popfile($2) and push @longs, $2 and push @flats,$popped and $popped) . "}"/egm;
+ $contents =~
+ s/\\includegraphics(\[[^\]]*\])?\{([^}]*)\}
+ (?{ $::popped = flattenfilename($2);
+ push @::longs, $2; push @::flats, $::popped })
+ /\\includegraphics$1\{$::popped\}/gmx;
- if ($#flats > -1) {
+ if ($#::flats > -1) {
my ($long, $flat);
- foreach $long (@longs) {
- $flat = shift @flats;
- print "Found graphics: '$long'\n";
+ foreach $long (@::longs) {
+ $flat = shift @::flats;
# convert LyX directory dots
$long =~ s/\\lyxdot /./g;
+ $flat =~ s/\\lyxdot /./g;
- my $epsfile = $inputdir . $long;
+ print "Looking for graphics: '$long'\n";
- if (system("cp $epsfile.eps $outputdir/$flat.eps") != 0) {
- print "Cannot find $epsfile.eps!\n";
- # if from figures dir, copy the EPS file as well
- if ($long =~ /figures\//) {
- $epsfile = $inputdir . $long;
- } else {
- $epsfile = $inputdir . '../figures/' . $long;
- }
+ my @exts = ("", ".eps", ".pdf", ".pstex");
+ my @dirs = ("", "$inputdir", $inputdir . '../figures/');
- if (system("cp $epsfile.eps $outputdir/$flat.eps") != 0) {
- print "Cannot find $epsfile.eps!\n";
- if (system("cp $epsfile.pstex $outputdir/$flat.eps") != 0) {
- die "Cannot find figure file '$epsfile'";
- } else {
- print "Found: '$epsfile.pstex'\n";
- }
- }
- } else {
- print "Found: '$epsfile.pstex'\n";
- }
+ seekfile($long, $flat, ["", ".eps", ".pdf", ".pstex"],
+ ["", "$inputdir", $inputdir . '../figures/']);
}
- my $long = $2;
-
}
+ # Must do bibs before input commands because, when expanded, they
+ # add new bibs inside.
+ replacebibs(\$contents, $inputdir);
+
# an \input or \include statement
@flats = ();
@longs = ();
- $contents =~
- s/\\(input|include){([^}]*)}/"\\${1}{" .
- ($popped = popfile($2) and push @longs, $2 and push @flats,$popped and $popped) . "}"/egm;
+ $contents =~
+ s/\\(input|include)\{([^}]*)\}/"\\${1}\{" .
+ ($popped = flattenfilename($2) and push @longs, $2 and push @flats,$popped and $popped)
+ . "\}"/egm;
- if ($#flats > 0) {
+ if ($#flats > -1) {
#print "Found " . scalar @longs . " items on line: '@flats'.\n";
my ($long, $flat);
@@ -208,24 +232,60 @@
}
}
$texfiles{$flat} = $long;
- parseTeX($long, $inputdir); #later
-
+ my $newcontents = parseTeX($long, basedir($long), $flat, $level + 1); #later
+ if ( $onetex ) {
+ # If specified, expand inclusion directives
+ die "Failed to find input/include to expand for '$flat'!\n"
+ if (! ( $contents =~
+ s/\\(input|include) \{ \Q$flat\E \}
+ (?{ print "===Found \\$1\{$flat\} to expand.\n" if $DEBUG; })
+ / ($1 eq 'include' ? "\\clearpage\n" : '') . "$newcontents"/gxem ) );
+ }
}
}
}
- replacebibs(\$contents, $inputdir);
#print "Writing to \"$outfile\"\n" .
# "----------------------------------------\n" .
# "$contents\n" .
# "----------------------------------------\n";
- # write to flat copy
- print $COPY $contents;
+ if (! $onetex || $level == 0) { # do output at zero recurse level
+ # open flat output file
+ open my $COPY, ">$outfile" or die "Cannot write file $outfile\n";
+ # write to flat copy
+ print $COPY $contents;
- close $COPY;
+ close $COPY;
+ } else {
+ return $contents;
+ }
+}
+# Look for file to copy
+sub seekfile {
+ my ($file, $dest, $exts, $dirs) = @_;
+ my @exts = @$exts;
+ my @dirs = @$dirs;
+
+ OUT: foreach my $dir (@dirs) {
+ foreach my $ext (@exts) {
+ my $tryfile = "$dir$file$ext";
+ if (-r $tryfile) {
+ # add the extension to $dest only if it hasn't any dots
+ my $dext = '';
+ $dext = $ext if (! $dest =~ /\./);
+
+ if (system("cp $tryfile $outputdir/$dest$dext") != 0) {
+ die "Cannot copy $tryfile!\n";
+ }
+ # If we found it, then get out of the loop
+ print "Found: '$tryfile'\n";
+ last OUT;
+ }
+ }
+ }
}
# Return everything after the last /
@@ -238,6 +298,35 @@
pop @a;
}
+# Make a new file by flattening directory names
+sub flattenfilename {
+ local $_ = shift;
+
+ # convert slashes to pluses, dots to Xs
+ tr|/|+|;
+ tr|\.|X|;
+
+ # add a unique number at the beginning so files don't start with a
+ # dot
+ $_ = sprintf("%03d_", ++$::filecount) . "$_";
+
+ print "===Flattened file to '$_'\n" if $DEBUG;
+
+ return $_;
+}
+
+sub basedir {
+ my $file = shift (@_);
+
+ my @a = split /\//, $file;
+
+ #print "Popping $file... split: @a ($#a), pop: " . pop(@a) . "\n";
+ pop @a; # remove file part
+ my $basedir = join('/', @a); # combine the rest with /'s
+ $basedir .= '/' if (! $basedir =~ /^$/); # add a trailing / if not empty
+ $basedir;
+}
+
# get the bibliography files
sub replacebibs {
my ($contentsref, $inputdir) = @_;
@@ -253,13 +342,13 @@
$" = ','; # set list item separator
# search for \bibliography statements
$$contentsref =~
- s/\\bibliography(\[[^\]]*\])? {
+ s/\\bibliography(\[[^\]]*\])? {
(?{ @::refs = (); #print "Found bibliography!\n"; #initialize ref list
}) (?: \s* ([^}, ]+)(?=[,}]),?
(?{ # for each word do:
#local (@_flats, @_longs, @_refs);
#print "Word: \"$+\", ";
- $popped = popfile($+); push @::longs, $+;
+ $popped = flattenfilename($+); push @::longs, $+;
push @::flats,$popped; push @::refs, $popped;
}) )+ \s* }
(?{ #print "\n+++ $#::flats; $#::refs; $#::longs\n";
@@ -270,7 +359,7 @@
#print "\n*** $#::flats; $#::refs; $#::longs\n";
$" = ' '; # restore list item separator
- if ($#::flats > 0) {
+ if ($#::flats > -1) {
#print "Found " . scalar @::longs . " items on line: '@::flats'.\n";
my ($long, $flat);
@@ -283,11 +372,8 @@
# convert LyX directory dots
$long =~ s/\\lyxdot /./g;
- my $bibfile = $inputdir . $long;
-
- if (system("cp $bibfile.bib $outputdir/$flat.bib") != 0) {
- die "Cannot find $bibfile.bib!\n";
- }
+ seekfile($long, "$flat.bib", [".bib"],
+ ["", "$inputdir"]);
}
}
}
Modified: trunk/Master/texmf-dist/doc/man/man1/texdirflatten.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/texdirflatten.1 2017-06-27 21:56:10 UTC (rev 44712)
+++ trunk/Master/texmf-dist/doc/man/man1/texdirflatten.1 2017-06-27 21:56:44 UTC (rev 44713)
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.1801 (Pod::Simple 3.05)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -38,6 +38,8 @@
. ds PI \(*p
. ds L" ``
. ds R" ''
+. ds C`
+. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
@@ -48,17 +50,24 @@
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
-.ie \nF \{\
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
..
-. nr % 0
-. rr F
-.\}
-.el \{\
-. de IX
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{
+. if \nF \{
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
+. if !\nF==2 \{
+. nr % 0
+. nr F 2
+. \}
+. \}
.\}
+.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -124,17 +133,17 @@
.\" ========================================================================
.\"
.IX Title "TEXDIRFLATTEN 1"
-.TH TEXDIRFLATTEN 1 "2009-04-17" "perl v5.10.0" "User Contributed Perl Documentation"
+.TH TEXDIRFLATTEN 1 "2017-06-26" "perl v5.22.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
-\&\fBtexdirflatten\fR \- Collects all components of a (La)TeX file in a
-single output directory \*(-- i.e., flattens its hierarchy.
+texdirflatten \- Collects all components of a (La)TeX file in a
+single output directory \-\- i.e., flattens its hierarchy.
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
-texdirflatten \-f input.tex [\-o outputdir]
+texdirflatten [\-1|\-\-onetex] [\-f|\-\-file input.tex] [\-o outputdir] [\-?|\-\-help]
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
It parses the source file, following its included children (La)TeX
@@ -142,14 +151,21 @@
graphics and BiBTeX bibliography files in different directories.
.SH "OPTIONS"
.IX Header "OPTIONS"
-.IP "\fB\-f\fR \fIinput.tex\fR" 4
-.IX Item "-f input.tex"
+.IP "\fB\-\-file\fR, \fB\-f\fR \fIinput.tex\fR" 4
+.IX Item "--file, -f input.tex"
Specifies input (La)TeX file.
-.IP "\fB\-o\fR \fIoutputdir\fR" 4
-.IX Item "-o outputdir"
+.IP "\fB\-\-onetex\fR, \fB\-1\fR" 4
+.IX Item "--onetex, -1"
+If specified, produces a single TeX file by expanding all \einput and
+\&\einclude commands in place.
+.IP "\fB\-\-output\fR, \fB\-o\fR \fIoutputdir\fR" 4
+.IX Item "--output, -o outputdir"
Directory to collect all files. \fBtexdirflatten\fR will copy each source
file, graphics and bibliography file to this directory. It will be
created if it is unexistent. If unspecified, it defaults to \f(CW\*(C`flat/\*(C'\fR.
+.IP "\fB\-\-help\fR, \fB\-?\fR" 4
+.IX Item "--help, -?"
+Show this manual page.
.SH "EXAMPLES"
.IX Header "EXAMPLES"
The following example scans \f(CW\*(C`manuscript.tex\*(C'\fR in the current directory
@@ -162,6 +178,12 @@
.IX Header "CAVEATS"
Please take backups before running this command. No warranties
whatsoever provided.
+.PP
+You may need to run \f(CW\*(C`epstopdf\*(C'\fR on \s-1EPS\s0 files if you are using \f(CW\*(C`pdflatex\*(C'\fR:
+.PP
+.Vb 1
+\& $ for i in *.eps; do epstopdf $i; done
+.Ve
.SH "BUGS"
.IX Header "BUGS"
Bug reports and patches are welcome.
@@ -170,7 +192,7 @@
Cengiz Gunay <cengique<\s-1AT\s0>users.sf.net>
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
-Copyleft 2003\-2009, Cengiz Gunay
+Copyleft 2003\-2017, Cengiz Gunay
.PP
This library is free software; you may redistribute it and/or modify
it under the same terms as Perl itself.
Modified: trunk/Master/texmf-dist/doc/man/man1/texdirflatten.man1.pdf
===================================================================
(Binary files differ)
Added: trunk/Master/texmf-dist/doc/support/texdirflatten/README
===================================================================
--- trunk/Master/texmf-dist/doc/support/texdirflatten/README (rev 0)
+++ trunk/Master/texmf-dist/doc/support/texdirflatten/README 2017-06-27 21:56:44 UTC (rev 44713)
@@ -0,0 +1,55 @@
+NAME
+ texdirflatten - Collects all components of a (La)TeX file in a single
+ output directory -- i.e., flattens its hierarchy.
+
+SYNOPSIS
+ texdirflatten [-1|--onetex] [-f|--file input.tex] [-o outputdir]
+ [-?|--help]
+
+DESCRIPTION
+ It parses the source file, following its included children (La)TeX files
+ recursively, to collect together its components, such as graphics and
+ BiBTeX bibliography files in different directories.
+
+OPTIONS
+ --file, -f *input.tex*
+ Specifies input (La)TeX file.
+
+ --onetex, -1
+ If specified, produces a single TeX file by expanding all \input and
+ \include commands in place.
+
+ --output, -o *outputdir*
+ Directory to collect all files. texdirflatten will copy each source
+ file, graphics and bibliography file to this directory. It will be
+ created if it is unexistent. If unspecified, it defaults to "flat/".
+
+ --help, -?
+ Show this manual page.
+
+EXAMPLES
+ The following example scans "manuscript.tex" in the current directory
+ and gathers it and all its components in the "submit_01/" directory:
+
+ $ texdirflatten -f manuscript.tex -o submit_01
+
+CAVEATS
+ Please take backups before running this command. No warranties
+ whatsoever provided.
+
+ You may need to run "epstopdf" on EPS files if you are using "pdflatex":
+
+ $ for i in *.eps; do epstopdf $i; done
+
+BUGS
+ Bug reports and patches are welcome.
+
+AUTHOR
+ Cengiz Gunay <cengique<AT>users.sf.net>
+
+COPYRIGHT AND LICENSE
+ Copyleft 2003-2017, Cengiz Gunay
+
+ This library is free software; you may redistribute it and/or modify it
+ under the same terms as Perl itself.
+
Property changes on: trunk/Master/texmf-dist/doc/support/texdirflatten/README
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/texdirflatten/texdirflatten
===================================================================
--- trunk/Master/texmf-dist/scripts/texdirflatten/texdirflatten 2017-06-27 21:56:10 UTC (rev 44712)
+++ trunk/Master/texmf-dist/scripts/texdirflatten/texdirflatten 2017-06-27 21:56:44 UTC (rev 44713)
@@ -1,5 +1,10 @@
-#! /usr/bin/perl
+#! /usr/bin/env perl
+# Use:
+# $ perldoc texdirflatten
+# to see embedded documentation. Alternatively, you can create manual
+# or HTML pages using pod2man and pod2html.
+
=pod
=head1 NAME
@@ -9,7 +14,7 @@
=head1 SYNOPSIS
-texdirflatten -f input.tex [-o outputdir]
+texdirflatten [-1|--onetex] [-f|--file input.tex] [-o outputdir] [-?|--help]
=head1 DESCRIPTION
@@ -24,16 +29,25 @@
=over
-=item B<-f> I<input.tex>
+=item B<--file>, B<-f> I<input.tex>
Specifies input (La)TeX file.
-=item B<-o> I<outputdir>
+=item B<--onetex>, B<-1>
+If specified, produces a single TeX file by expanding all \input and
+\include commands in place.
+
+=item B<--output>, B<-o> I<outputdir>
+
Directory to collect all files. B<texdirflatten> will copy each source
file, graphics and bibliography file to this directory. It will be
created if it is unexistent. If unspecified, it defaults to C<flat/>.
+=item B<--help>, B<-?>
+
+Show this manual page.
+
=back
=head1 EXAMPLES
@@ -48,6 +62,10 @@
Please take backups before running this command. No warranties
whatsoever provided.
+You may need to run C<epstopdf> on EPS files if you are using C<pdflatex>:
+
+ $ for i in *.eps; do epstopdf $i; done
+
=head1 BUGS
Bug reports and patches are welcome.
@@ -58,7 +76,7 @@
=head1 COPYRIGHT AND LICENSE
-Copyleft 2003-2009, Cengiz Gunay
+Copyleft 2003-2017, Cengiz Gunay
This library is free software; you may redistribute it and/or modify
it under the same terms as Perl itself.
@@ -65,8 +83,6 @@
=cut
-# $Id: texdirflatten,v 1.1 2009/04/17 14:15:39 cengiz Exp $
-
# TODO:
#
# - parse BIBINPUTS environment variable and search figures and such
@@ -77,10 +93,13 @@
use Getopt::Long qw(GetOptions);
use Pod::Usage;
use strict;
+use warnings;
+use re 'eval';
# Global
-my $outputdir = "flat";
-my $file;
+my $outputdir = "flat"; # Output directory
+my $file = ""; # File to read
+my $onetex = 0; # Indicates all input and include commands be expanded
my $help;
# parse helpers
@@ -88,35 +107,41 @@
# GetOpt::Long::
my $result = GetOptions ("output|o=s" => \$outputdir,
- "file|f=s" => \$file,
- "help|?" => \$help );
+ "onetex|1" => \$onetex,
+ "file|f=s" => \$file,
+ "help|?" => \$help );
+# regexp for none or an even number of backslashes (\):
+my $unescaped =
+ '(?<! \\\\)(?(?= \\\\) (?: \\\\\\\\)* )?';
-#print "help: $help, file: $file\n";
+# counter for files translated (like LyX does)
+$::filecount = 0;
+my $DEBUG = 1;
-#print "poop: " . popfile('slkjs/lkjlsjd/saa.abc');
-#{
-# print ;
-#}
+pod2usage( -verbose => 2 ) if ($help);
-pod2usage( -section => "SYNOPSIS") if ($file eq "" || $help);
+pod2usage( -section => "SYNOPSIS") if ($file eq "");
system "mkdir $outputdir" if (not -d $outputdir);
# start recursing
-parseTeX($file, "");
+parseTeX($file, "", popfile($file), 0);
sub parseTeX {
my $file = shift;
my $inputdir = shift;
+ my $outfile = "$outputdir/" . shift;
+ my $level = shift;
+ # Add a proper TeX suffix if it's missing
+ $outfile .= '.tex' if ! ($outfile =~ /\.tex\s*$/i );
+
my @flats;
my @longs;
my $popped;
open my $FILE, $file or die "Cannot find file to read $file\n";
- my $outfile = "$outputdir/" . popfile($file);
- open my $COPY, ">$outfile" or die "Cannot write file $outfile\n";
# Read to whole file first, and then scan for regexps
my $contents = "";
@@ -125,12 +150,20 @@
}
close $FILE;
+ ## First, remove comments so that input commands inside are ignored.
+ # Also remove trailing newline and all whitespace at the beginning
+ # of the following line like TeX does it. Only for %'s following
+ # the proper backslash pattern.
+ $contents =~ s/( $unescaped )\%.*?\n[ \t]*/$1/gx;
+
# Look for graphics include statement
- if ($contents =~ /\\input\@path{{([^}]*)}}/) {
+ if ($contents =~ /\\input\@path\{\{([^}]*)\}\}/) {
$inputdir = $1;
print "Found input directory: $inputdir\n";
}
+ print "Parsing '$file' in directory '$inputdir'\n";
+
# Default value
#$inputdir = './' if (-z $inputdir);
@@ -137,59 +170,50 @@
# three cases: graphics, inputs and bibs
# an \includegraphics statement
- @flats = ();
- @longs = ();
+ @::flats = ();
+ @::longs = ();
+ #$::popped = "";
- $contents =~
- s/\\includegraphics(\[[^\]]*\])?\{([^}]*)\}/"\\includegraphics" . $1 .
- "{" . ($popped = popfile($2) and push @longs, $2 and push @flats,$popped and $popped) . "}"/egm;
+ $contents =~
+ s/\\includegraphics(\[[^\]]*\])?\{([^}]*)\}
+ (?{ $::popped = flattenfilename($2);
+ push @::longs, $2; push @::flats, $::popped })
+ /\\includegraphics$1\{$::popped\}/gmx;
- if ($#flats > -1) {
+ if ($#::flats > -1) {
my ($long, $flat);
- foreach $long (@longs) {
- $flat = shift @flats;
- print "Found graphics: '$long'\n";
+ foreach $long (@::longs) {
+ $flat = shift @::flats;
# convert LyX directory dots
$long =~ s/\\lyxdot /./g;
+ $flat =~ s/\\lyxdot /./g;
- my $epsfile = $inputdir . $long;
+ print "Looking for graphics: '$long'\n";
- if (system("cp $epsfile.eps $outputdir/$flat.eps") != 0) {
- print "Cannot find $epsfile.eps!\n";
- # if from figures dir, copy the EPS file as well
- if ($long =~ /figures\//) {
- $epsfile = $inputdir . $long;
- } else {
- $epsfile = $inputdir . '../figures/' . $long;
- }
+ my @exts = ("", ".eps", ".pdf", ".pstex");
+ my @dirs = ("", "$inputdir", $inputdir . '../figures/');
- if (system("cp $epsfile.eps $outputdir/$flat.eps") != 0) {
- print "Cannot find $epsfile.eps!\n";
- if (system("cp $epsfile.pstex $outputdir/$flat.eps") != 0) {
- die "Cannot find figure file '$epsfile'";
- } else {
- print "Found: '$epsfile.pstex'\n";
- }
- }
- } else {
- print "Found: '$epsfile.pstex'\n";
- }
+ seekfile($long, $flat, ["", ".eps", ".pdf", ".pstex"],
+ ["", "$inputdir", $inputdir . '../figures/']);
}
- my $long = $2;
-
}
+ # Must do bibs before input commands because, when expanded, they
+ # add new bibs inside.
+ replacebibs(\$contents, $inputdir);
+
# an \input or \include statement
@flats = ();
@longs = ();
- $contents =~
- s/\\(input|include){([^}]*)}/"\\${1}{" .
- ($popped = popfile($2) and push @longs, $2 and push @flats,$popped and $popped) . "}"/egm;
+ $contents =~
+ s/\\(input|include)\{([^}]*)\}/"\\${1}\{" .
+ ($popped = flattenfilename($2) and push @longs, $2 and push @flats,$popped and $popped)
+ . "\}"/egm;
- if ($#flats > 0) {
+ if ($#flats > -1) {
#print "Found " . scalar @longs . " items on line: '@flats'.\n";
my ($long, $flat);
@@ -208,24 +232,60 @@
}
}
$texfiles{$flat} = $long;
- parseTeX($long, $inputdir); #later
-
+ my $newcontents = parseTeX($long, basedir($long), $flat, $level + 1); #later
+ if ( $onetex ) {
+ # If specified, expand inclusion directives
+ die "Failed to find input/include to expand for '$flat'!\n"
+ if (! ( $contents =~
+ s/\\(input|include) \{ \Q$flat\E \}
+ (?{ print "===Found \\$1\{$flat\} to expand.\n" if $DEBUG; })
+ / ($1 eq 'include' ? "\\clearpage\n" : '') . "$newcontents"/gxem ) );
+ }
}
}
}
- replacebibs(\$contents, $inputdir);
#print "Writing to \"$outfile\"\n" .
# "----------------------------------------\n" .
# "$contents\n" .
# "----------------------------------------\n";
- # write to flat copy
- print $COPY $contents;
+ if (! $onetex || $level == 0) { # do output at zero recurse level
+ # open flat output file
+ open my $COPY, ">$outfile" or die "Cannot write file $outfile\n";
+ # write to flat copy
+ print $COPY $contents;
- close $COPY;
+ close $COPY;
+ } else {
+ return $contents;
+ }
+}
+# Look for file to copy
+sub seekfile {
+ my ($file, $dest, $exts, $dirs) = @_;
+ my @exts = @$exts;
+ my @dirs = @$dirs;
+
+ OUT: foreach my $dir (@dirs) {
+ foreach my $ext (@exts) {
+ my $tryfile = "$dir$file$ext";
+ if (-r $tryfile) {
+ # add the extension to $dest only if it hasn't any dots
+ my $dext = '';
+ $dext = $ext if (! $dest =~ /\./);
+
+ if (system("cp $tryfile $outputdir/$dest$dext") != 0) {
+ die "Cannot copy $tryfile!\n";
+ }
+ # If we found it, then get out of the loop
+ print "Found: '$tryfile'\n";
+ last OUT;
+ }
+ }
+ }
}
# Return everything after the last /
@@ -238,6 +298,35 @@
pop @a;
}
+# Make a new file by flattening directory names
+sub flattenfilename {
+ local $_ = shift;
+
+ # convert slashes to pluses, dots to Xs
+ tr|/|+|;
+ tr|\.|X|;
+
+ # add a unique number at the beginning so files don't start with a
+ # dot
+ $_ = sprintf("%03d_", ++$::filecount) . "$_";
+
+ print "===Flattened file to '$_'\n" if $DEBUG;
+
+ return $_;
+}
+
+sub basedir {
+ my $file = shift (@_);
+
+ my @a = split /\//, $file;
+
+ #print "Popping $file... split: @a ($#a), pop: " . pop(@a) . "\n";
+ pop @a; # remove file part
+ my $basedir = join('/', @a); # combine the rest with /'s
+ $basedir .= '/' if (! $basedir =~ /^$/); # add a trailing / if not empty
+ $basedir;
+}
+
# get the bibliography files
sub replacebibs {
my ($contentsref, $inputdir) = @_;
@@ -253,13 +342,13 @@
$" = ','; # set list item separator
# search for \bibliography statements
$$contentsref =~
- s/\\bibliography(\[[^\]]*\])? {
+ s/\\bibliography(\[[^\]]*\])? {
(?{ @::refs = (); #print "Found bibliography!\n"; #initialize ref list
}) (?: \s* ([^}, ]+)(?=[,}]),?
(?{ # for each word do:
#local (@_flats, @_longs, @_refs);
#print "Word: \"$+\", ";
- $popped = popfile($+); push @::longs, $+;
+ $popped = flattenfilename($+); push @::longs, $+;
push @::flats,$popped; push @::refs, $popped;
}) )+ \s* }
(?{ #print "\n+++ $#::flats; $#::refs; $#::longs\n";
@@ -270,7 +359,7 @@
#print "\n*** $#::flats; $#::refs; $#::longs\n";
$" = ' '; # restore list item separator
- if ($#::flats > 0) {
+ if ($#::flats > -1) {
#print "Found " . scalar @::longs . " items on line: '@::flats'.\n";
my ($long, $flat);
@@ -283,11 +372,8 @@
# convert LyX directory dots
$long =~ s/\\lyxdot /./g;
- my $bibfile = $inputdir . $long;
-
- if (system("cp $bibfile.bib $outputdir/$flat.bib") != 0) {
- die "Cannot find $bibfile.bib!\n";
- }
+ seekfile($long, "$flat.bib", [".bib"],
+ ["", "$inputdir"]);
}
}
}
Modified: trunk/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc 2017-06-27 21:56:10 UTC (rev 44712)
+++ trunk/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc 2017-06-27 21:56:44 UTC (rev 44713)
@@ -1,2 +1,2 @@
binpattern f bin/${ARCH}/${PKGNAME}
-docpattern f texmf-dist/doc/man/man1/${PKGNAME}.*
+docpattern +f texmf-dist/doc/man/man1/${PKGNAME}.*
More information about the tex-live-commits
mailing list