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}