diff options
Diffstat (limited to 'pkgs/tools/typesetting/tex/nix/default.nix')
-rw-r--r-- | pkgs/tools/typesetting/tex/nix/default.nix | 244 |
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 00000000000..f5a34fb67a2 --- /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 + + ensureDir $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" + ]; + }; + +} |