nixpkgs/pkgs/tools/typesetting/tex/texlive/default.nix
2021-07-04 11:47:32 +01:00

220 lines
8.1 KiB
Nix

/* TeX Live user docs
- source: ../../../../../doc/languages-frameworks/texlive.xml
- current html: https://nixos.org/nixpkgs/manual/#sec-language-texlive
*/
{ stdenv, lib, fetchurl, runCommand, writeText, buildEnv
, callPackage, ghostscriptX, harfbuzz
, makeWrapper, python3, ruby, perl
, useFixedHashes ? true
, recurseIntoAttrs
, fetchpatch
}:
let
# various binaries (compiled)
bin = callPackage ./bin.nix {
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 python3 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; };
};
texdoc = orig.texdoc // {
# build Data.tlpdb.lua (part of the 'tlType == "run"' package)
postUnpack = let
# commit that ensures reproducibility of Data.tlpdb.lua
# remove on the next texdoc update
reproPatch = fetchpatch {
name = "make-data-tlpdb-lua-reproducible.patch";
url = "https://github.com/TeX-Live/texdoc/commit/82aff83d5453a887c1117b9e771a98bddd8a605a.patch";
sha256 = "0y04y468i7db4p5bsyyhgzip8q4fi1756x9a15ndha9xfnasbf44";
stripLen = 2;
extraPrefix = "scripts/texdoc/";
};
in ''
if [[ -f "$out"/scripts/texdoc/texdoc.tlu ]]; then
patch -p1 -d "$out" < "${reproPatch}"
unxz --stdout "${tlpdb}" > texlive.tlpdb
# create dummy doc file to ensure that texdoc does not return an error
mkdir -p support/texdoc
touch support/texdoc/NEWS
TEXMFCNF="${bin.core}"/share/texmf-dist/web2c TEXMF="$out" TEXDOCS=. TEXMFVAR=. \
"${bin.luatex}"/bin/texlua "$out"/scripts/texdoc/texdoc.tlu \
-c texlive_tlpdb=texlive.tlpdb -lM texdoc
cp texdoc/cache-tlpdb.lua "$out"/scripts/texdoc/Data.tlpdb.lua
fi
'';
};
}); # overrides
# tl =
in lib.mapAttrs flatDeps clean;
# TODO: texlive.infra for web2c config?
flatDeps = pname: attrs:
let
version = attrs.version or (builtins.toString attrs.revision);
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";
hasHyphens = attrs.hasHyphens or false;
}
)]
++ 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 {});
};
snapshot = {
year = "2021";
month = "04";
day = "08";
};
tlpdb = fetchurl {
# use the same mirror(s) as urlPrefixes below
urls = [
#"http://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2019/tlnet-final/tlpkg/texlive.tlpdb.xz"
#"ftp://tug.org/texlive/historic/2019/tlnet-final/tlpkg/texlive.tlpdb.xz"
"https://texlive.info/tlnet-archive/${snapshot.year}/${snapshot.month}/${snapshot.day}/tlnet/tlpkg/texlive.tlpdb.xz"
];
sha512 = "1dsj4bza84g2f2z0w31yil3iwcnggcyg9f1xxwmp6ljk5xlzyr39cb556prx9691zbwpbrwbb5hnbqxqlnwsivgk0pmbl9mbjbk9cz0";
};
# 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
map (up: "${up}/${urlName}.r${toString revision}.tar.xz") 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/${snapshot.year}/${snapshot.month}/${snapshot.day}/tlnet/archive"
];
in runCommand "texlive-${tlName}"
( {
src = fetchurl { inherit urls sha512; };
inherit stripPrefix;
# metadata for texlive.combine
passthru = {
inherit pname tlType version;
hasHyphens = args.hasHyphens or false;
};
} // lib.optionalAttrs (fixedHash != null) {
outputHash = fixedHash;
outputHashAlgo = "sha1";
outputHashMode = "recursive";
}
)
( ''
mkdir "$out"
tar -xf "$src" \
--strip-components="$stripPrefix" \
-C "$out" --anchored --exclude=tlpkg --keep-old-files
'' + postUnpack
);
# 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;
maintainers = with lib.maintainers; [ veprbl ];
}
(combine {
${pname} = attrs;
extraName = "combined" + lib.removePrefix "scheme" pname;
extraVersion = ".${snapshot.year}${snapshot.month}${snapshot.day}";
})
)
{ inherit (tl)
scheme-basic scheme-context scheme-full scheme-gust scheme-infraonly
scheme-medium scheme-minimal scheme-small scheme-tetex;
}
);
}