From 5ac5cca5eec65f2b492169f01406f6954c244142 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 27 Jun 2017 21:56:44 +0000 Subject: texdirflatten (27jun17) git-svn-id: svn://tug.org/texlive/trunk@44713 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/man/man1/texdirflatten.1 | 58 ++++-- .../texmf-dist/doc/man/man1/texdirflatten.man1.pdf | Bin 4842 -> 8363 bytes Master/texmf-dist/doc/support/texdirflatten/README | 55 +++++ .../texmf-dist/scripts/texdirflatten/texdirflatten | 226 ++++++++++++++------- Master/tlpkg/tlpsrc/texdirflatten.tlpsrc | 2 +- 5 files changed, 252 insertions(+), 89 deletions(-) create mode 100644 Master/texmf-dist/doc/support/texdirflatten/README (limited to 'Master') diff --git a/Master/texmf-dist/doc/man/man1/texdirflatten.1 b/Master/texmf-dist/doc/man/man1/texdirflatten.1 index 0da2a4fa74f..2e76412bfb9 100644 --- a/Master/texmf-dist/doc/man/man1/texdirflatten.1 +++ b/Master/texmf-dist/doc/man/man1/texdirflatten.1 @@ -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 @@ files recursively, to collect together its components, such as 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 @@ and gathers it and all its components in the \f(CW\*(C`submit_01/\*(C'\fR direct .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 @@ Bug reports and patches are welcome. Cengiz Gunay 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. diff --git a/Master/texmf-dist/doc/man/man1/texdirflatten.man1.pdf b/Master/texmf-dist/doc/man/man1/texdirflatten.man1.pdf index 69bea837ba7..3de3cfe1c13 100644 Binary files a/Master/texmf-dist/doc/man/man1/texdirflatten.man1.pdf and b/Master/texmf-dist/doc/man/man1/texdirflatten.man1.pdf differ diff --git a/Master/texmf-dist/doc/support/texdirflatten/README b/Master/texmf-dist/doc/support/texdirflatten/README new file mode 100644 index 00000000000..5705aa21a91 --- /dev/null +++ b/Master/texmf-dist/doc/support/texdirflatten/README @@ -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 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. + diff --git a/Master/texmf-dist/scripts/texdirflatten/texdirflatten b/Master/texmf-dist/scripts/texdirflatten/texdirflatten index c43b489f18e..f67adc77dc6 100755 --- a/Master/texmf-dist/scripts/texdirflatten/texdirflatten +++ b/Master/texmf-dist/scripts/texdirflatten/texdirflatten @@ -1,4 +1,9 @@ -#! /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 @@ -9,7 +14,7 @@ single output directory -- i.e., flattens its hierarchy. =head1 SYNOPSIS -texdirflatten -f input.tex [-o outputdir] +texdirflatten [-1|--onetex] [-f|--file input.tex] [-o outputdir] [-?|--help] =head1 DESCRIPTION @@ -24,16 +29,25 @@ Run without parameters to see usage. =over -=item B<-f> I +=item B<--file>, B<-f> I Specifies input (La)TeX file. -=item B<-o> I +=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 Directory to collect all files. B 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. +=item B<--help>, B<-?> + +Show this manual page. + =back =head1 EXAMPLES @@ -48,6 +62,10 @@ and gathers it and all its components in the C directory: Please take backups before running this command. No warranties whatsoever provided. +You may need to run C on EPS files if you are using C: + + $ for i in *.eps; do epstopdf $i; done + =head1 BUGS Bug reports and patches are welcome. @@ -58,15 +76,13 @@ Cengiz Gunay users.sf.net> =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. =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 @@ package texdirflatten; 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 @@ my %texfiles; # 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 = + '(? 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,71 +150,70 @@ sub parseTeX { } 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); # 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 @@ sub parseTeX { } } $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 @@ sub popfile { 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 @@ sub replacebibs { $" = ','; # 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 @@ sub replacebibs { #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 @@ sub replacebibs { # 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"]); } } } diff --git a/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc b/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc index 98052766046..745e64e018f 100644 --- a/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc +++ b/Master/tlpkg/tlpsrc/texdirflatten.tlpsrc @@ -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}.* -- cgit v1.2.3