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