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
//! Typesets the sample formulas in bulk and writes them to standard output
//!
//! This makes suki do the same work as KaTeX and MathJax, to compare the time including startup.
//!
//! Usage:
//! cargo run --release --example many -- svg 1000 > out.svg
//! cargo run --release --example many -- html 1000 > out.html
use std::io::Write;
use suki::font;
use suki::{Mode, Shape, parse, render_html, render_svg};
/// Uses the same formulas as test/formula.js. Writing them twice would let the copies differ,
/// so they are read from main.rs
const MAIN: &str = include_str!("../src/main.rs");
/// Extracts each r"..." in SAMPLES
fn samples() -> Vec<&'static str> {
let from = MAIN.find("const SAMPLES").expect("SAMPLES not found");
let rest = &MAIN[from..];
let to = rest.find("];").expect("SAMPLES is not closed");
let mut found = Vec::new();
for line in rest[..to].lines() {
if let Some(body) = line.trim().strip_prefix("r\"") {
if let Some(body) = body.strip_suffix("\",") {
found.push(body);
}
}
}
found
}
fn main() {
let mut arguments = std::env::args().skip(1);
let kind = arguments.next().unwrap_or_else(|| "svg".to_string());
let wanted: usize = arguments
.next()
.and_then(|value| value.parse().ok())
.unwrap_or(1000);
let data = std::fs::read("font/latinmodern-math.otf").expect("Cannot read the font");
let font = font::load(data).expect("Cannot load the font");
// The last sample is broken on purpose, so leave it out
let base: Vec<&str> = samples().into_iter().filter(|s| parse(s).is_ok()).collect();
let mut out = String::new();
for index in 0..wanted {
let source = base[index % base.len()];
let markup = if kind == "html" {
render_html(source, &font, Mode::Display)
} else {
render_svg(source, &font, Mode::Display, Shape::Outline)
};
out.push_str(&markup.expect("Cannot typeset the formula"));
}
std::io::stdout().write_all(out.as_bytes()).expect("Cannot write the output");
}