Designing a Math Symbols Input System

, , …,

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 nowhere consistent or comprehensive. In the back of my mind, i thought that someday i'll think about it and find a way that's efficient and comprehensive for inputting hundreds of math chars. When you need to type a lot special chars, there's a interface design issue, because there are so many ways to do it.

AltGraph Key System vs Abbrev System

AltGraph Key System

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

mac Unicode char
Keymap from Mac OS X Keyboard Viewer (with Dvorak Keyboard Layout), showing you what characters you can type using the ⌥ Opt 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 have different set of chars that's frequently used for them. (See: Math Symbols in UnicodeArrows in UnicodeMatching Brackets in Unicode)

(For how to do this on Mac, see: Creating Keyboard Layout in Mac OS X.)

Abbrev System

Other solution is to use abbreviation. For example, you type “a”, 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 large number of chars. Math symbols, and also common chars such as ‹ › « » ¢ € £ ¥ © ® ™ § ¶ † ‡ ※ ● ■ ◆ ↑ ↓ → ← ◀ ▶ ▲ ▼ etc. This way, you don't have to remember hundreds of key combination for each char. You just type the name of the symbol, using full name or short abbrevs (1 to 5 letters).

The advantage of this method are:

The disadvantage is that it's slower. If you need let's say only 10 to 30 chars that you need to type every few minutes, for example, say the acute e é in some language, then the direct input by AltGraph is much better.

However, the 2 methods can both be used. That is, have a AltGraph layout, but also have the abbrev system.

When is Hotkey Pressed

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

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

In Mathematica, you press 【Esc ‹abbrev› Esc】 to insert a special char. 〔➤ How Mathematica does Unicode?

For automatic abbrev expansion, both emacs and Microsoft Word and many editors support that. For example, in Word, typing, typing (c) auto-becomes “©”. 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. For example, you don't want “not” to always automatically become the logic symbol ¬, or this “>=” becoming in programing source code.

Changes to my Emacs Elisp Code

So, yesterday, i started to organize my several elisp code related to inputting special math symbols to a unified minor mode. For example, i had the following code that sets up 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" "∈")
    ("nin" "∉")
    ("inf" "∞")
    ("luv" "♥")
    ("smly" "☺")
    ;;))

Now they are all gone. In replacement is a emacs minor mode Emacs Math Symbols Input Mode (xmsi-mode).

blog comments powered by Disqus