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