2010-12-08

Designing a Math Symbols Input System

Perm url with updates: http://xahlee.org/comp/design_math_symbol_input.html

Designing a Math Symbols Input System

Xah Lee, 2010-12-08

This article discuss some of my thoughts about the problem of a input system for entering math symbols and special characters.

In the past few years, i need to type math symbols a lot in emacs. In some hodgepodge way, i created several custom ways to enter special chars i need in emacs, such as: “” 【】〈 〉 「」 © • ◇ ◆ ★ × α θ λ ← → ⇒ ≠ ∞ etc. The system is hodgepodge, no-where consistent or comprehensive. In the back of my mind, i have this special char input system design problem, that someday i'll think about it and find a way that's efficient and comprehensive for inputing hundreds of special chars math in Unicode. When you need to type a lot special chars, there's a interface design issue, especially in emacs, because there are so many ways to do it.

AltGraph Key System vs Abbrev System

For example, first is simple method of using a modifer key (usually called AltGr) to insert special chars.

mac unicode char

Key maps from OS X's Keyboard Viewer (using a Dvorak Keyboard Layout), showing you what characters you can type using the option key. Those colored orange are prefix keys, allowing you to type combination characters such as “áéíóú”.

In this method, you press a key combination to insert a char. This is great solution if you just need a few chars that's frequently used. If you need more than say 50 chars, you need to add more modifier key combinations, it quickly become a problem of remembering which chars are what key. So, this method isn't good if you need to input a lot math for example, because there are few hundred of math symbols, and different people needs a slightly different set that's frequently used for them. (See: Math Symbols in UnicodeArrows in UnicodeMatching Brackets in Unicode)

(See also: Creating Keyboard Layout in Mac OS X.)

Other solution is to use abbreviation that becomes the char. For example, you type “alpha”, then press a hotkey, and it becomes “α”, and “inf” becomes “∞”, “>=” becomes “≥”, etc. While studying How Mathematica does Unicode?, i realized that this is the most practical, efficient, method, to input potentially large number of chars. Math symbols, and also common chars such as ‹ › « » ¢ € £ ¥ © ® ™ § ¶ † ‡ ※ ● ■ ◆ ↑ ↓ → ← ◀ ▶ ▲ ▼ etc. This way, instead of remembering some 100+ keys for the chars, you just type the name of the symbol, using full name or short abbrevs (1 to 5 chars). This is much easier to remember. Also, there's just one hotkey to remember.

When is Hotkey Pressed

The hotkey can be pressed first before you type the abbrev , or, it can be pressed after. Or, it can be completely eliminated by a automatic change.

For example of hotkey first, in emacs, you can press 【Ctrl+x 8】 then a abbrev to enter chars such as ¿¡¢£¥¤§®©ª «» ×÷¬ °±µ¶ ÀÁÂÃÄÅÆ Ç ÈÉÊË ÌÍÎÏ ÐÑ ÒÓÔÕÖ ØÙÚÛÜÝÞß àáâãäåæç èéêë ìíîï ðñòóôõö øùúûüýþÿ. (See: Emacs and Unicode Tips.)

In Mathematica, you press 【Esc abbrev Esc】 to insert a special char. (See: How Mathematica does Unicode?.)

For automatic abbrev, both emacs and Microsoft Word and many editors support that. For example, in Word, typing 「"something"」 automatically becomes 「“something”」 . The automatic change method is great, but the problem is that if you have hundreds of abbrevs, often some of them are common words too, which you do not want to automatically become a special char.

I decided that pressing a hotkey afterwards is the best option.

Changes to my Emacs Elisp Code

So, yesterday, i started to organize my several elisp code related to inputing special math symbols to a unified minor mode. For example, i had the following code that setsup a emacs hyper key to insert chars:

(global-set-key (kbd "H-y <up>") (lambda () (interactive) (insert "↑"))) ; up arrow
(global-set-key (kbd "H-y <down>") (lambda () (interactive) (insert "↓"))) ; down arrow
(global-set-key (kbd "H-y <left>") (lambda () (interactive) (insert "←"))) ; left arrow
(global-set-key (kbd "H-y <right>") (lambda () (interactive) (insert "→"))) ; right arrow
(global-set-key (kbd "H-y <kp-6>") (lambda () (interactive) (insert "⇒"))) ; RIGHTWARDS DOUBLE ARROW
(global-set-key (kbd "H-y <kp-add>") (lambda () (interactive) (insert "⊕"))) ; CIRCLED PLUS
(global-set-key (kbd "H-y *") (lambda () (interactive) (insert "⊗"))) ; CIRCLED TIMES
(global-set-key (kbd "H-y <kp-multiply>") (lambda () (interactive) (insert "×"))) ; MULTIPLICATION SIGN
(global-set-key (kbd "H-y <") (lambda () (interactive) (insert "≤"))) ; greater htan
(global-set-key (kbd "H-y >") (lambda () (interactive) (insert "≥"))) ; less than
(global-set-key (kbd "H-y Z") (lambda () (interactive) (insert "ℤ"))) ; integer
(global-set-key (kbd "H-y Q") (lambda () (interactive) (insert "ℚ"))) ; rational
(global-set-key (kbd "H-y R") (lambda () (interactive) (insert "ℝ"))) ; real
(global-set-key (kbd "H-y C") (lambda () (interactive) (insert "ℂ"))) ; complex
(global-set-key (kbd "H-y a") (lambda () (interactive) (insert "α"))) ; alpha
(global-set-key (kbd "H-y b") (lambda () (interactive) (insert "β"))) ; beta
(global-set-key (kbd "H-y g") (lambda () (interactive) (insert "γ"))) ; gamma
(global-set-key (kbd "H-y t") (lambda () (interactive) (insert "θ"))) ; theta
(global-set-key (kbd "H-y l") (lambda () (interactive) (insert "λ"))) ; lambda
(global-set-key (kbd "H-y p") (lambda () (interactive) (insert "π"))) ; pi
(global-set-key (kbd "H-y A") (lambda () (interactive) (insert "∀"))) ; FOR ALL
(global-set-key (kbd "H-y E") (lambda () (interactive) (insert "∃"))) ; THERE EXISTS
(global-set-key (kbd "H-y ^") (lambda () (interactive) (insert "∧"))) ; and
(global-set-key (kbd "H-y 6") (lambda () (interactive) (insert "∨"))) ; or
(global-set-key (kbd "H-y !") (lambda () (interactive) (insert "¬"))) ; not
(global-set-key (kbd "H-y =") (lambda () (interactive) (insert "≡"))) ; equivalent
(global-set-key (kbd "H-y +") (lambda () (interactive) (insert "≠"))) ; not equal
(global-set-key (kbd "H-*") (lambda () (interactive) (insert "°"))) ; degree

I also had Emacs Abbrev:

(define-abbrev-table 'global-abbrev-table '(
    ;; math/unicode symbols
    ("tin" "∈" nil 0)
    ("nin" "∉" nil 0)
    ("inf" "∞" nil 0)
    ("luv" "♥" nil 0)
    ("smly" "☺" nil 0)
    ;;...
)

Now they are all gone. In replacement is a emacs minor mode xmsi-math-symbols-input.el Emacs xmsi-mode for Math Symbols Input , which i'm still working on, to add all TeX/LaTex and HTML/XML char entities names.

Was this page useful? If so, please do donate $3, thank you donors!