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.

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

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 Unicode ◇ Arrows in Unicode ◇ Matching Brackets in Unicode)

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

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:

- Good for large number of chars. (⁖ above 100)
- This is much easier to remember.
- There's just one hotkey to remember.

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.

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. 〔➤ 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)`

automatically 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.

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: xah-math-input.el.