| 1 | """Author equations through OneNote 2010's equation editor on a Rust-written page and capture |
| 2 | the COM read, which exports each equation as MathML: the oracle for `onestore::page::Math`. |
| 3 | |
| 4 | Usage: native_math.py NOTEBOOK_DIR OUTPUT_DIR |
| 5 | """ |
| 6 | import base64 |
| 7 | import json |
| 8 | import os |
| 9 | import sys |
| 10 | from pathlib import Path |
| 11 | import xml.etree.ElementTree as ET |
| 12 | |
| 13 | sys.path.insert(0, str(Path(__file__).resolve().parent)) |
| 14 | import native_runner as runner |
| 15 | |
| 16 | windows = runner.windows |
| 17 | |
| 18 | # Linear-format input, one equation per paragraph; a space builds each expression up. |
| 19 | EQUATIONS = [ |
| 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 | ] |
| 27 | if os.environ.get('ONESTORE_MATH_EQUATIONS'): |
| 28 | EQUATIONS = os.environ['ONESTORE_MATH_EQUATIONS'].split('|') |
| 29 | |
| 30 | |
| 31 | def 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) |
| 45 | WinWait("ahk_exe ONENOTE.EXE", , 30) |
| 46 | WinActivate("ahk_exe ONENOTE.EXE") |
| 47 | WinWaitActive("ahk_exe ONENOTE.EXE", , 30) |
| 48 | WinMaximize("ahk_exe ONENOTE.EXE") |
| 49 | Sleep(3000) |
| 50 | CoordMode("Mouse", "Screen") |
| 51 | Click(300, 140) |
| 52 | Sleep(500) |
| 53 | Send("{End}") |
| 54 | Sleep(300) |
| 55 | Send("{Enter}") |
| 56 | Sleep(500) |
| 57 | %s |
| 58 | Sleep(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 | |
| 71 | if __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) |