;; 2006-10-03 LaTeX indexing utility
;; 2009-03-09 updated
(defun latex-insert-index-ja (begin end pre &optional key)
  "Insert \\index{key@term} using region text (or last killed text if
   with prefix arg) as index term. If the term is Japanese and the key is
   ommited, term's reading is copied as key."
  (interactive "r\nP\nsKey:")
  (let ((term (if pre
                  (caar *kill-ring*)
                  (buffer-substring begin end))))
    (insert (concat
             (if (or (equal key nil) (equal key ""))
                 (if (string-match "\\sj" term)
                     (concat (mecab-reading-katakana term) "@")
                 (concat key "@"))
             "}" )

(defvar kata
  (let ((str (concat "ァ ア ィ イ ゥ ウ ェ エ ォ オ "
                     "カ ガ キ ギ ク グ ケ ゲ コ ゴ "
                     "サ ザ シ ジ ス ズ セ ゼ ソ ゾ "
                     "タ ダ チ ヂ ッ ツ ヅ テ デ ト ド "
                     "ナ ニ ヌ ネ ノ "
                     "ハ バ パ ヒ ビ ピ フ ブ プ ヘ ベ ペ ホ ボ ポ "
                     "マ ミ ム メ モ "
                     "ャ ヤ ュ ユ ョ ヨ "
                     "ラ リ ル レ ロ ゎ ワ ゐ ゑ ヲ ン")))
    (mapcar 'character (split-string str " "))))

(defvar hira
  (let ((str (concat "ぁ あ ぃ い ぅ う ぇ え ぉ お "
                     "か が き ぎ く ぐ け げ こ ご "
                     "さ ざ し じ す ず せ ぜ そ ぞ "
                     "た だ ち ぢ っ つ づ て で と ど "
                     "な に ぬ ね の "
                     "は ば ぱ ひ び ぴ ふ ぶ ぷ へ べ ぺ ほ ぼ ぽ "
                     "ま み む め も "
                     "ゃ や ゅ ゆ ょ よ "
                     "ら り る れ ろ ゎ わ ゐ ゑ を ん")))
    (mapcar 'character (split-string str " "))))

(defun translate-char (chr from-dict to-dict)
  (let* ((dic (mapcar (lambda (x y) (list* x y)) from-dict to-dict))
         (counterpart (cdr (assoc chr dic :test 'equal))))
    (if counterpart counterpart chr)))

(defun kata-to-hira-char (chr) (translate-char chr kata hira))
(defun hira-to-kata-char (chr) (translate-char chr hira kata))
(defun kata-to-hira-string (str) (map 'string 'kata-to-hira-char str))
(defun hira-to-kata-string (str) (map 'string 'hira-to-kata-char str))

(defun filter-region (f begin end)
  (let ((src (buffer-substring begin end)))
      (delete-region begin end)
      (insert (funcall f src)))))

(defun kata-to-hira-region (begin end)
  "Convert katakana in region to hiragana."
  (interactive "r")
  (filter-region kata-to-hira-string begin end))

(defun hira-to-kata-region (begin end)
  "Convert hiragana in region to katakana."
  (interactive "r")
  (filter-region hira-to-kata-string begin end))

(defun run-command (cmd &optional input) ;; thanks to snmsts
  "Run CMD as sub-process with INPUT for stdin. Return stdout as string."
  (let ((buf (create-new-buffer "tmp"))
          (setup-temp-buffer buf)
        (set-buffer buf)
        (setq proc (make-process cmd))
        (if input (process-send-string proc (concat input (string #\C-z)))
        (while (eql :run (process-status proc))
            (string-right-trim "\r\n" (buffer-substring (point-min) (point-max)))
          (delete-buffer buf))))))

(defun mecab-reading-katakana (str)
  "Acquire reading of Japanese text in katakana using MeCab morphological analyzer."
  (let* ((src-enc (detect-char-encoding str))
         (src-internal (convert-encoding-to-internal src-enc str))
         (src-sjis (convert-encoding-from-internal *encoding-sjis* src-internal))
         (src-utf8 (convert-encoding-from-internal *encoding-utf8* src-internal))
         (str src-utf8)
         (yomi (run-command "C:/Program Files/MeCab/bin/mecab.exe -Oyomi" str))
         (yomi-internal (convert-encoding-to-internal (detect-char-encoding yomi) yomi)))

(defun mecab-reading-hiragana (str)
  "Acquire reading of Japanese text in hiragana using MeCab morphological analyzer."
  (kata-to-hira-string (mecab-reading-katakana str)))