* Made findLaTeXIncludes pure. Previously find-includes.pl looked
outside of the Nix store for the dependencies of the root source file, which is impure. That's why it needed the `builtins.currentTime' hack to force a rebuild. It also didn't work in a chroot. Now find-includes.pl only scans the source file at hand, and we use builtins.genericClosure to find all includes recursively. svn path=/nixpkgs/trunk/; revision=16414
This commit is contained in:
parent
3451ae1a64
commit
04cc6b721a
|
@ -10,7 +10,6 @@ rec {
|
||||||
, extraFiles ? []
|
, extraFiles ? []
|
||||||
, compressBlanksInIndex ? true
|
, compressBlanksInIndex ? true
|
||||||
, packages ? []
|
, packages ? []
|
||||||
, searchRelativeTo ? dirOf (toString rootFile) # !!! duplication
|
|
||||||
, copySources ? false
|
, copySources ? false
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
@ -25,31 +24,57 @@ rec {
|
||||||
inherit rootFile generatePDF generatePS extraFiles
|
inherit rootFile generatePDF generatePS extraFiles
|
||||||
compressBlanksInIndex copySources;
|
compressBlanksInIndex copySources;
|
||||||
|
|
||||||
includes = import (findLaTeXIncludes {inherit rootFile searchRelativeTo;});
|
includes = map (x: [x.key (baseNameOf (toString x.key))])
|
||||||
|
(findLaTeXIncludes {inherit rootFile;});
|
||||||
|
|
||||||
buildInputs = [ pkgs.tetex pkgs.perl ] ++ packages;
|
buildInputs = [ pkgs.tetex pkgs.perl ] ++ packages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the closure of the "dependencies" of a LaTeX source file.
|
||||||
|
# Dependencies are other LaTeX source files (e.g. included using
|
||||||
|
# \input{}), images (e.g. \includegraphics{}), bibliographies, and
|
||||||
|
# so on.
|
||||||
findLaTeXIncludes =
|
findLaTeXIncludes =
|
||||||
{ rootFile
|
{ rootFile
|
||||||
, searchRelativeTo ? dirOf (toString rootFile)
|
|
||||||
}:
|
}:
|
||||||
|
|
||||||
pkgs.stdenv.mkDerivation {
|
builtins.genericClosure {
|
||||||
name = "latex-includes";
|
startSet = [{key = rootFile;}];
|
||||||
|
|
||||||
|
operator =
|
||||||
|
{key, ...}:
|
||||||
|
|
||||||
realBuilder = pkgs.perl + "/bin/perl";
|
let
|
||||||
args = [ ./find-includes.pl ];
|
|
||||||
|
|
||||||
rootFile = toString rootFile; # !!! hacky
|
trace = x: builtins.trace x x;
|
||||||
|
|
||||||
inherit searchRelativeTo;
|
# `find-includes.pl' returns the dependencies of the current
|
||||||
|
# source file (`key') as a list, e.g. [{type = "tex"; name =
|
||||||
|
# "introduction.tex";} {type = "img"; name = "example"}].
|
||||||
|
# The type denotes the kind of dependency, which determines
|
||||||
|
# what extensions we use to look for it.
|
||||||
|
deps = import (pkgs.runCommand "latex-includes"
|
||||||
|
{ src = trace key; }
|
||||||
|
"${pkgs.perl}/bin/perl ${./find-includes.pl}");
|
||||||
|
|
||||||
# Forces rebuilds.
|
# Look for the dependencies of `key', trying various
|
||||||
hack = builtins.currentTime;
|
# extensions determined by the type of each dependency.
|
||||||
|
# TODO: support a search path.
|
||||||
|
foundDeps = dep: xs:
|
||||||
|
let
|
||||||
|
exts =
|
||||||
|
if dep.type == "img" then [".pdf" ".png" ".ps" ".jpg"]
|
||||||
|
else if dep.type == "tex" then [".tex" ""]
|
||||||
|
else [""];
|
||||||
|
fn = pkgs.lib.findFirst (fn: builtins.pathExists fn) null
|
||||||
|
(map (ext: "${dirOf key}/${dep.name}${ext}") exts);
|
||||||
|
in if fn != null then [{key = fn;}] ++ xs
|
||||||
|
else builtins.trace "not found: ${dep.name}" xs;
|
||||||
|
|
||||||
|
in pkgs.lib.fold foundDeps [] deps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
dot2pdf =
|
dot2pdf =
|
||||||
{ dotGraph
|
{ dotGraph
|
||||||
|
@ -158,7 +183,6 @@ rec {
|
||||||
inherit packages;
|
inherit packages;
|
||||||
generatePDF = false;
|
generatePDF = false;
|
||||||
generatePS = true;
|
generatePS = true;
|
||||||
searchRelativeTo = dirOf (toString body);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,7 +200,6 @@ rec {
|
||||||
inherit body preamble;
|
inherit body preamble;
|
||||||
};
|
};
|
||||||
inherit packages;
|
inherit packages;
|
||||||
searchRelativeTo = dirOf (toString body);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,102 +1,60 @@
|
||||||
use strict;
|
use strict;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
|
|
||||||
my $root = $ENV{"rootFile"};
|
my $src = $ENV{"src"};
|
||||||
my $out = $ENV{"out"};
|
my $out = $ENV{"out"};
|
||||||
my $path = $ENV{"searchRelativeTo"};
|
my $path = $ENV{"searchRelativeTo"};
|
||||||
my $store = $ENV{"NIX_STORE"};
|
|
||||||
|
|
||||||
open OUT, ">$out" or die;
|
open OUT, ">$out" or die;
|
||||||
print OUT "[\n";
|
print OUT "[\n";
|
||||||
|
|
||||||
my @workset = ();
|
open FILE, "< $src" or die;
|
||||||
my %doneset = ();
|
|
||||||
|
|
||||||
sub addToWorkSetExts {
|
sub addName {
|
||||||
my $base = shift;
|
my ($type, $name) = @_;
|
||||||
foreach my $ext (@_) {
|
print OUT "{ type = \"$type\"; name = \"$name\"; }\n";
|
||||||
push @workset, "$base$ext";
|
}
|
||||||
|
|
||||||
|
while (<FILE>) {
|
||||||
|
if (/\\input\{(.*)\}/) {
|
||||||
|
my $fn2 = $1;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "tex", "$fn2";
|
||||||
|
} elsif (/\\usepackage(\[.*\])?\{(.*)\}/) {
|
||||||
|
my $fn2 = $2;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "misc", "$fn2.sty";
|
||||||
|
} elsif (/\\documentclass(\[.*\])?\{(.*)\}/) {
|
||||||
|
my $fn2 = $2;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "misc", "$fn2.cls";
|
||||||
|
} elsif (/\\bibliographystyle\{(.*)\}/) {
|
||||||
|
my $fn2 = $1;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "misc", "$fn2.bst";
|
||||||
|
} elsif (/\\bibliography\{(.*)\}/) {
|
||||||
|
foreach my $bib (split /,/, $1) {
|
||||||
|
$bib =~ s/^\s+//; # remove leading / trailing whitespace
|
||||||
|
$bib =~ s/\s+$//;
|
||||||
|
addName "misc", "$bib.bib";
|
||||||
|
}
|
||||||
|
} elsif (/\\includegraphics(\[.*\])?\{(.*)\}/) {
|
||||||
|
my $fn2 = $2;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "img", "$fn2";
|
||||||
|
} elsif (/\\pgfdeclareimage(\[.*\])?\{.*\}\{(.*)\}/) {
|
||||||
|
my $fn2 = $2;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "img", "$fn2";
|
||||||
|
} elsif (/\\pgfimage(\[.*\])?\{(.*)\}/) {
|
||||||
|
my $fn2 = $2;
|
||||||
|
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
||||||
|
addName "img", "$fn2";
|
||||||
}
|
}
|
||||||
|
# !!! also support \usepackage
|
||||||
}
|
}
|
||||||
|
|
||||||
push @workset, $root;
|
close FILE;
|
||||||
|
|
||||||
while (scalar @workset > 0) {
|
|
||||||
|
|
||||||
my $fn = pop @workset;
|
|
||||||
next if (defined $doneset{$fn});
|
|
||||||
|
|
||||||
$doneset{$fn} = 1;
|
|
||||||
|
|
||||||
if (!-e "$fn") {
|
|
||||||
print STDERR "cannot access `$fn': $!\n" if !$!{ENOENT};
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
next unless -e "$fn";
|
|
||||||
|
|
||||||
|
|
||||||
# Print out the full path *and* its relative path to $root.
|
|
||||||
|
|
||||||
if (substr($fn, 0, length $path) eq $path) {
|
|
||||||
my $relFN = substr($fn, (length $path) + 1);
|
|
||||||
print OUT "$fn \"$relFN\"\n";
|
|
||||||
} else {
|
|
||||||
my $base = basename $fn;
|
|
||||||
my $x = substr($fn, 0, length($store) + 1);
|
|
||||||
if (substr($fn, 0, length($store) + 1) eq "$store/") {
|
|
||||||
$base = substr($base, 33);
|
|
||||||
}
|
|
||||||
print OUT "$fn \"$base\"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# If this is a TeX file, recursively find include in $fn.
|
|
||||||
next unless $fn =~ /.tex$/ or $fn =~ /.ltx$/;
|
|
||||||
open FILE, "< $fn" or die;
|
|
||||||
|
|
||||||
while (<FILE>) {
|
|
||||||
if (/\\input\{(.*)\}/) {
|
|
||||||
my $fn2 = $1;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
push @workset, "$path/$fn2.tex";
|
|
||||||
push @workset, "$path/$fn2";
|
|
||||||
} elsif (/\\usepackage(\[.*\])?\{(.*)\}/) {
|
|
||||||
my $fn2 = $2;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
push @workset, "$path/$fn2.sty";
|
|
||||||
} elsif (/\\documentclass(\[.*\])?\{(.*)\}/) {
|
|
||||||
my $fn2 = $2;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
push @workset, "$path/$fn2.cls";
|
|
||||||
} elsif (/\\bibliographystyle\{(.*)\}/) {
|
|
||||||
my $fn2 = $1;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
push @workset, "$path/$fn2.bst";
|
|
||||||
} elsif (/\\bibliography\{(.*)\}/) {
|
|
||||||
foreach my $bib (split /,/, $1) {
|
|
||||||
$bib =~ s/^\s+//; # remove leading / trailing whitespace
|
|
||||||
$bib =~ s/\s+$//;
|
|
||||||
push @workset, "$path/$bib.bib";
|
|
||||||
}
|
|
||||||
} elsif (/\\includegraphics(\[.*\])?\{(.*)\}/) {
|
|
||||||
my $fn2 = $2;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
addToWorkSetExts("$path/$fn2", ".pdf", ".png", ".ps", ".jpg");
|
|
||||||
} elsif (/\\pgfdeclareimage(\[.*\])?\{.*\}\{(.*)\}/) {
|
|
||||||
my $fn2 = $2;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
addToWorkSetExts("$path/$fn2", ".pdf", ".png", ".jpg");
|
|
||||||
} elsif (/\\pgfimage(\[.*\])?\{(.*)\}/) {
|
|
||||||
my $fn2 = $2;
|
|
||||||
die "absolute path! $fn2" if substr($fn2, 0, 1) eq "/";
|
|
||||||
addToWorkSetExts("$path/$fn2", ".pdf", ".png", ".jpg");
|
|
||||||
}
|
|
||||||
# !!! also support \usepackage
|
|
||||||
}
|
|
||||||
|
|
||||||
close FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
print OUT "]\n";
|
print OUT "]\n";
|
||||||
close OUT;
|
close OUT;
|
||||||
|
|
|
@ -7851,7 +7851,7 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
texFunctions = import ../misc/tex/nix {
|
texFunctions = import ../misc/tex/nix {
|
||||||
inherit stdenv perl tetex graphviz ghostscript makeFontsConf imagemagick;
|
inherit stdenv perl tetex graphviz ghostscript makeFontsConf imagemagick runCommand lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
texLive = builderDefsPackage (import ../misc/tex/texlive) {
|
texLive = builderDefsPackage (import ../misc/tex/texlive) {
|
||||||
|
|
Loading…
Reference in New Issue