Registry / RepositoryTypeScriptRustPython
Rollpie
ReadmeFiles
Versions
Info
Download
0.2.3555.5 KB2026-10-160.2.2572.8 KB2026-10-150.2.1580.5 KB2026-10-150.2.0579.9 KB2026-09-150.1.1576.6 KB2026-09-12
Version
0.2.2
Copyright
Rollpie, Irohabook
Publisher
math
Published
2026-10-15
Size
572.8 KB
Downloads
28
Checksum
ce26f898ba26eb49c71ebc68597f62f268b83e41bb265b1b5a01688966054588
Dependencies
None

many.rs

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");
}