summaryrefslogtreecommitdiff
path: root/modules/devenv/languages/latex.nix
blob: eece1733a2e7001f26cbb6dc2a085cccd0d160f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
{
  config,
  lib,
  pkgs,
  devenv,
  ...
}: let
  cfg = config.languages.texlive;
  pdfModes = {
    "pdflatex" = "1";
    "ps2pdf" = "2";
    "dvi2pdf" = "3";
    "lulatex" = "4";
    "xelatex" = "5";
  };
  dviModes = {
    "latex" = "1";
    "lualatex" = "2";
  };
  latexmkrc = with latexmkrc; let
    pdfMode = with output.pdf;
      if enable
      then pdfModes."${mode}"
      else "0";
    dviMode = with output.dvi;
      if enable
      then dviModes."${mode}"
      else "0";
    psMode =
      if output.ps.enable
      then "1"
      else "0";
  in ''
    set_tex_cmds('${extraFlags}');
    $pdf_mode=${pdfMode}
    $dvi_mode=${dviMode}
    $ps_mode=${psMode}

    ${extraConfig}
  '';
  packages = cfg.packages cfg.base;
  packagesRequireShellEscape = packages ? minted;
  texlive = cfg.base.combine packages;
in {
  disabledModules = ["${devenv}/src/modules/languages/texlive.nix"];

  options.languages.texlive = {
    enable = lib.mkEnableOption "TeX Live";
    base = lib.mkPackageOption pkgs "TeX Live" {
      default = ["texlive"];
    };
    packages = lib.mkOption {
      type = with lib.types;
        functionTo (attrsOf (submodule {
          pkgs = lib.mkOption {
            type = listOf package;
          };
        }));
      default = tl: {inherit (tl) scheme-medium;};
      description = "Packages available to TeX Live.";
    };

    latexmk = {
      enable = lib.mkEnableOption "latexmk";
      shellEscape.enable = lib.mkEnableOption "shell escaping";
      extraFlags = lib.mkOption {
        type = with lib.types; listOf str;
        default = [];
        example = ["--interaction=nonstopmode"];
      };
      output = let
        mkOutputOptions = formats:
          lib.mapAttrs (format: extra:
            lib.recursiveUpdate {
              enable = lib.mkEnableOption "${format} output";
            }
            extra)
          formats;
      in
        mkOutputOptions {
          pdf = {
            enable.default = true;
            mode = lib.mkOption {
              type = lib.types.enum (lib.attrNames pdfModes);
              default = "lualatex";
              description = "How to generate the pdf file.";
            };
          };
          dvi = {
            mode = lib.mkOption {
              type = lib.types.enum (lib.attrNames dviModes);
              default = "latex";
              description = "How to generate the dvi file.";
            };
          };
          ps = {};
        };
      extraConfig = lib.mkOption {
        type = lib.types.lines;
        default = "";
        description = "Extra configuration to put inside the RC file.";
      };
    };
  };

  config = lib.mkMerge [
    {
      languages.texlive = {
        latexmk = {
          shellEscape.enable = lib.mkIf (lib.mkDefault packagesRequireShellEscape true);
          extraFlags = lib.optional cfg.latexmkrc.shellEscape.enable "-shell-escape";
        };
        packages = tl: lib.optionalAttrs cfg.latexmk.enable {inherit (tl) latexmk;};
      };
      packages = lib.optional cfg.enable texlive;
    }
    (lib.mkIf cfg.latexmk.enable {
      scripts.latexmk.exec = ''
        ${texlive}/bin/latexmk -r ${devenv.root}/.latexmkrc
      '';
      dotfiles.".latexmkrc" = {
        gitignore = lib.mkDefault false;
        text = latexmkrc;
      };
    })
  ];
}