New TeX Live withPackages function

I wanted to flag that texlive now implements .withPackages (as soon as the PR below hits master). It is temporarily undocumented, but it works like for other languages

texlive.withPackages (with ps; [ scheme-small collection-pstricks ])

and can be called on an existing combined scheme to add packages. It’s also easier to create non-texlive packages (just make them multi-output with special outputs names tex, texdoc…).

There is an experimental interface to add the docs too:

texlive.combined.scheme-small.__overrideTeXConfig { withDocs = true; }

It would be great if people using texlive could play with this and report any bugs, issues, feedback so that we ship 23.11 in a good state and possibly with a stable overrideTeXConfig.

https://github.com/NixOS/nixpkgs/pull/250805

12 Likes

It’s also easier to create non-texlive packages (just make them multi-output with special outputs names tex, texdoc…).

Could you provide a little more detail on this? I’m trying to use a 2024 version of dvisvgm with the texlive-2022 that’s available in nixpkgs 23.11. I can build dvisvgm fine on its own, but it lacks the paths to texmf.cnf and other files provided by kpathsea. I’m guessing I can use texlive.withPackages to integrate it into texlive but I can’t figure out how.

A small question on texlive (with no intention to be rude) : most packages of nixos seem to be fresh. Is there a particular reason for texlive to stay at 2022 ?

It should work with e.g. texliveInfraOnly.withPackages (_: [ dvisvgm3 ]), assuming dvisvgm3 is your updated version of dvisvgm.

However, if you start with a scheme that already contains dvisvgm, the two packages will clash. Unfortunately, overriding packages deep inside TeX Live is virtually impossible at the moment.

I was hoping to make TeX Live overrideable and ship TeX Live 2022 ‘stable’ and 2023 ‘unstable’ simultaneously before 23.11, but it didn’t work out. I guess at this point we should update nixpkgs-unstable to 2023 and work towards 2023 ‘stable’ and 2024 ‘unstable’ at the next release cycle.

Switching to 2023 is a bit trickier than usual due to ConTeXt now being outside of TeX Live, but luckily @apfelkuchen6 has worked out most build details in an old PR. I hope to resume that work in the next few weeks.

PS: keeping a stable release matters for some niche use cases, such as LaTeXML, which cannot keep up with the daily TeX Live churn.

1 Like

Thank you! I’ll try this and update this thread with the result.

Yes, I already had some name collision issues when I tried this (with the non-working dvisvgm3). I had to move to a more minimal scheme and add in the missing packages manually.

@xworld21 Quick question about texliveInfraOnly:

My texlive package configuration looks like this:

  mytex = pkgs.texliveSmall.withPackages
    (ps: with ps;
      [
        dvipng latexmk ieeetran
        fourier fouriernc bbm bbm-macros  ]); #Plus more packages, no dvisvgm here

  mydvisvgm = pkgs.texliveInfraOnly.withPackages
    (_: [ dvisvgm3 ]);

and I set

  home.packages = [ mytex mydvisvgm ];

When I try this I get an error:

error: builder for '/nix/store/l1mfzwlsznhhjqnp3ccby4lxsyl2hyx3-home-manager-path.drv' failed with exit code 25;
       last 1 log lines:
       > error: collision between `/nix/store/jhdiz5ir1zaszkh5qy22a7ygz5kh8l2f-texlive-2022-env/share/texmf/ls-R' and `/nix/store/3gbxcy9s92gavmxqm32vsahzlnxjbbn4-texlive-2022-env/share/texmf/ls-R'
       For full logs, run 'nix log /nix/store/l1mfzwlsznhhjqnp3ccby4lxsyl2hyx3-home-manager-path.drv'.
error: 1 dependencies of derivation '/nix/store/8jpz8gcvr1r0j5qvw828rp5a4k8pk1jm-home-manager-generation.drv' failed to build

Am I doing it wrong?

Dummy question here (I am a NixOS beginner) :

texlive.withPackages (with ps; [ scheme-small collection-pstricks ])

I see a lot of commands like this with withPackages (most of the time with python), with p:, ps;,

Where can I find a proper documentation for this and how to use it ? I search a bit but nothing really convincing.

Accordinf to this discussion, it seems that it is package related. But again, the explanation does not go further.

You can only install one TeX Live environment at a time, so you need to put the packages together:

mytex = pkgs.texliveSmall.withPackages (ps: with ps; [ dvipng latexmk ... dvisvgm3]);

I believe ps stands for “package set”. When you call texlive.withPackages, the function ps: [ ps.dvipng ] is applied to the texlive.pkgs package set.

Why do that instead of say texlive.withPackages [ texlive.pkgs.dvipng ]? Because repeating texlive twice is brittle. If you create your own overridden mytexlive with a different package set, for instance replace dvisvgm with a patched version or an entirely different TeX Live year, you’d have to replace each texlive with mytexlive. By using the ps argument you ensure that withPackages is always using the correct package set, for free.

(Or to give a better example, consider python311.withPackages vs python310.withPackages: using ps ensures that you automatically pick packages built for the requested Python version.)

Of course right now overriding texlive is as hard as it gets, but it will make more sense once we improve on that, and/or have separate texlive2022, texlive2023.

1 Like

That worked perfectly, thank you for the explanation(s).

I’m using the withPackages example here for creating a custom package, but my custom package contains a Type1 font, so I need to be able to run updmap --sys --enable Map myfont.map.

However, when running that command in the installPhase I’m getting

updmap: can’t write to /nix/store/rkchl1f1kypids82zaf49bz9j3wa61lx-texlive-2022-env/share/texmf-config/web2c/updmap.cfg: Permission denied at /nix/store/sfg2ipgijzxwgdlv0q37897pl3pcfs3a-texlive-texlive-scripts.bin-66570/bin/updmap line 1590.

What’s the right way to do this?

At the system level, you need to override the postBuild attribute (via the usual overrideAttrs) and add your command. Something like

(texlive.withPackages (...)).overrideAttrs (prev:
  {
    postBuild = prev.postBuild + ''
      updmap --sys --enable Map myfont.map
    '';
  })

Alternatively, if you are doing this for a single user, just run updmap --user, not updmap --sys. Just keep in mind that you’ll have to run updmap --user regularly to keep your files in sync.

But I also have good news: the refactor texlive.withPackages: replace postBuild with install-tl like script by xworld21 · Pull Request #294826 · NixOS/nixpkgs · GitHub, which I have just sent now, allows font maps from custom packages by setting passthru.fontMaps = "Map myfont.map\n" instead of messing with updmap. @ngm if you are able to try that PR, or send me your custom package privately for testing, that would be great! It would help me choose the ‘correct’ interface for font maps (i.e. should passthru.fontMaps be a string, or a list of strings, …).