Skip to main content

retex_kpath/
format.rs

1//! File formats known to kpathsea and their search parameters.
2
3/// A kind of file to look up, mirroring kpathsea's `kpse_file_format_type`.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum FileFormat {
6    /// TeX input files (`.tex`, and anything `\input` can read).
7    Tex,
8    /// Lua modules (`require` from LuaTeX).
9    Lua,
10    /// Format files (`.fmt`).
11    Fmt,
12    /// TeX font metrics (`.tfm`).
13    Tfm,
14    /// OpenType fonts (`.otf`).
15    OpenType,
16    /// TrueType fonts and collections (`.ttf`, `.ttc`).
17    TrueType,
18    /// Type 1 fonts (`.pfb`, `.pfa`).
19    Type1,
20    /// Encoding vectors (`.enc`).
21    Enc,
22    /// Font map files (`.map`).
23    Map,
24    /// Virtual fonts (`.vf`).
25    Vf,
26    /// BibTeX databases (`.bib`).
27    Bib,
28    /// BibTeX styles (`.bst`).
29    Bst,
30    /// Graphics and other files read by the backend (`TEXPICTS`).
31    Pict,
32    /// PostScript headers (`.pro`), which luapstricks reads.
33    PsHeader,
34    /// Files opened with `kpse.find_file(name, "other text files")`.
35    Text,
36}
37
38/// Search parameters for a [`FileFormat`].
39#[derive(Debug, Clone, Copy)]
40pub struct FormatInfo {
41    /// Variables holding the search path, in order of precedence.
42    pub env_vars: &'static [&'static str],
43    /// The path to use when no variable is set.
44    pub default_path: &'static str,
45    /// Standard suffixes, tried before the bare name.
46    pub suffixes: &'static [&'static str],
47    /// Alternate suffixes: a name with one is not given a standard suffix
48    /// (`article.cls` is not looked up as `article.cls.tex`).
49    pub alt_suffixes: &'static [&'static str],
50    /// Whether the bare name is tried after the suffixed ones (not for Lua
51    /// modules: `kpsewhich -format=lua q` does not find a file `q`).
52    pub bare: bool,
53}
54
55impl FileFormat {
56    /// The search parameters for this format.
57    pub fn info(self) -> FormatInfo {
58        let (env_vars, suffixes): (&[&str], &[&str]) = match self {
59            FileFormat::Tex => (&["TEXINPUTS"], &[".tex"]),
60            FileFormat::Lua => (
61                &["LUAINPUTS"],
62                &[
63                    ".lua", ".luatex", ".luc", ".luctex", ".texlua", ".texluc", ".tlu",
64                ],
65            ),
66            FileFormat::Fmt => (&["TEXFORMATS", "TEXMFINI"], &[".fmt"]),
67            FileFormat::Tfm => (&["TFMFONTS", "TEXFONTS"], &[".tfm"]),
68            FileFormat::OpenType => (&["OPENTYPEFONTS", "TEXFONTS"], &[".otf", ".OTF"]),
69            FileFormat::TrueType => (
70                &["TTFONTS", "TEXFONTS"],
71                &[".ttf", ".ttc", ".TTF", ".TTC", ".dfont"],
72            ),
73            FileFormat::Type1 => (
74                &[
75                    "T1FONTS",
76                    "T1INPUTS",
77                    "TEXFONTS",
78                    "TEXPSHEADERS",
79                    "PSHEADERS",
80                ],
81                &[".pfa", ".pfb"],
82            ),
83            FileFormat::Enc => (&["ENCFONTS", "TEXFONTS"], &[".enc"]),
84            FileFormat::Map => (&["TEXFONTMAPS", "TEXFONTS"], &[".map"]),
85            FileFormat::Vf => (&["VFFONTS", "TEXFONTS"], &[".vf"]),
86            FileFormat::Bib => (&["BIBINPUTS", "TEXBIB"], &[".bib"]),
87            FileFormat::Bst => (&["BSTINPUTS"], &[".bst"]),
88            FileFormat::Pict => (&["TEXPICTS", "TEXINPUTS"], &[]),
89            FileFormat::PsHeader => (&["TEXPSHEADERS", "PSHEADERS"], &[".pro"]),
90            // See [`FileFormat::variables`].
91            FileFormat::Text => (&[], &[]),
92        };
93        // The paths compiled into kpathsea for the variables texmf.cnf
94        // does not set (`kpsewhich -show-path`).
95        let default_path = match self {
96            FileFormat::Text => ".:$TEXMF/$progname//",
97            _ => ".",
98        };
99        // Observed with `kpsewhich --help-formats`.
100        let alt_suffixes: &[&str] = match self {
101            FileFormat::Tex => &[
102                ".sty", ".cls", ".fd", ".aux", ".bbl", ".def", ".clo", ".ldf",
103            ],
104            FileFormat::Pict => &[".eps", ".epsi"],
105            _ => &[],
106        };
107        FormatInfo {
108            env_vars,
109            default_path,
110            suffixes,
111            alt_suffixes,
112            bare: self != FileFormat::Lua,
113        }
114    }
115
116    /// The variables holding the search path for program `progname`, in
117    /// order of precedence. For "other text files" it is the program name
118    /// in capitals followed by `INPUTS` (`LUALATEXINPUTS`; `kpsewhich
119    /// -progname=lualatex --help-formats`).
120    pub fn variables(self, progname: &str) -> Vec<String> {
121        match self {
122            FileFormat::Text => vec![format!("{}INPUTS", progname.to_ascii_uppercase())],
123            _ => self
124                .info()
125                .env_vars
126                .iter()
127                .map(|v| (*v).to_owned())
128                .collect(),
129        }
130    }
131}