Use cases to account for: - Typing math expressions - Invalid and incomplete expressions - Empty slots (like an exponent with nothing typed in it yet) - Unpaired brakets - Live editing/multiplayer (CRDT or OT) - Editable/static - Fully editable input - Fully static input - Editable slot embedded within static - Deeper nesting–editable within static within editable... - Syntax highlighting - Plugins (allow new types of things to be defined within the AST as a plugin; for example, a new operator or the concept of matrices) - Programmatic edits being performed without losing cursor position & focus state - Embedding non-math elements within math (such as a plain text input, an image, a footnote marker, an emoji, etc) - Use within multiple component systems (React/Svelte/Vue/etc) or without one Design decisions: - Use plugins to define... a. Types of nodes in the AST b. How to respond to keyboard events (or maybe how to handle operations; can plugins define new types of operations?) c. Rules about what nodes are allowed to contain d. How to render/display output (perhaps in a constrained way to maintain consistency–maybe the plugin generates some representation of what to display, but does not directly touch the DOM) e. Post-processing that happens between completion of AST and render time (eg. syntax highlighting, custom syntax highlighting for a specific use case or based on external knowledge) f. Styling (allow styles to be fully customized by a plugin, including performing logic and then styling based on that–see syntax highlighting) g. Styling & appearance of cursors/selections - Define in the core... - Accepting keyboard events using a hidden input - What a "location" is and how that enables cursors/ranges - Explicitly encode editing events as operations - Keyboard event --> operation --> updated state & focus/cursor - Handle multiplayer/syncing of operations - Minimal dependencies; no reliance on a component library (but provide thin wrapper libraries in many component systems)