Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_austenite/tools/bench/gen_synthetic.py

3.1 KiB, 1 run, executable

created by r1870400018:60941, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1#!/usr/bin/env python3
2"""Generates a deterministic synthetic Typst document for the S0 bench harness.
3
4No book content: every word is drawn from a small fixed vocabulary by a seeded
5PRNG, so the text carries no meaning and no licence. Each page mixes a heading,
6two or three prose paragraphs, and -- on every fifth page -- a small table or a
7maths block, so the document exercises more than the pure-text path without
8pulling in cetz or other package fixtures S0 was not asked to touch.
9
10Every paragraph opens with a sentinel token `EDITTOK{n}` (n = 1-based paragraph
11index across the whole document), so `edit_latency.mjs` can find paragraph N by
12string search and flip one character in it without parsing the document.
13
14Usage: gen_synthetic.py <pages> <out.typ>
15"""
16import random
17import sys
18
19VOCAB = (
20 "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod "
21 "tempor incididunt ut labore et dolore magna aliqua enim ad minim veniam "
22 "quis nostrud exercitation ullamco laboris nisi aliquip ex ea commodo "
23 "consequat duis aute irure in reprehenderit voluptate velit esse cillum "
24 "eu fugiat nulla pariatur excepteur sint occaecat cupidatat non proident"
25).split()
26
27
28def sentence(rng, n_words):
29 words = [rng.choice(VOCAB) for _ in range(n_words)]
30 words[0] = words[0].capitalize()
31 return " ".join(words) + "."
32
33
34def paragraph(rng, tok):
35 sentences = [sentence(rng, rng.randint(6, 14)) for _ in range(rng.randint(3, 6))]
36 return f"{tok} " + " ".join(sentences)
37
38
39def table_block(rng, page):
40 rows = []
41 for r in range(4):
42 cells = [str(rng.randint(0, 9999)) for _ in range(3)]
43 rows.append(" [" + "], [".join(cells) + "],")
44 body = "\n".join(rows)
45 return (
46 f"#table(\n columns: 3,\n [A], [B], [C],\n{body}\n)"
47 )
48
49
50def maths_block(rng, page):
51 a, b, c = rng.randint(2, 9), rng.randint(2, 9), rng.randint(2, 9)
52 return f"$ ({a}x + {b})^{c} = sum_(k=0)^{c} binom({c}, k) ({a}x)^k {b}^({c}-k) $"
53
54
55def main():
56 if len(sys.argv) != 3:
57 print("usage: gen_synthetic.py <pages> <out.typ>", file=sys.stderr)
58 sys.exit(2)
59 pages = int(sys.argv[1])
60 out_path = sys.argv[2]
61 rng = random.Random(20260923) # fixed seed: reproducible across runs and machines
62
63 lines = [
64 "// Generated by tools/bench/gen_synthetic.py -- synthetic, no book content.",
65 "// Regenerate rather than hand-edit; edit_latency.mjs depends on the EDITTOK",
66 "// markers below staying at paragraph-start.",
67 "#set page(width: 15cm, height: 21cm, margin: 2cm)",
68 "#set text(size: 10pt)",
69 "#set par(justify: true)",
70 "",
71 ]
72 tok = 0
73 for page in range(1, pages + 1):
74 lines.append(f"= Section {page}")
75 n_paras = 2 if page % 5 == 0 else 3
76 for _ in range(n_paras):
77 tok += 1
78 lines.append(paragraph(rng, f"EDITTOK{tok}"))
79 lines.append("")
80 if page % 10 == 0:
81 lines.append(maths_block(rng, page))
82 lines.append("")
83 elif page % 5 == 0:
84 lines.append(table_block(rng, page))
85 lines.append("")
86 if page != pages:
87 lines.append("#pagebreak()")
88 lines.append("")
89
90 with open(out_path, "w") as f:
91 f.write("\n".join(lines) + "\n")
92 print(f"wrote {out_path}: {pages} pages, {tok} paragraphs", file=sys.stderr)
93
94
95if __name__ == "__main__":
96 main()