about summary refs log tree commit diff
path: root/pkgs/tools/typesetting/tex/nix/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/tools/typesetting/tex/nix/default.nix')
-rw-r--r--pkgs/tools/typesetting/tex/nix/default.nix244
1 files changed, 244 insertions, 0 deletions
diff --git a/pkgs/tools/typesetting/tex/nix/default.nix b/pkgs/tools/typesetting/tex/nix/default.nix
new file mode 100644
index 000000000000..9ae567e635b7
--- /dev/null
+++ b/pkgs/tools/typesetting/tex/nix/default.nix
@@ -0,0 +1,244 @@
+pkgs:
+
+rec {
+
+
+  runLaTeX =
+    { rootFile
+    , generatePDF ? true # generate PDF, not DVI
+    , generatePS ? false # generate PS in addition to DVI
+    , extraFiles ? []
+    , compressBlanksInIndex ? true
+    , packages ? []
+    , copySources ? false
+    }:
+
+    assert generatePDF -> !generatePS;
+    
+    pkgs.stdenv.mkDerivation {
+      name = "doc";
+      
+      builder = ./run-latex.sh;
+      copyIncludes = ./copy-includes.pl;
+      
+      inherit rootFile generatePDF generatePS extraFiles
+        compressBlanksInIndex copySources;
+
+      includes = map (x: [x.key (baseNameOf (toString x.key))])
+        (findLaTeXIncludes {inherit rootFile;});
+      
+      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 =
+    { rootFile
+    }:
+
+    builtins.genericClosure {
+      startSet = [{key = rootFile;}];
+      
+      operator =
+        {key, ...}:
+
+        let
+
+          # `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"
+            { rootFile = baseNameOf (toString rootFile); src = key; }
+            "${pkgs.perl}/bin/perl ${./find-includes.pl}");
+
+          # Look for the dependencies of `key', trying various
+          # 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 xs;
+
+        in pkgs.lib.fold foundDeps [] deps;
+    };
+    
+
+  findLhs2TeXIncludes =
+    { rootFile
+    }:
+
+    builtins.genericClosure {
+      startSet = [{key = rootFile;}];
+      
+      operator =
+        {key, ...}:
+
+        let
+
+          deps = import (pkgs.runCommand "lhs2tex-includes"
+            { src = key; }
+            "${pkgs.stdenv.bash}/bin/bash ${./find-lhs2tex-includes.sh}");
+
+        in pkgs.lib.concatMap (x : if builtins.pathExists x then [{key = x;}] else [])
+                              (map (x : "${dirOf key}/${x}") deps);
+    };
+
+  dot2pdf =
+    { dotGraph
+    }:
+
+    pkgs.stdenv.mkDerivation {
+      name = "pdf";
+      builder = ./dot2pdf.sh;
+      inherit dotGraph fontsConf;
+      buildInputs = [
+        pkgs.perl pkgs.tetex pkgs.graphviz
+      ];
+    };
+  
+
+  dot2ps =
+    { dotGraph
+    }:
+
+    pkgs.stdenv.mkDerivation {
+      name = "ps";
+      builder = ./dot2ps.sh;
+      inherit dotGraph;
+      buildInputs = [
+        pkgs.perl pkgs.tetex pkgs.graphviz pkgs.ghostscript
+      ];
+    };
+
+  lhs2tex =
+    { source, flags ? null } :
+    pkgs.stdenv.mkDerivation {
+      name = "tex";
+      builder = ./lhs2tex.sh;
+      inherit source flags;
+      buildInputs = [ pkgs.lhs2tex pkgs.perl ];
+      copyIncludes = ./copy-includes.pl;
+      includes = map (x: [x.key (baseNameOf (toString x.key))])
+        (findLhs2TeXIncludes {rootFile = source;});
+    };
+  
+  animateDot = dotGraph: nrFrames: pkgs.stdenv.mkDerivation {
+    name = "dot-frames";
+    builder = ./animatedot.sh;
+    inherit dotGraph nrFrames;
+  };
+
+
+  # Wrap a piece of TeX code in a document.  Useful when generating
+  # inline images from TeX code.
+  wrapSimpleTeX =
+    { preamble ? null
+    , body
+    , name ? baseNameOf (toString body)
+    }:
+
+    pkgs.stdenv.mkDerivation {
+      inherit name preamble body;
+      buildCommand = ''
+        touch $out
+        echo '\documentclass{article}' >> $out
+        echo '\pagestyle{empty}' >> $out
+        if test -n "$preamble"; then cat $preamble >> $out; fi
+        echo '\begin{document}' >> $out
+        cat $body >> $out
+        echo '\end{document}' >> $out
+      '';
+    };
+
+
+  # Convert a Postscript file to a PNG image, trimming it so that
+  # there is no unnecessary surrounding whitespace.    
+  postscriptToPNG =
+    { postscript
+    }:
+
+    pkgs.stdenv.mkDerivation {
+      name = "png";
+      inherit postscript;
+
+      buildInputs = [pkgs.imagemagick pkgs.ghostscript];
+      
+      buildCommand = ''
+        if test -d $postscript; then
+          input=$(ls $postscript/*.ps)
+        else
+          input=$(stripHash $postscript; echo $strippedName)
+          ln -s $postscript $input
+        fi
+
+        mkdir -p $out
+        convert -units PixelsPerInch \
+          -density 600 \
+          -trim \
+          -matte \
+          -transparent '#ffffff' \
+          -type PaletteMatte \
+          +repage \
+          $input \
+          "$out/$(basename $input .ps).png"
+      ''; # */
+    };
+
+
+  # Convert a piece of TeX code to a PNG image.
+  simpleTeXToPNG =
+    { preamble ? null
+    , body
+    , name ? baseNameOf (toString body)
+    , packages ? []
+    }:
+
+    postscriptToPNG {
+      postscript = runLaTeX {
+        rootFile = wrapSimpleTeX {
+          inherit body preamble;
+        };
+        inherit packages;
+        generatePDF = false;
+        generatePS = true;
+      };
+    };
+
+
+  # Convert a piece of TeX code to a PDF.
+  simpleTeXToPDF =
+    { preamble ? null
+    , body
+    , name ? baseNameOf (toString body)
+    , packages ? []
+    }:
+
+    runLaTeX {
+      rootFile = wrapSimpleTeX {
+        inherit body preamble;
+      };
+      inherit packages;
+    };
+
+
+  # Some tools (like dot) need a fontconfig configuration file.
+  # This should be extended to allow the called to add additional
+  # fonts.
+  fontsConf = pkgs.makeFontsConf {
+    fontDirectories = [
+      "${pkgs.ghostscript}/share/ghostscript/fonts"
+    ];
+  };
+  
+}