1"""Author equations through OneNote 2010's equation editor on a Rust-written page and capture
2the COM read, which exports each equation as MathML: the oracle for `onestore::page::Math`.
3
4Usage: native_math.py NOTEBOOK_DIR OUTPUT_DIR
5"""
6import base64
7import json
8import os
9import sys
10from pathlib import Path
11import xml.etree.ElementTree as ET
12
13sys.path.insert(0, str(Path(__file__).resolve().parent))
14import native_runner as runner
15
16windows = runner.windows
17
18# Linear-format input, one equation per paragraph; a space builds each expression up.
19EQUATIONS = [
20 'a_1+b_2',
21 '\\sqrt(x+1)',
22 'x_i^2',
23 '(a+b)',
24 '\\int_0^1 x dx',
25 '\\sum_(i=1)^n i',
26]
27if os.environ.get('ONESTORE_MATH_EQUATIONS'):
28 EQUATIONS = os.environ['ONESTORE_MATH_EQUATIONS'].split('|')
29
30
31def interaction(name, output):
32 lines = []
33 for equation in EQUATIONS:
34 lines.append('Send("!=")')
35 lines.append('Sleep(600)')
36 lines.append('SendText("%s")' % equation.replace('"', '""'))
37 lines.append('Send(" ")')
38 lines.append('Sleep(600)')
39 lines.append('Send("{End}")')
40 lines.append('Sleep(300)')
41 lines.append('Send("{Enter}")')
42 lines.append('Sleep(600)')
43 page = ET.parse(sorted((output / 'read').glob('page-*.xml'))[0]).getroot().attrib['ID']
44 script = '''ComObject("OneNote.Application").NavigateTo("PAGE_ID", "", false)
45WinWait("ahk_exe ONENOTE.EXE", , 30)
46WinActivate("ahk_exe ONENOTE.EXE")
47WinWaitActive("ahk_exe ONENOTE.EXE", , 30)
48WinMaximize("ahk_exe ONENOTE.EXE")
49Sleep(3000)
50CoordMode("Mouse", "Screen")
51Click(300, 140)
52Sleep(500)
53Send("{End}")
54Sleep(300)
55Send("{Enter}")
56Sleep(500)
57%s
58Sleep(2000)
59''' % '\n'.join(lines)
60 script = script.replace('PAGE_ID', page)
61 (output / 'equations.ahk').write_text(script)
62 result = windows.do_exec(script, target=name, timeout_ms=180000, shot_delay_ms=1500)
63 screenshot = result.pop('png_b64', None)
64 if screenshot:
65 (output / 'equations.png').write_bytes(base64.b64decode(screenshot))
66 (output / 'equations.json').write_text(json.dumps(result, indent=2))
67 if result.get('error') or result.get('exit') != 0:
68 raise RuntimeError(str(result))
69
70
71if __name__ == '__main__':
72 notebook, output = Path(sys.argv[1]), Path(sys.argv[2])
73 runner.capture(notebook, output, expected_pages=1, collect_notebook=True, interaction=interaction)