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}