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}