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