/* TeX Live user docs - source: ../../../../../doc/languages-frameworks/texlive.xml - current html: https://nixos.org/nixpkgs/manual/#sec-language-texlive */ { stdenv, lib, fetchurl, fetchpatch, runCommand, writeText, buildEnv , callPackage, ghostscriptX, harfbuzz, poppler_min , makeWrapper, python, ruby, perl , useFixedHashes ? true , recurseIntoAttrs }: let # various binaries (compiled) bin = callPackage ./bin.nix { poppler = poppler_min; # otherwise depend on various X stuff ghostscript = ghostscriptX; harfbuzz = harfbuzz.override { withIcu = true; withGraphite2 = true; }; }; # map: name -> fixed-output hash # sha1 in base32 was chosen as a compromise between security and length fixedHashes = lib.optionalAttrs useFixedHashes (import ./fixedHashes.nix); # function for creating a working environment from a set of TL packages combine = import ./combine.nix { inherit bin combinePkgs buildEnv lib makeWrapper writeText stdenv python ruby perl; ghostscript = ghostscriptX; # could be without X, probably, but we use X above }; # the set of TeX Live packages, collections, and schemes; using upstream naming tl = let orig = import ./pkgs.nix tl; removeSelfDep = lib.mapAttrs (n: p: if p ? deps then p // { deps = lib.filterAttrs (dn: _: n != dn) p.deps; } else p); clean = removeSelfDep (orig // { # overrides of texlive.tlpdb texlive-msg-translations = orig.texlive-msg-translations // { hasRunfiles = false; # only *.po for tlmgr }; xdvi = orig.xdvi // { # it seems to need it to transform fonts deps = (orig.xdvi.deps or {}) // { inherit (tl) metafont; }; }; # remove dependency-heavy packages from the basic collections collection-basic = orig.collection-basic // { deps = removeAttrs orig.collection-basic.deps [ "metafont" "xdvi" ]; }; # add them elsewhere so that collections cover all packages collection-metapost = orig.collection-metapost // { deps = orig.collection-metapost.deps // { inherit (tl) metafont; }; }; collection-plaingeneric = orig.collection-plaingeneric // { deps = orig.collection-plaingeneric.deps // { inherit (tl) xdvi; }; }; # TODO revert for texlive 2020 arara = lib.recursiveUpdate orig.arara { postUnpack = let arara_jar_fix = fetchpatch { url = "https://github.com/TeX-Live/texlive-source/commit/dbaf12f4a47dcd62bcc96346f65493fda3fec2c8.diff"; sha256 = "148knr8k6sm6fpyj31kdq85yxvzvwp1prjha3f07q24kbar2l830"; }; in '' if [ -f "$out"/scripts/arara/arara.sh ]; then cd "$out"/scripts/ patch -p4 <${arara_jar_fix} fi ''; }; }); # overrides # tl = in lib.mapAttrs flatDeps clean; # TODO: texlive.infra for web2c config? flatDeps = pname: attrs: let version = attrs.version or bin.texliveYear; mkPkgV = tlType: let pkg = attrs // { sha512 = attrs.sha512.${tlType}; inherit pname tlType version; }; in mkPkg pkg; in { # TL pkg contains lists of packages: runtime files, docs, sources, binaries pkgs = # tarball of a collection/scheme itself only contains a tlobj file [( if (attrs.hasRunfiles or false) then mkPkgV "run" # the fake derivations are used for filtering of hyphenation patterns else { inherit pname version; tlType = "run"; } )] ++ lib.optional (attrs.sha512 ? doc) (mkPkgV "doc") ++ lib.optional (attrs.sha512 ? source) (mkPkgV "source") ++ lib.optional (bin ? ${pname}) ( bin.${pname} // { inherit pname; tlType = "bin"; } ) ++ combinePkgs (attrs.deps or {}); }; # create a derivation that contains an unpacked upstream TL package mkPkg = { pname, tlType, revision, version, sha512, postUnpack ? "", stripPrefix ? 1, ... }@args: let # the basename used by upstream (without ".tar.xz" suffix) urlName = pname + lib.optionalString (tlType != "run") ".${tlType}"; tlName = urlName + "-${version}"; fixedHash = fixedHashes.${tlName} or null; # be graceful about missing hashes urls = args.urls or (if args ? url then [ args.url ] else lib.concatMap (up: [ # Only ~11% of packages in texlive 2019 have revisions, so # the number of requests is nearly doubled if we lookup # the name with revision # "${up}/${urlName}.r${toString revision}.tar.xz" "${up}/${urlName}.tar.xz" # TODO To be removed for texlive 2020? ]) urlPrefixes); # The tarballs on CTAN mirrors for the current release are constantly # receiving updates, so we can't use those directly. Stable snapshots # need to be used instead. Ideally, for the release branches of NixOS we # should be switching to the tlnet-final versions # (https://tug.org/historic/). urlPrefixes = args.urlPrefixes or [ # tlnet-final snapshot "http://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2019/tlnet-final/archive" "ftp://tug.org/texlive/historic/2019/tlnet-final/archive" # Daily snapshots hosted by one of the texlive release managers #https://texlive.info/tlnet-archive/2019/10/19/tlnet/archive ]; src = fetchurl { inherit urls sha512; }; passthru = { inherit pname tlType version; } // lib.optionalAttrs (sha512 != "") { inherit src; }; unpackCmd = file: '' tar -xf ${file} \ '--strip-components=${toString stripPrefix}' \ -C "$out" --anchored --exclude=tlpkg --keep-old-files '' + postUnpack; in if sha512 == "" then # hash stripped from pkgs.nix to save space -> fetch&unpack in a single step fetchurl { inherit urls; sha1 = if fixedHash == null then throw "TeX Live package ${tlName} is missing hash!" else fixedHash; name = tlName; recursiveHash = true; downloadToTemp = true; postFetch = ''mkdir "$out";'' + unpackCmd "$downloadedFile"; # TODO: perhaps override preferHashedMirrors and allowSubstitutes } // passthru else runCommand "texlive-${tlName}" ( { # lots of derivations, not meant to be cached preferLocalBuild = true; allowSubstitutes = false; inherit passthru; } // lib.optionalAttrs (fixedHash != null) { outputHash = fixedHash; outputHashAlgo = "sha1"; outputHashMode = "recursive"; } ) ( '' mkdir "$out" '' + unpackCmd "'${src}'" ); # combine a set of TL packages into a single TL meta-package combinePkgs = pkgSet: lib.concatLists # uniqueness is handled in `combine` (lib.mapAttrsToList (_n: a: a.pkgs) pkgSet); in tl // { inherit bin combine; # Pre-defined combined packages for TeX Live schemes, # to make nix-env usage more comfortable and build selected on Hydra. combined = with lib; recurseIntoAttrs ( mapAttrs (pname: attrs: addMetaAttrs rec { description = "TeX Live environment for ${pname}"; platforms = lib.platforms.all; hydraPlatforms = lib.optionals (!lib.elem pname ["scheme-infraonly"]) platforms; maintainers = with lib.maintainers; [ veprbl ]; } (combine { ${pname} = attrs; extraName = "combined" + lib.removePrefix "scheme" pname; }) ) { inherit (tl) scheme-basic scheme-context scheme-full scheme-gust scheme-infraonly scheme-medium scheme-minimal scheme-small scheme-tetex; } ); }