236 lines
10 KiB
Nix
236 lines
10 KiB
Nix
|
/* TeX Live user docs
|
||
|
- source: ../../../../../doc/languages-frameworks/texlive.xml
|
||
|
- current html: https://nixos.org/nixpkgs/manual/#sec-language-texlive
|
||
|
*/
|
||
|
{ lib
|
||
|
#, stdenv
|
||
|
, gcc12Stdenv
|
||
|
, fetchurl, runCommand, writeShellScript, writeText, buildEnv
|
||
|
, callPackage, ghostscript_headless, harfbuzz
|
||
|
, makeWrapper, installShellFiles
|
||
|
, python3, ruby, perl, tk, jdk, bash, snobol4
|
||
|
, coreutils, findutils, gawk, getopt, gnugrep, gnumake, gnupg, gnused, gzip, html-tidy, ncurses, zip
|
||
|
, libfaketime, asymptote, biber-ms, makeFontsConf
|
||
|
, useFixedHashes ? true
|
||
|
, recurseIntoAttrs
|
||
|
}:
|
||
|
let stdenv = gcc12Stdenv; in
|
||
|
let
|
||
|
# various binaries (compiled)
|
||
|
bin = callPackage ./bin.nix {
|
||
|
ghostscript = ghostscript_headless;
|
||
|
harfbuzz = harfbuzz.override {
|
||
|
withIcu = true; withGraphite2 = true;
|
||
|
};
|
||
|
inherit useFixedHashes;
|
||
|
tlpdb = overriddenTlpdb;
|
||
|
};
|
||
|
|
||
|
tlpdb = import ./tlpdb.nix;
|
||
|
|
||
|
tlpdbVersion = tlpdb."00texlive.config";
|
||
|
|
||
|
# the set of TeX Live packages, collections, and schemes; using upstream naming
|
||
|
overriddenTlpdb = let
|
||
|
overrides = import ./tlpdb-overrides.nix {
|
||
|
inherit
|
||
|
stdenv lib bin tlpdb tlpdbxz tl
|
||
|
installShellFiles
|
||
|
coreutils findutils gawk getopt ghostscript_headless gnugrep
|
||
|
gnumake gnupg gnused gzip html-tidy ncurses perl python3 ruby zip;
|
||
|
};
|
||
|
in overrides tlpdb;
|
||
|
|
||
|
version = {
|
||
|
# day of the snapshot being taken
|
||
|
year = "2024";
|
||
|
month = "03";
|
||
|
day = "16";
|
||
|
# TeX Live version
|
||
|
texliveYear = 2023;
|
||
|
# final (historic) release or snapshot
|
||
|
final = true;
|
||
|
};
|
||
|
|
||
|
# 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/).
|
||
|
mirrors = with version; lib.optionals final [
|
||
|
# tlnet-final snapshot; used when texlive.tlpdb is frozen
|
||
|
# the TeX Live yearly freeze typically happens in mid-March
|
||
|
"http://ftp.math.utah.edu/pub/tex/historic/systems/texlive/${toString texliveYear}/tlnet-final"
|
||
|
"ftp://tug.org/texlive/historic/${toString texliveYear}/tlnet-final"
|
||
|
] ++ [
|
||
|
# CTAN mirrors
|
||
|
"https://mirror.ctan.org/systems/texlive/tlnet"
|
||
|
# daily snapshots hosted by one of the texlive release managers;
|
||
|
# used for packages that in the meanwhile have been updated or removed from CTAN
|
||
|
# and for packages that have not reached yet the historic mirrors
|
||
|
# please note that this server is not meant for large scale deployment
|
||
|
# https://tug.org/pipermail/tex-live/2019-November/044456.html
|
||
|
# https://texlive.info/ MUST appear last (see tlpdbxz)
|
||
|
"https://texlive.info/tlnet-archive/${year}/${month}/${day}/tlnet"
|
||
|
];
|
||
|
|
||
|
tlpdbxz = fetchurl {
|
||
|
urls = map (up: "${up}/tlpkg/texlive.tlpdb.xz")
|
||
|
# use last mirror for daily snapshots as texlive.tlpdb.xz changes every day
|
||
|
# TODO make this less hacky
|
||
|
(if version.final then mirrors else [ (lib.last mirrors) ]);
|
||
|
hash = "sha256-w+04GBFDk/P/XvW7T9PotGD0nQslMkV9codca2urNK4=";
|
||
|
};
|
||
|
|
||
|
tlpdbNix = runCommand "tlpdb.nix" {
|
||
|
inherit tlpdbxz;
|
||
|
tl2nix = ./tl2nix.sed;
|
||
|
}
|
||
|
''
|
||
|
xzcat "$tlpdbxz" | sed -rn -f "$tl2nix" | uniq > "$out"
|
||
|
'';
|
||
|
|
||
|
# map: name -> fixed-output hash
|
||
|
fixedHashes = lib.optionalAttrs useFixedHashes (import ./fixed-hashes.nix);
|
||
|
|
||
|
buildTeXLivePackage = import ./build-texlive-package.nix {
|
||
|
inherit lib fetchurl runCommand writeShellScript bash jdk perl python3 ruby snobol4 tk;
|
||
|
texliveBinaries = bin;
|
||
|
};
|
||
|
|
||
|
tl = lib.mapAttrs (pname: { revision, extraRevision ? "", ... }@args:
|
||
|
buildTeXLivePackage (args
|
||
|
# NOTE: the fixed naming scheme must match generate-fixed-hashes.nix
|
||
|
// { inherit mirrors pname; fixedHashes = fixedHashes."${pname}-${toString revision}${extraRevision}" or { }; }
|
||
|
// lib.optionalAttrs (args ? deps) { deps = map (n: tl.${n}) (args.deps or [ ]); })
|
||
|
) overriddenTlpdb;
|
||
|
|
||
|
# function for creating a working environment
|
||
|
buildTeXEnv = import ./build-tex-env.nix {
|
||
|
inherit bin tl;
|
||
|
ghostscript = ghostscript_headless;
|
||
|
inherit lib buildEnv libfaketime makeFontsConf makeWrapper runCommand
|
||
|
writeShellScript writeText toTLPkgSets bash perl coreutils gawk gnugrep gnused;
|
||
|
};
|
||
|
|
||
|
### texlive.combine compatibility layer:
|
||
|
# convert TeX packages to { pkgs = [ ... ]; } lists
|
||
|
# respecting specified outputs
|
||
|
toTLPkgList = drv: if drv.outputSpecified or false
|
||
|
then let tlType = drv.tlType or tlOutToType.${drv.tlOutputName or drv.outputName} or null; in
|
||
|
lib.optional (tlType != null) (drv // { inherit tlType; })
|
||
|
else [ (drv.tex // { tlType = "run"; }) ] ++
|
||
|
lib.optional (drv ? texdoc) (drv.texdoc // { tlType = "doc"; } // lib.optionalAttrs (drv ? man) { hasManpages = true; }) ++
|
||
|
lib.optional (drv ? texsource) (drv.texsource // { tlType = "source"; }) ++
|
||
|
lib.optional (drv ? tlpkg) (drv.tlpkg // { tlType = "tlpkg"; }) ++
|
||
|
lib.optional (drv ? out) (drv.out // { tlType = "bin"; });
|
||
|
tlOutToType = { out = "bin"; tex = "run"; texsource = "source"; texdoc = "doc"; tlpkg = "tlpkg"; };
|
||
|
|
||
|
# convert { pkgs = [ ... ]; } lists to TeX packages
|
||
|
# possibly more than one, if pkgs is also used to specify dependencies
|
||
|
tlTypeToOut = { run = "tex"; doc = "texdoc"; source = "texsource"; bin = "out"; tlpkg = "tlpkg"; };
|
||
|
toSpecifiedNV = p: rec {
|
||
|
name = value.tlOutputName;
|
||
|
value = builtins.removeAttrs p [ "pkgs" ]
|
||
|
// { outputSpecified = true; tlOutputName = tlTypeToOut.${p.tlType}; };
|
||
|
};
|
||
|
toTLPkgSet = pname: drvs:
|
||
|
let set = lib.listToAttrs (builtins.map toSpecifiedNV drvs);
|
||
|
mainDrv = set.out or set.tex or set.tlpkg or set.texdoc or set.texsource; in
|
||
|
builtins.removeAttrs mainDrv [ "outputSpecified" ];
|
||
|
toTLPkgSets = { pkgs, ... }: lib.mapAttrsToList toTLPkgSet
|
||
|
(builtins.groupBy (p: p.pname) pkgs);
|
||
|
|
||
|
# export TeX packages as { pkgs = [ ... ]; } in the top attribute set
|
||
|
allPkgLists = lib.mapAttrs (n: drv: { pkgs = toTLPkgList drv; }) tl;
|
||
|
|
||
|
# function for creating a working environment from a set of TL packages
|
||
|
# now a legacy wrapper around buildTeXEnv
|
||
|
combine = import ./combine-wrapper.nix { inherit buildTeXEnv lib toTLPkgList toTLPkgSets; };
|
||
|
|
||
|
assertions = with lib;
|
||
|
assertMsg (tlpdbVersion.year == version.texliveYear) "TeX Live year in texlive does not match tlpdb.nix, refusing to evaluate" &&
|
||
|
assertMsg (tlpdbVersion.frozen == version.final) "TeX Live final status in texlive does not match tlpdb.nix, refusing to evaluate";
|
||
|
|
||
|
# Pre-defined evironment packages for TeX Live schemes,
|
||
|
# to make nix-env usage more comfortable and build selected on Hydra.
|
||
|
|
||
|
# these license lists should be the sorted union of the licenses of the packages the schemes contain.
|
||
|
# The correctness of this collation is tested by tests.texlive.licenses
|
||
|
licenses = with lib.licenses; {
|
||
|
scheme-basic = [ free gfl gpl1Only gpl2Only gpl2Plus knuth lgpl21 lppl1 lppl13c mit ofl publicDomain ];
|
||
|
scheme-bookpub = [ artistic2 asl20 bsd3 fdl13Only free gfl gpl1Only gpl2Only gpl2Plus knuth lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain ];
|
||
|
scheme-context = [ bsd2 bsd3 cc-by-sa-40 free gfl gfsl gpl1Only gpl2Only gpl2Plus gpl3Only gpl3Plus knuth lgpl2 lgpl21
|
||
|
lppl1 lppl13c mit ofl publicDomain x11 ];
|
||
|
scheme-full = [ artistic1-cl8 artistic2 asl20 bsd2 bsd3 bsdOriginal cc-by-10 cc-by-20 cc-by-30 cc-by-40 cc-by-sa-10 cc-by-sa-20 cc-by-sa-30
|
||
|
cc-by-sa-40 cc0 fdl13Only free gfl gfsl gpl1Only gpl2Only gpl2Plus gpl3Only gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit
|
||
|
ofl publicDomain x11 ];
|
||
|
scheme-gust = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-40 cc0 fdl13Only free gfl gfsl gpl1Only gpl2Only
|
||
|
gpl2Plus gpl3Only gpl3Plus knuth lgpl2 lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ];
|
||
|
scheme-infraonly = [ gpl2Plus lgpl21 ];
|
||
|
scheme-medium = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-40 cc-by-sa-20 cc-by-sa-30 cc-by-sa-40 cc0 fdl13Only
|
||
|
free gfl gpl1Only gpl2Only gpl2Plus gpl3Only gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit ofl
|
||
|
publicDomain x11 ];
|
||
|
scheme-minimal = [ free gpl1Only gpl2Plus knuth lgpl21 lppl1 lppl13c mit ofl publicDomain ];
|
||
|
scheme-small = [ asl20 cc-by-40 cc-by-sa-40 cc0 fdl13Only free gfl gpl1Only gpl2Only gpl2Plus gpl3Only gpl3Plus knuth
|
||
|
lgpl2 lgpl21 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ];
|
||
|
scheme-tetex = [ artistic1-cl8 asl20 bsd2 bsd3 cc-by-30 cc-by-40 cc-by-sa-10 cc-by-sa-20 cc-by-sa-30 cc-by-sa-40 cc0 fdl13Only free gfl gpl1Only
|
||
|
gpl2Only gpl2Plus gpl3Only gpl3Plus isc knuth lgpl2 lgpl21 lgpl3 lppl1 lppl12 lppl13a lppl13c mit ofl publicDomain x11 ];
|
||
|
};
|
||
|
|
||
|
meta = {
|
||
|
description = "TeX Live environment";
|
||
|
platforms = lib.platforms.all;
|
||
|
maintainers = with lib.maintainers; [ veprbl ];
|
||
|
license = licenses.scheme-infraonly;
|
||
|
};
|
||
|
|
||
|
combined = recurseIntoAttrs (
|
||
|
lib.genAttrs [ "scheme-basic" "scheme-bookpub" "scheme-context" "scheme-full" "scheme-gust" "scheme-infraonly"
|
||
|
"scheme-medium" "scheme-minimal" "scheme-small" "scheme-tetex" ]
|
||
|
(pname:
|
||
|
(buildTeXEnv {
|
||
|
__extraName = "combined" + lib.removePrefix "scheme" pname;
|
||
|
__extraVersion = with version; if final then "-final" else ".${year}${month}${day}";
|
||
|
requiredTeXPackages = ps: [ ps.${pname} ];
|
||
|
# to maintain full backward compatibility, enable texlive.combine behavior
|
||
|
__combine = true;
|
||
|
}).overrideAttrs {
|
||
|
meta = meta // {
|
||
|
description = "TeX Live environment for ${pname}";
|
||
|
license = licenses.${pname};
|
||
|
};
|
||
|
}
|
||
|
)
|
||
|
);
|
||
|
|
||
|
schemes = lib.listToAttrs (map (s: {
|
||
|
name = "texlive" + s;
|
||
|
value = lib.addMetaAttrs { license = licenses.${"scheme-" + (lib.toLower s)}; } (buildTeXEnv { requiredTeXPackages = ps: [ ps.${"scheme-" + (lib.toLower s)} ]; });
|
||
|
}) [ "Basic" "BookPub" "ConTeXt" "Full" "GUST" "InfraOnly" "Medium" "Minimal" "Small" "TeTeX" ]);
|
||
|
|
||
|
in
|
||
|
allPkgLists // {
|
||
|
pkgs = tl;
|
||
|
|
||
|
tlpdb = {
|
||
|
# nested in an attribute set to prevent them from appearing in search
|
||
|
nix = tlpdbNix;
|
||
|
xz = tlpdbxz;
|
||
|
};
|
||
|
|
||
|
bin = assert assertions; bin // {
|
||
|
# for backward compatibility
|
||
|
latexindent = tl.latexindent;
|
||
|
};
|
||
|
|
||
|
combine = assert assertions; combine;
|
||
|
|
||
|
combined = assert assertions; combined;
|
||
|
|
||
|
inherit schemes;
|
||
|
|
||
|
# convenience alias
|
||
|
withPackages = (buildTeXEnv { }).withPackages;
|
||
|
}
|