(defgroup translit-ru nil
"The major mode for typing in Russian translit"
:group 'languages)
(defvar *local-last-input* nil)
(defvar *latin-cyrillic-map*
'((97 . "а") (98 . "б") (99 . "ц") (100 . "д")
(101 . "е") (102 . "ф") (39 . "ь") (35 . "ъ")
(103 . "г") (104 . "х") (105 . "и") (106 . "й")
(107 . "к") (108 . "л") (109 . "м") (110 . "н")
(111 . "о") (112 . "п") (113 . "щ") (114 . "р")
(115 . "с") (116 . "т") (117 . "у") (118 . "в")
(119 . "щ") (120 . "х") (121 . "ы") (122 . "з")))
(defvar *latin-cyrillic-prefices*
'((106 . ((117 . "ю") (97 . "я") (101 . "э") (111 . "ё"))) ; j
(115 . ((104 . "ш"))) ; s
(99 . ((104 . "ч"))) ; c
(122 . ((104 . "ж"))))) ; z
(defun upcase-if-needed (c needed)
(if needed c (upcase c)))
(defun latin-to-cyrillic ()
(interactive)
(setq debug-on-error t)
(let* ((downcase-c (downcase last-input-char))
(matched-c (cdr (assq downcase-c *latin-cyrillic-map*)))
(continuation
(when *local-last-input*
(assq (downcase *local-last-input*)
*latin-cyrillic-prefices*)))
(completion (assq downcase-c continuation))
(last-input *local-last-input*)
(need-upcase (eq last-input-char downcase-c))
(reset-last (assq downcase-c *latin-cyrillic-prefices*)))
(setq *local-last-input* nil)
(cond
(completion
(insert (upcase-if-needed
(cdr completion)
(eq (downcase last-input) last-input))))
(last-input
(insert (upcase-if-needed
(cdr (assq (downcase last-input) *latin-cyrillic-map*))
(eq (downcase last-input) last-input)))
(when (and matched-c (not reset-last))
(insert (upcase-if-needed matched-c need-upcase))))
((and matched-c (not reset-last))
(insert (upcase-if-needed matched-c need-upcase)))
((not matched-c) (insert last-input-char)))
(when reset-last
(setq *local-last-input* last-input-char))))
(define-key (current-global-map)
[remap self-insert-command]
'latin-to-cyrillic)
;(define-key (current-global-map) [remap self-insert-command] 'self-insert-command)
(provide 'translit-ru)