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
//! Typesets every document in test/ and lists the number of pages and the size of each
//!
//! Usage:
//! cargo run --example check
//! cargo run --example check -- --font-japanese /path/to/mincho.otf
use hongo::style::Style;
use std::path::{Path, PathBuf};
/// Looks for one typeface in font/ that is not the math typeface
fn any_font(except: &Path) -> Option<PathBuf> {
let mut found: Vec<PathBuf> = std::fs::read_dir("font")
.ok()?
.filter_map(|entry| entry.ok())
.map(|entry| entry.path())
.filter(|path| {
let suffix = path
.extension()
.and_then(|one| one.to_str())
.unwrap_or_default()
.to_lowercase();
matches!(suffix.as_str(), "otf" | "ttf" | "ttc") && path != except
})
.collect();
found.sort();
found.into_iter().next()
}
fn main() {
let mut argument: Vec<String> = std::env::args().skip(1).collect();
let mut japanese: Option<PathBuf> = None;
if let Some(at) = argument.iter().position(|one| one == "--font-japanese") {
if at + 1 >= argument.len() {
eprintln!("--font-japanese must be followed by a file");
std::process::exit(1);
}
japanese = Some(PathBuf::from(argument.remove(at + 1)));
argument.remove(at);
}
if japanese.is_none() {
japanese = any_font(Path::new("font/latinmodern-math.otf"));
}
if japanese.is_none() {
// A typeface on this Mac. It is only for checking on the local machine
let known = PathBuf::from("/Library/Fonts/Arial Unicode.ttf");
if known.is_file() {
japanese = Some(known);
}
}
let library = match hongo::font::open(
Path::new("font/latinmodern-math.otf"),
None,
None,
None,
None,
None,
japanese.as_deref(),
) {
Ok(library) => library,
Err(reason) => {
eprintln!("cannot read the typefaces: {reason}");
std::process::exit(1);
}
};
let style = Style::default();
let mut found: Vec<PathBuf> = std::fs::read_dir("test")
.expect("cannot read test/")
.filter_map(|entry| entry.ok())
.map(|entry| entry.path())
.filter(|path| path.extension().is_some_and(|one| one == "tex"))
.collect();
found.sort();
let mut wrong = 0;
for path in &found {
let source = std::fs::read_to_string(path).expect("cannot read the document");
match hongo::render(&source, &library, &style, Path::new("test")) {
Ok(made) => {
let missing: String = made.missing.iter().take(10).collect();
let note = if missing.is_empty() {
String::new()
} else {
format!(" - missing: {missing}")
};
println!(
"{:<22} {:>3} pages {:>5} KB{note}",
path.file_name().unwrap_or_default().to_string_lossy(),
made.page,
made.data.len() / 1024
);
}
Err(reason) => {
wrong += 1;
println!("{:<22} cannot typeset: {reason}", path.display());
}
}
}
if wrong > 0 {
std::process::exit(1);
}
}