texlive.withPackages: use buildenv (finalAttrs: ...)

This commit is contained in:
Vincenzo Mantova
2026-05-23 13:50:51 +01:00
parent f5804647d9
commit 62b7051f28
3 changed files with 452 additions and 421 deletions
+1 -1
View File
@@ -951,7 +951,7 @@ rec {
scheme:
builtins.foldl' (
acc: pkg: concatLicenses acc (lib.toList (pkg.meta.license or [ ]))
) [ ] scheme.passthru.requiredTeXPackages;
) [ ] scheme.passthru.includedTeXPackages;
correctLicensesAttrNames = scheme: lib.sort lt (map licenseToAttrName (correctLicenses scheme));
hasLicenseMismatch =
@@ -23,12 +23,9 @@
}:
lib.fix (
self:
buildTeXEnv:
{
withDocs ? false,
withSources ? false,
requiredTeXPackages ? ps: [ ps.scheme-infraonly ],
### texlive.combine backward compatibility
__extraName ? "combined",
__extraVersion ? "",
@@ -38,448 +35,484 @@ lib.fix (
__fromCombineWrapper ? false,
# build only the formats of a package (for internal use!)
__formatsOf ? null,
}@args:
}:
buildEnv (
finalAttrs:
let
### texlive.combine backward compatibility
# if necessary, convert old style { pkgs = [ ... ]; } packages to attribute sets
isOldPkgList = p: !p.outputSpecified or false && p ? pkgs && builtins.all (p: p ? tlType) p.pkgs;
ensurePkgSets =
ps:
if !__fromCombineWrapper && builtins.any isOldPkgList ps then
let
oldPkgLists = builtins.partition isOldPkgList ps;
in
oldPkgLists.wrong ++ lib.concatMap toTLPkgSets oldPkgLists.right
else
ps;
let
withDocs = finalAttrs.passthru.withDocs or false;
withSources = finalAttrs.passthru.withSources or false;
pkgList = rec {
# resolve dependencies of the packages that affect the runtime
all =
let
packages = ensurePkgSets (requiredTeXPackages tl);
runtime = builtins.partition (
p:
p.outputSpecified or false
-> builtins.elem (p.tlOutputName or p.outputName) [
"out"
"tex"
"tlpkg"
]
) packages;
keySet = p: {
key =
p.pname or p.name
+ lib.optionalString (p.outputSpecified or false) ("-" + p.tlOutputName or p.outputName or "");
inherit p;
tlDeps = if p ? tlDeps then ensurePkgSets p.tlDeps else (p.requiredTeXPackages or (_: [ ]) tl);
};
in
# texlive.combine: the wrapper already resolves all dependencies
if __fromCombineWrapper then
requiredTeXPackages null
# if necessary, convert old style { pkgs = [ ... ]; } packages to attribute sets
isOldPkgList = p: !p.outputSpecified or false && p ? pkgs && builtins.all (p: p ? tlType) p.pkgs;
ensurePkgSets =
ps:
if !finalAttrs.passthru.__fromCombineWrapper && builtins.any isOldPkgList ps then
let
oldPkgLists = builtins.partition isOldPkgList ps;
in
oldPkgLists.wrong ++ lib.concatMap toTLPkgSets oldPkgLists.right
else
builtins.catAttrs "p" (
builtins.genericClosure {
startSet = map keySet runtime.right;
operator = p: map keySet p.tlDeps;
}
)
++ runtime.wrong;
ps;
# group the specified outputs
specified = builtins.partition (p: p.outputSpecified or false) all;
specifiedOutputs = lib.groupBy (p: p.tlOutputName or p.outputName) specified.right;
otherOutputNames = builtins.catAttrs "key" (
builtins.genericClosure {
startSet = map (key: { inherit key; }) (
lib.concatLists (builtins.catAttrs "outputs" specified.wrong)
);
operator = _: [ ];
}
);
otherOutputs = lib.genAttrs otherOutputNames (n: builtins.catAttrs n specified.wrong);
outputsToInstall = builtins.catAttrs "key" (
builtins.genericClosure {
startSet = map (key: { inherit key; }) (
[ "out" ]
++ lib.optional (otherOutputs ? man) "man"
++ lib.concatLists (builtins.catAttrs "outputsToInstall" (builtins.catAttrs "meta" specified.wrong))
);
operator = _: [ ];
}
);
pkgList = rec {
# resolve dependencies of the packages that affect the runtime
all =
let
packages = ensurePkgSets (finalAttrs.passthru.requiredTeXPackages tl);
runtime = builtins.partition (
p:
p.outputSpecified or false
-> builtins.elem (p.tlOutputName or p.outputName) [
"out"
"tex"
"tlpkg"
]
) packages;
keySet = p: {
key =
p.pname or p.name
+ lib.optionalString (p.outputSpecified or false) ("-" + p.tlOutputName or p.outputName or "");
inherit p;
tlDeps = if p ? tlDeps then ensurePkgSets p.tlDeps else (p.requiredTeXPackages or (_: [ ]) tl);
};
in
# texlive.combine: the wrapper already resolves all dependencies
if finalAttrs.passthru.__fromCombineWrapper then
finalAttrs.passthru.requiredTeXPackages null
else
builtins.catAttrs "p" (
builtins.genericClosure {
startSet = map keySet runtime.right;
operator = p: map keySet p.tlDeps;
}
)
++ runtime.wrong;
# split binary and tlpkg from tex, texdoc, texsource
bin =
if __fromCombineWrapper then
builtins.filter (p: p.tlType == "bin") all # texlive.combine: legacy filter
else
otherOutputs.out or [ ] ++ specifiedOutputs.out or [ ];
tlpkg =
if __fromCombineWrapper then
builtins.filter (p: p.tlType == "tlpkg") all # texlive.combine: legacy filter
else
otherOutputs.tlpkg or [ ] ++ specifiedOutputs.tlpkg or [ ];
nonbin =
if __fromCombineWrapper then
builtins.filter (p: p.tlType != "bin" && p.tlType != "tlpkg") all # texlive.combine: legacy filter
else
(
if __combine then # texlive.combine: emulate old input ordering to avoid rebuilds
lib.concatMap (
p:
lib.optional (p ? tex) p.tex
++ lib.optional ((withDocs || p ? man) && p ? texdoc) p.texdoc
++ lib.optional (withSources && p ? texsource) p.texsource
) specified.wrong
else
otherOutputs.tex or [ ]
++ lib.optionals withDocs (otherOutputs.texdoc or [ ])
++ lib.optionals withSources (otherOutputs.texsource or [ ])
)
++ specifiedOutputs.tex or [ ]
++ specifiedOutputs.texdoc or [ ]
++ specifiedOutputs.texsource or [ ];
# outputs that do not become part of the environment
nonEnvOutputs = lib.subtractLists [ "out" "tex" "texdoc" "texsource" "tlpkg" ] otherOutputNames;
# packages that contribute to config files and formats
fontMaps = lib.filter (p: p ? fontMaps && (p.tlOutputName or p.outputName == "tex")) nonbin;
sortedFontMaps = builtins.sort (a: b: a.pname < b.pname) fontMaps;
hyphenPatterns = lib.filter (
p: p ? hyphenPatterns && (p.tlOutputName or p.outputName == "tex")
) nonbin;
sortedHyphenPatterns = builtins.sort (a: b: a.pname < b.pname) hyphenPatterns;
formatPkgs = lib.filter (
p:
p ? formats
&& (p.outputSpecified or false -> p.tlOutputName or p.outputName == "tex")
&& builtins.any (f: f.enabled or true) p.formats
) all;
sortedFormatPkgs =
if __formatsOf != null then [ __formatsOf ] else builtins.sort (a: b: a.pname < b.pname) formatPkgs;
formats = map (
p:
self {
requiredTeXPackages =
ps:
[
ps.scheme-infraonly
p
]
++ hyphenPatterns;
__formatsOf = p;
}
) sortedFormatPkgs;
};
# list generated by inspecting `grep -IR '\([^a-zA-Z]\|^\)gs\( \|$\|"\)' "$TEXMFDIST"/scripts`
# and `grep -IR rungs "$TEXMFDIST"`
# and ignoring luatex, perl, and shell scripts (those must be patched using postFixup)
needsGhostscript = lib.any (
p:
lib.elem p.pname [
"context"
"dvipdfmx"
"latex-papersize"
"lyluatex"
]
) pkgList.bin;
pname =
if __combine then
"texlive-${__extraName}" # texlive.combine: old name
else
"texlive";
version =
if __combine then
"${toString tlpdbVersion.year}${__extraVersion}" # texlive.combine: old version
else
"${toString tlpdbVersion.year}-r${toString tlpdbVersion.revision}-"
+ (lib.optionalString tlpdbVersion.frozen "final-")
+ (if __formatsOf != null then "${__formatsOf.pname}-fmt" else "env");
name = "${pname}-${version}";
texmfdist = buildEnv {
name = "${name}-texmfdist";
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
paths = builtins.catAttrs "outPath" pkgList.nonbin;
# mktexlsr
nativeBuildInputs = [
tl.texlive-scripts # for mktexlsr.pl with --sort support
perl
];
postBuild = # generate ls-R database
''
perl ${tl.texlive-scripts.tex}/scripts/texlive/mktexlsr.pl --sort "$out"
'';
};
tlpkg = buildEnv {
name = "${name}-tlpkg";
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
paths = builtins.catAttrs "outPath" pkgList.tlpkg;
};
# the 'non-relocated' packages must live in $TEXMFROOT/texmf-dist
# and sometimes look into $TEXMFROOT/tlpkg (notably fmtutil, updmap look for perl modules in both)
texmfroot =
runCommand "${name}-texmfroot"
{
inherit texmfdist tlpkg;
}
''
mkdir -p "$out"
ln -s "$texmfdist" "$out"/texmf-dist
ln -s "$tlpkg" "$out"/tlpkg
'';
# texlive.combine: expose info and man pages in usual /share/{info,man} location
doc = buildEnv {
name = "${name}-doc";
paths = [ (texmfdist.outPath + "/doc") ];
extraPrefix = "/share";
pathsToLink = [
"/info"
"/man"
];
};
meta = {
description =
"TeX Live environment"
+ lib.optionalString withDocs " with documentation"
+ lib.optionalString (withDocs && withSources) " and"
+ lib.optionalString withSources " with sources";
platforms = lib.platforms.all;
longDescription =
"Contains the following packages and their transitive dependencies:\n - "
+ lib.concatMapStringsSep "\n - " (
p:
p.pname + (lib.optionalString (p.outputSpecified or false) " (${p.tlOutputName or p.outputName})")
) (requiredTeXPackages tl);
};
# other outputs
nonEnvOutputs = lib.genAttrs pkgList.nonEnvOutputs (
outName:
buildEnv {
inherit name;
paths = builtins.catAttrs "outPath" (
pkgList.otherOutputs.${outName} or [ ] ++ pkgList.specifiedOutputs.${outName} or [ ]
# group the specified outputs
specified = builtins.partition (p: p.outputSpecified or false) all;
specifiedOutputs = lib.groupBy (p: p.tlOutputName or p.outputName) specified.right;
otherOutputNames = builtins.catAttrs "key" (
builtins.genericClosure {
startSet = map (key: { inherit key; }) (
lib.concatLists (builtins.catAttrs "outputs" specified.wrong)
);
operator = _: [ ];
}
);
derivationArgs = {
outputs = [ outName ];
nativeBuildInputs = [
# force the output to be ${outName} or nix-env will not work
(writeShellScript "force-output.sh" ''
export out="''${${outName}-}"
'')
];
inherit meta passthru;
};
}
);
passthru = {
# This is set primarily to help find-tarballs.nix to do its job
requiredTeXPackages = builtins.filter lib.isDerivation (
pkgList.bin
++ pkgList.nonbin
++ lib.optionals (!__fromCombineWrapper) (
lib.concatMap (
n: (pkgList.otherOutputs.${n} or [ ] ++ pkgList.specifiedOutputs.${n} or [ ])
) pkgList.nonEnvOutputs
)
);
# useful for inclusion in the `fonts.packages` nixos option or for use in devshells
fonts = "${texmfroot}/texmf-dist/fonts";
# support variants attrs, (prev: attrs)
__overrideTeXConfig =
newArgs:
let
appliedArgs = if builtins.isFunction newArgs then newArgs args else newArgs;
in
self (args // { __fromCombineWrapper = false; } // appliedArgs);
withPackages =
reqs:
self (
args
// {
requiredTeXPackages = ps: reqs ps ++ requiredTeXPackages ps;
__fromCombineWrapper = false;
otherOutputs = lib.genAttrs otherOutputNames (n: builtins.catAttrs n specified.wrong);
outputsToInstall = builtins.catAttrs "key" (
builtins.genericClosure {
startSet = map (key: { inherit key; }) (
[ "out" ]
++ lib.optional (otherOutputs ? man) "man"
++ lib.concatLists (builtins.catAttrs "outputsToInstall" (builtins.catAttrs "meta" specified.wrong))
);
operator = _: [ ];
}
);
};
# TeXLive::TLOBJ::fmtutil_cnf_lines
fmtutilLine =
{
name,
engine,
enabled ? true,
patterns ? [ "-" ],
options ? "",
...
}:
lib.optionalString (!enabled) "#! "
+ "${name} ${engine} ${lib.concatStringsSep "," patterns} ${options}";
fmtutilLines =
{ pname, formats, ... }:
[
"#"
"# from ${pname}:"
]
++ map fmtutilLine formats;
# split binary and tlpkg from tex, texdoc, texsource
bin =
if finalAttrs.passthru.__fromCombineWrapper then
builtins.filter (p: p.tlType == "bin") all # texlive.combine: legacy filter
else
otherOutputs.out or [ ] ++ specifiedOutputs.out or [ ];
tlpkg =
if finalAttrs.passthru.__fromCombineWrapper then
builtins.filter (p: p.tlType == "tlpkg") all # texlive.combine: legacy filter
else
otherOutputs.tlpkg or [ ] ++ specifiedOutputs.tlpkg or [ ];
# TeXLive::TLOBJ::language_dat_lines
langDatLine =
{
name,
file,
synonyms ? [ ],
...
}:
[ "${name} ${file}" ] ++ map (s: "=" + s) synonyms;
langDatLines =
{ pname, hyphenPatterns, ... }:
[ "% from ${pname}:" ] ++ builtins.concatMap langDatLine hyphenPatterns;
nonbin =
if finalAttrs.passthru.__fromCombineWrapper then
builtins.filter (p: p.tlType != "bin" && p.tlType != "tlpkg") all # texlive.combine: legacy filter
else
(
if finalAttrs.__combine then # texlive.combine: emulate old input ordering to avoid rebuilds
lib.concatMap (
p:
lib.optional (p ? tex) p.tex
++ lib.optional ((withDocs || p ? man) && p ? texdoc) p.texdoc
++ lib.optional (withSources && p ? texsource) p.texsource
) specified.wrong
else
otherOutputs.tex or [ ]
++ lib.optionals withDocs (otherOutputs.texdoc or [ ])
++ lib.optionals withSources (otherOutputs.texsource or [ ])
)
++ specifiedOutputs.tex or [ ]
++ specifiedOutputs.texdoc or [ ]
++ specifiedOutputs.texsource or [ ];
# TeXLive::TLOBJ::language_def_lines
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
langDefLine =
{
name,
file,
lefthyphenmin ? "",
righthyphenmin ? "",
synonyms ? [ ],
...
}:
map (
n:
"\\addlanguage{${n}}{${file}}{}{${if lefthyphenmin == "" then "2" else lefthyphenmin}}{${
if righthyphenmin == "" then "3" else righthyphenmin
}}"
) ([ name ] ++ synonyms);
langDefLines =
{ pname, hyphenPatterns, ... }:
[ "% from ${pname}:" ] ++ builtins.concatMap langDefLine hyphenPatterns;
# outputs that do not become part of the environment
nonEnvOutputs = lib.subtractLists [ "out" "tex" "texdoc" "texsource" "tlpkg" ] otherOutputNames;
# TeXLive::TLOBJ::language_lua_lines
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
langLuaLine =
{
name,
file,
lefthyphenmin ? "",
righthyphenmin ? "",
synonyms ? [ ],
...
}@args:
''
''\t['${name}'] = {
''\t''\tloader = '${file}',
''\t''\tlefthyphenmin = ${if lefthyphenmin == "" then "2" else lefthyphenmin},
''\t''\trighthyphenmin = ${if righthyphenmin == "" then "3" else righthyphenmin},
''\t''\tsynonyms = { ${lib.concatStringsSep ", " (map (s: "'${s}'") synonyms)} },
''
+ lib.optionalString (args ? file_patterns) "\t\tpatterns = '${args.file_patterns}',\n"
+ lib.optionalString (args ? file_exceptions) "\t\thyphenation = '${args.file_exceptions}',\n"
+ lib.optionalString (args ? luaspecial) "\t\tspecial = '${args.luaspecial}',\n"
+ "\t},";
langLuaLines =
{ pname, hyphenPatterns, ... }: [ "-- from ${pname}:" ] ++ map langLuaLine hyphenPatterns;
# packages that contribute to config files and formats
fontMaps = lib.filter (p: p ? fontMaps && (p.tlOutputName or p.outputName == "tex")) nonbin;
sortedFontMaps = builtins.sort (a: b: a.pname < b.pname) fontMaps;
hyphenPatterns = lib.filter (
p: p ? hyphenPatterns && (p.tlOutputName or p.outputName == "tex")
) nonbin;
sortedHyphenPatterns = builtins.sort (a: b: a.pname < b.pname) hyphenPatterns;
formatPkgs = lib.filter (
p:
p ? formats
&& (p.outputSpecified or false -> p.tlOutputName or p.outputName == "tex")
&& builtins.any (f: f.enabled or true) p.formats
) all;
sortedFormatPkgs =
if __formatsOf != null then [ __formatsOf ] else builtins.sort (a: b: a.pname < b.pname) formatPkgs;
formats = map (
p:
buildTeXEnv {
requiredTeXPackages =
ps:
[
ps.scheme-infraonly
p
]
++ hyphenPatterns;
__formatsOf = p;
}
) sortedFormatPkgs;
};
assembleConfigLines = f: packages: builtins.concatStringsSep "\n" (builtins.concatMap f packages);
# list generated by inspecting `grep -IR '\([^a-zA-Z]\|^\)gs\( \|$\|"\)' "$TEXMFDIST"/scripts`
# and `grep -IR rungs "$TEXMFDIST"`
# and ignoring luatex, perl, and shell scripts (those must be patched using postFixup)
needsGhostscript = lib.any (
p:
lib.elem p.pname [
"context"
"dvipdfmx"
"latex-papersize"
"lyluatex"
]
) pkgList.bin;
updmapLines = { pname, fontMaps, ... }: [ "# from ${pname}:" ] ++ fontMaps;
pname =
if finalAttrs.__combine then
"texlive-${finalAttrs.passthru.__extraName}" # texlive.combine: old name
else
"texlive";
version =
if finalAttrs.__combine then
"${toString tlpdbVersion.year}${finalAttrs.passthru.__extraVersion}" # texlive.combine: old version
else
"${toString tlpdbVersion.year}-r${toString tlpdbVersion.revision}-"
+ (lib.optionalString tlpdbVersion.frozen "final-")
+ (if __formatsOf != null then "${__formatsOf.pname}-fmt" else "env");
in
buildEnv {
name = "${pname}-${version}";
inherit name;
texmfdist = buildEnv {
name = "${name}-texmfdist";
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
paths =
builtins.catAttrs "outPath" pkgList.bin
++ lib.optionals (!__combine && __formatsOf == null) pkgList.formats
++ lib.optional __combine doc;
pathsToLink = [
"/"
"/share/texmf-var/scripts"
"/share/texmf-var/tex/generic/config"
"/share/texmf-var/web2c"
"/share/texmf-config"
"/bin" # ensure these are writeable directories
];
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
paths = builtins.catAttrs "outPath" pkgList.nonbin;
postBuild = ''
. "${./build-tex-env.sh}"
'';
# mktexlsr
nativeBuildInputs = [
tl.texlive-scripts # for mktexlsr.pl with --sort support
perl
];
derivationArgs = {
# use attrNames, attrValues to ensure the two lists are sorted in the same way
outputs = [
"out"
]
++ lib.optionals (!__combine && __formatsOf == null) (builtins.attrNames nonEnvOutputs);
otherOutputs = lib.optionals (!__combine && __formatsOf == null) (
builtins.attrValues nonEnvOutputs
postBuild = # generate ls-R database
''
perl ${tl.texlive-scripts.tex}/scripts/texlive/mktexlsr.pl --sort "$out"
'';
};
tlpkg = buildEnv {
name = "${name}-tlpkg";
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
paths = builtins.catAttrs "outPath" pkgList.tlpkg;
};
# the 'non-relocated' packages must live in $TEXMFROOT/texmf-dist
# and sometimes look into $TEXMFROOT/tlpkg (notably fmtutil, updmap look for perl modules in both)
texmfroot =
runCommand "${name}-texmfroot"
{
inherit texmfdist tlpkg;
}
''
mkdir -p "$out"
ln -s "$texmfdist" "$out"/texmf-dist
ln -s "$tlpkg" "$out"/tlpkg
'';
# texlive.combine: expose info and man pages in usual /share/{info,man} location
doc = buildEnv {
name = "${name}-doc";
paths = [ (texmfdist.outPath + "/doc") ];
extraPrefix = "/share";
pathsToLink = [
"/info"
"/man"
];
};
meta = {
description =
"TeX Live environment"
+ lib.optionalString withDocs " with documentation"
+ lib.optionalString (withDocs && withSources) " and"
+ lib.optionalString withSources " with sources";
platforms = lib.platforms.all;
longDescription =
"Contains the following packages and their transitive dependencies:\n - "
+ lib.concatMapStringsSep "\n - " (
p:
p.pname + (lib.optionalString (p.outputSpecified or false) " (${p.tlOutputName or p.outputName})")
) (finalAttrs.passthru.requiredTeXPackages tl);
};
# other outputs
nonEnvOutputs = lib.genAttrs pkgList.nonEnvOutputs (
outName:
buildEnv {
inherit name;
paths = builtins.catAttrs "outPath" (
pkgList.otherOutputs.${outName} or [ ] ++ pkgList.specifiedOutputs.${outName} or [ ]
);
derivationArgs = {
outputs = [ outName ];
nativeBuildInputs = [
# force the output to be ${outName} or nix-env will not work
(writeShellScript "force-output.sh" ''
export out="''${${outName}-}"
'')
];
inherit meta passthru;
};
}
);
nativeBuildInputs = [
makeWrapper
libfaketime
tl."texlive.infra" # mktexlsr
tl.texlive-scripts # fmtutil, updmap
tl.texlive-scripts-extra # texlinks
perl
passthru = {
inherit
requiredTeXPackages
__fromCombineWrapper
__extraName
__extraVersion
;
# This is set primarily to help find-tarballs.nix to do its job
includedTeXPackages = builtins.filter lib.isDerivation (
pkgList.bin
++ pkgList.nonbin
++ lib.optionals (!finalAttrs.passthru.__fromCombineWrapper) (
lib.concatMap (
n: (pkgList.otherOutputs.${n} or [ ] ++ pkgList.specifiedOutputs.${n} or [ ])
) pkgList.nonEnvOutputs
)
);
# useful for inclusion in the `fonts.packages` nixos option or for use in devshells
fonts = "${texmfroot}/texmf-dist/fonts";
__overrideTeXConfig = lib.warn "__overrideTeXConfig is deprecated, please switch to overrideAttrs" (
newArgs:
let
# arguments of buildTeXEnv before deprecation of __overrideTeXConfig
prevArgs = {
withDocs = finalAttrs.passthru.withDocs or false;
withSources = finalAttrs.passthru.withSources or false;
inherit (finalAttrs)
__combine
;
inherit (finalAttrs.passthru)
requiredTeXPackages
__extraName
__extraVersion
__fromCombineWrapper
;
};
appliedArgs = prevArgs // (if builtins.isFunction newArgs then newArgs prevArgs else newArgs);
in
finalAttrs.finalPackage.overrideAttrs (prevAttrs: {
passthru = prevAttrs.passthru // {
inherit (appliedArgs)
withDocs
withSources
requiredTeXPackages
__extraName
__extraVersion
;
__fromCombineWrapper = false;
};
inherit (appliedArgs) __combine;
})
);
withPackages =
reqs:
finalAttrs.finalPackage.overrideAttrs (prevAttrs: {
passthru = prevAttrs.passthru // {
requiredTeXPackages = ps: reqs ps ++ prevAttrs.passthru.requiredTeXPackages ps;
__fromCombineWrapper = false;
};
});
};
# TeXLive::TLOBJ::fmtutil_cnf_lines
fmtutilLine =
{
name,
engine,
enabled ? true,
patterns ? [ "-" ],
options ? "",
...
}:
lib.optionalString (!enabled) "#! "
+ "${name} ${engine} ${lib.concatStringsSep "," patterns} ${options}";
fmtutilLines =
{ pname, formats, ... }:
[
"#"
"# from ${pname}:"
]
++ map fmtutilLine formats;
# TeXLive::TLOBJ::language_dat_lines
langDatLine =
{
name,
file,
synonyms ? [ ],
...
}:
[ "${name} ${file}" ] ++ map (s: "=" + s) synonyms;
langDatLines =
{ pname, hyphenPatterns, ... }:
[ "% from ${pname}:" ] ++ builtins.concatMap langDatLine hyphenPatterns;
# TeXLive::TLOBJ::language_def_lines
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
langDefLine =
{
name,
file,
lefthyphenmin ? "",
righthyphenmin ? "",
synonyms ? [ ],
...
}:
map (
n:
"\\addlanguage{${n}}{${file}}{}{${if lefthyphenmin == "" then "2" else lefthyphenmin}}{${
if righthyphenmin == "" then "3" else righthyphenmin
}}"
) ([ name ] ++ synonyms);
langDefLines =
{ pname, hyphenPatterns, ... }:
[ "% from ${pname}:" ] ++ builtins.concatMap langDefLine hyphenPatterns;
# TeXLive::TLOBJ::language_lua_lines
# see TeXLive::TLUtils::parse_AddHyphen_line for default values
langLuaLine =
{
name,
file,
lefthyphenmin ? "",
righthyphenmin ? "",
synonyms ? [ ],
...
}@args:
''
''\t['${name}'] = {
''\t''\tloader = '${file}',
''\t''\tlefthyphenmin = ${if lefthyphenmin == "" then "2" else lefthyphenmin},
''\t''\trighthyphenmin = ${if righthyphenmin == "" then "3" else righthyphenmin},
''\t''\tsynonyms = { ${lib.concatStringsSep ", " (map (s: "'${s}'") synonyms)} },
''
+ lib.optionalString (args ? file_patterns) "\t\tpatterns = '${args.file_patterns}',\n"
+ lib.optionalString (args ? file_exceptions) "\t\thyphenation = '${args.file_exceptions}',\n"
+ lib.optionalString (args ? luaspecial) "\t\tspecial = '${args.luaspecial}',\n"
+ "\t},";
langLuaLines =
{ pname, hyphenPatterns, ... }: [ "-- from ${pname}:" ] ++ map langLuaLine hyphenPatterns;
assembleConfigLines = f: packages: builtins.concatStringsSep "\n" (builtins.concatMap f packages);
updmapLines = { pname, fontMaps, ... }: [ "# from ${pname}:" ] ++ fontMaps;
in
{
inherit name;
# remove fake derivations (without 'outPath') to avoid undesired build dependencies
paths =
builtins.catAttrs "outPath" pkgList.bin
++ lib.optionals (!finalAttrs.__combine && __formatsOf == null) pkgList.formats
++ lib.optional finalAttrs.__combine doc;
pathsToLink = [
"/"
"/share/texmf-var/scripts"
"/share/texmf-var/tex/generic/config"
"/share/texmf-var/web2c"
"/share/texmf-config"
"/bin" # ensure these are writeable directories
];
buildInputs = [
coreutils
gawk
gnugrep
gnused
]
++ lib.optional needsGhostscript ghostscript;
postBuild = ''
. "${./build-tex-env.sh}"
'';
inherit passthru __combine;
__formatsOf = __formatsOf.pname or null;
derivationArgs = {
# use attrNames, attrValues to ensure the two lists are sorted in the same way
outputs = [
"out"
]
++ lib.optionals (!finalAttrs.__combine && __formatsOf == null) (builtins.attrNames nonEnvOutputs);
otherOutputs = lib.optionals (!finalAttrs.__combine && __formatsOf == null) (
builtins.attrValues nonEnvOutputs
);
inherit texmfdist texmfroot;
nativeBuildInputs = [
makeWrapper
libfaketime
tl."texlive.infra" # mktexlsr
tl.texlive-scripts # fmtutil, updmap
tl.texlive-scripts-extra # texlinks
perl
];
fontconfigFile = makeFontsConf { fontDirectories = [ "${texmfroot}/texmf-dist/fonts" ]; };
buildInputs = [
coreutils
gawk
gnugrep
gnused
]
++ lib.optional needsGhostscript ghostscript;
fmtutilCnf = assembleConfigLines fmtutilLines pkgList.sortedFormatPkgs;
updmapCfg = assembleConfigLines updmapLines pkgList.sortedFontMaps;
inherit passthru __combine;
__formatsOf = __formatsOf.pname or null;
languageDat = assembleConfigLines langDatLines pkgList.sortedHyphenPatterns;
languageDef = assembleConfigLines langDefLines pkgList.sortedHyphenPatterns;
languageLua = assembleConfigLines langLuaLines pkgList.sortedHyphenPatterns;
inherit texmfdist texmfroot;
postactionScripts = builtins.catAttrs "postactionScript" pkgList.tlpkg;
fontconfigFile = makeFontsConf { fontDirectories = [ "${texmfroot}/texmf-dist/fonts" ]; };
allowSubstitutes = true;
preferLocalBuild = false;
fmtutilCnf = assembleConfigLines fmtutilLines pkgList.sortedFormatPkgs;
updmapCfg = assembleConfigLines updmapLines pkgList.sortedFontMaps;
meta =
meta
// lib.optionalAttrs (!__combine && __formatsOf == null) {
inherit (pkgList) outputsToInstall;
};
};
}
languageDat = assembleConfigLines langDatLines pkgList.sortedHyphenPatterns;
languageDef = assembleConfigLines langDefLines pkgList.sortedHyphenPatterns;
languageLua = assembleConfigLines langLuaLines pkgList.sortedHyphenPatterns;
postactionScripts = builtins.catAttrs "postactionScript" pkgList.tlpkg;
allowSubstitutes = true;
preferLocalBuild = false;
meta =
meta
// lib.optionalAttrs (!finalAttrs.__combine && __formatsOf == null) {
inherit (pkgList) outputsToInstall;
};
};
}
)
)
@@ -233,7 +233,7 @@ let
# function for creating a working environment
buildTeXEnv = import ./build-tex-env.nix {
inherit bin tl;
inherit tl;
inherit tlpdbVersion;
ghostscript = ghostscript_headless;
inherit
@@ -244,9 +244,7 @@ let
makeWrapper
runCommand
writeShellScript
writeText
toTLPkgSets
bash
perl
coreutils
gawk