A world-class math input for the web

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)