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
//! サンプルの式をまとめて組んで標準出力へ流す
//!
//! KaTeX・MathJax と同じ仕事をさせて、起動を含めた時間を比べるためのもの。
//!
//! 使い方:
//! 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};
/// test/formula.js と同じ式を使う。二重に書くと食い違うので main.rs から読む
const MAIN: &str = include_str!("../src/main.rs");
/// SAMPLES の中の r"..." を取り出す
fn samples() -> Vec<&'static str> {
let from = MAIN.find("const SAMPLES").expect("SAMPLES がありません");
let rest = &MAIN[from..];
let to = rest.find("];").expect("SAMPLES が閉じていません");
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("フォントを読めません");
let font = font::load(data).expect("フォントを読み込めません");
// 末尾のサンプルはわざと壊してあるので外す
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("式を組めません"));
}
std::io::stdout().write_all(out.as_bytes()).expect("書き出せません");
}