;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 花鳥の設定（必須）
;;; ロードパスに KaTeX のあるディレクトリを追加
(push (merge-pathnames "site-lisp/katex" (si:system-root)) *load-path*)
;;; elispパッケージを有効にする
(require "elisp")
;;; 拡張子と関数の関連付け
;;; （拡張子“.ins”,“.ini”は Windows 上で TeX 関連以外のプログラムと関連付けられており，
;;;   拡張子“.def”,“.cfg”は TeX 関連以外のプログラムでもよく使われているので，
;;;   この4つの拡張子は含めていない。）
(push '("\\.\\(tex\\|aux\\|toc\\|lof\\|lot\\|idx\\|ind\\|glo\\|gls\\|bbl\\|sty\\|cls\\|clo\\|dtx\\|fdd?\\|ltx\\|dfu\\|4ht\\)$" . elisp::katex-mode) *auto-mode-alist*)
;;; オートロード
(autoload 'elisp::katex-mode "katex" t)
;;; タイプセットを pTeX で
(setf elisp::tex-command "platex -src -interaction=batchmode")

;; 花鳥の設定（オプション）
; M-x katex-mode で花鳥を起動 [xyzzy:07770]より
(defun katex-mode()
  (interactive)
  (elisp::katex-mode))
; かてふツールバーを使う
;(setf elisp::*KaTeX-use-toolbar* t)
; jsarticle をデフォルトにする
(setf elisp::KaTeX-default-documentclass "jsarticle")
; M-RET
(set-extended-key-translate-table exkey-M-return #\M-RET)
; タイプセットバッファの高さを調整　[xyzzy:07590]より
(setf elisp::KaTeX-default-pop-window-height "3")
; 自動改行をやめる [xyzzy:07892]より
(add-hook 'elisp::katex-mode-hook
            #'(lambda ()
              (auto-fill-mode nil)))
; ショートカット
(defun user::katex-mode ()
  (interactive)
  (elisp::katex-mode))
; Windowsっぽいキーバインド（コピー，貼り付けなど）
;(load-library "winkey")
(load-library "pavail")

(setq elisp::KaTeX-use-AMS-LaTeX t) ; AMS-LaTeXを使う
(setq elisp::KaTeX-math-need-image t) ; 数式モードでTABを押したときにイメージを表示する
(setq elisp::*KaTeX-math-formats*
      (compile-regexp-keyword-list
       '(("\\$[^$]*\\$" t (:keyword 2) nil)))) ; 正規表現での色付け
; [色表示の指定]の部分は、xyzzyのChangeLog.htmlの
;    Mon Jul 02 2001 Version 0.2.2.202
; 付近をみる

;;; paren or parentag
(require "paren")
(turn-on-paren) ;常に paren を使いたいとき
;; paren を KaTeXモードに対応
(add-hook 'elisp::katex-mode-hook #'(lambda()
  (set-syntax-match (syntax-table) #\( #\))
  (set-syntax-match (syntax-table) #\{ #\})
  (set-syntax-match (syntax-table) #\[ #\])
))
; http://white.s151.xrea.com/wiki/index.php?script%2Fparen より
;; paren強調前の強調を常に
;(setq-default *paren-continue-original-attribute* t)
;; tagは強調しない (<とか>とか)
;(setq-default *paren-tag-highlight* nil)

;; KaTeX からその他のコマンドを実行できるように改造
(in-package "elisp")
(require "katex")
;;
(defun KaTeX-typeset-menu (arg &optional char)
  "Typeset, preview, visit error and miscellaneous convenient menu.
Optional second argument CHAR is for non-interactive call from menu."
  (interactive "P")
  (message
   (concat "J)latex R)egion B)ibtex mk(I)ndex "
	   (if (fboundp 'start-process) "K)ill-latex ")
	   "P)review "
	   (and (boundp 'window-system) window-system "S)earch ")
	   "V)iewerr L)pr D)vips dvipdF)m"
	   ;; ここでさらにコマンドを追加する場合は説明文をダブルクウォート (") で区切って
	   ;; 追加する。ここでは「O)ut2uni」というのをスペースのあとに追加する。
	   ;; 2つ以上追加したい場合（ここでは「A)command」というのを追加する）は
	   ;; 例えば「O)ut2uni」のあとにスペースで区切り，
	   ;; " O)ut2uni A)command"
	   ;; のように書く。
	   ;;
	   ;; ここから
	   
           ;; " O)ut2uni"
              " T)ex2pdf"
	   
	   ;; ここまで
	   ))
  (let ((pre-ime (and (get-ime-mode) (toggle-ime)))
	(sw (selected-window)) (c (or char (read-char))))
    (require "katexprc") ;for Nemacs's bug
    (select-window sw)
    (cond
     ((= c #\j) (KaTeX-typeset-buffer))
     ((= c #\r) (KaTeX-typeset-region))
     ((= c #\b) (KaTeX-call-command-on-file
		 bibtex-command "*KaTeX-bibtex*"))
     ((= c #\i) (KaTeX-call-command-on-file
		 makeindex-command "*KaTeX-makeindex*"))
     ((= c #\k) (KaTeX-kill-typeset-process KaTeX-typeset-process))
     
     ((= c #\p) (call-interactively 'KaTeX-preview))
     ;((= c #\q) (KaTeX-system "lpq" "*Printer queue*"))
     ((= c #\v) (KaTeX-view-error))
     ((= c #\l) (KaTeX-lpr arg))
     ((= c #\m) (KaTeX-switch-mode-menu arg))
     ((= c #\b) (KaTeX-insert-string "\\")) ;???
     ;((= c #\s) (KaTeX-xdvi-remote-search arg))
     ;; -----------------------------------------------------------
     ;; added command
     ((= c #\d) (KaTeX-dvi2ps))
     ((= c #\f) (KaTeX-dvipdfm))
     ;; さらに加えたいコマンドを「ここから」から「ここまで」まで以下に次の様式で記入します。
     ;; ((= c #\【Ctrl + c, t の後に押すキーボード】) (【コマンドを実行するための関数名】))
     ;; 一例では Ctrl + c, t そして“o”の順に押すキーボードショートカットに
     ;; “KaTeX-out2uni”という関数を割り当てます。
     ;; 2つ以上関数を割り当てる場合は，上の added command の下のように改行するなりして並べます。
     ;;
     ;; ここから
    
     ;; ((= c #\o) (KaTeX-out2uni))
        ((= c #\t) (KaTeX-tex2pdf))
     
     ;; ここまで
     )
    (and pre-ime (not (get-ime-mode)) (toggle-ime))))
(KaTeX-define-key #\t 'KaTeX-typeset-menu)
;;
(defvar dvips-command "dvipsk -Pdl")
(defun KaTeX-dvi2ps ()
(interactive)
(KaTeX-save-buffers)
(KaTeX-call-command-on-file dvips-command KaTeX-typeset-buffer))
;;
(defvar dvipdfm-command "dvipdfmx ")
(defun KaTeX-dvipdfm ()
(interactive)
(KaTeX-save-buffers)
(KaTeX-call-command-on-file dvipdfm-command KaTeX-typeset-buffer))

;;; 実際にコマンドを呼び出す関数を作ります。
;;; 先ほど，“KaTeX-out2uni”という関数に Ctrl + c, t, o というキーボードショートカットを
;;; 割り当てました。これは「out2uni （現在編集中のファイルから拡張子を抜いたファイル名）」という外部コマンドを呼び出す関数です。
;;; あとは次のテンプレートを参考に，見よう見まねで作ってください。
;;; 複数以上コマンドを割り当てるときは defvar から KaTeX-call-command-on-file の行まで追記します。
;;;
;;; (defvar 【適当な分かりやすい変数の名前。なんでもいい。】 "【呼び出すコマンド。最後のスペースをお忘れなく】")
;;; (defun 【先ほどキーボードショートカットに割り当てた関数名】 ()
;;; (interactive)
;;; (KaTeX-save-buffers)
;;; (KaTeX-call-command-on-file 【先ほど defvar... で記述した変数の名前】 KaTeX-typeset-buffer))
;;; 自作した各種コマンド起動関数，たとえば多言語関連で後述する UTF82TeX などを起動する関数
;;; などについてもこの下に記入します。
;;;
;;; ここから

;;(defvar out2uni-command "out2uni ")
;;(defun KaTeX-out2uni ()
;;  (interactive)
;;  (KaTeX-save-buffers)
;;  (KaTeX-call-command-on-file out2uni-command KaTeX-typeset-buffer))

(defvar tex2pdf-command "tex2pdf.cmd")
(defun KaTeX-tex2pdf ()
  (interactive)
  (KaTeX-save-buffers)
  (KaTeX-call-command-on-file tex2pdf-command KaTeX-typeset-buffer))

;;; ここまで

;; 動的補完
;;; keyword list
(defvar *my-latex-completion-list* nil)
(defvar *my-latex-popup-completion-list* :always)
(defvar *my-latex-keyword-hash-table* nil)
(defvar *my-latex-keyword-file* "~/site-lisp/texkey")

(defun my-latex-completion ()
  (interactive)
  (or *my-latex-completion-list*
      (setq *my-latex-completion-list* (make-list-from-keyword-table *my-latex-keyword-hash-table*))
      (return-from my-latex-completion nil))
  (let ((opoint (point)))
    ;(when (skip-syntax-spec-backward "w_.")
    (when (skip-syntax-spec-backward "w_.@")
      (let ((from (point)))
        (goto-char opoint)
        (do-completion from opoint :list *my-latex-completion-list*
                      nil nil *my-latex-popup-completion-list*)))))

(defun my-latex-load-keyword ()
  (and *my-latex-keyword-file*
       (null *my-latex-keyword-hash-table*)
       (setq *my-latex-keyword-hash-table*
             (load-keyword-file *my-latex-keyword-file* t))))

(add-hook 'elisp::katex-mode-hook
         #'(lambda ()
             (my-latex-load-keyword)
             (define-key elisp::*KaTeX-mode-map* #\C-. 'my-latex-completion)))

;; outline-tree 2
(require "outline-tree/outline-tree")
;;アウトラインツリーにフォーカスを移動させる操作を Ctrl + Tab，
;;アウトラインツリーの作成・更新を Ctrl + Enter 
;;というショートカットキーボードでできるような設定方法を以下に示します。
;;; extended-key-translate-table 設定
(set-extended-key-translate-table exkey-C-tab #\F23) ; focus
(set-extended-key-translate-table exkey-C-return #\F20) ; reload
;;; Editor <-> TreeView
 ;; Editor -> TreeView
(require "treeview/setup")
(global-set-key #\F23 'treeview::treeview-focus-treeview)
 ;; TreeView (outline-tree) -> Editor
(require "outline-tree/outline-tree")
(define-key outline-tree2::*outline-tree-map*
            #\F23 'treeview::treeview-focus-editor)
;;; outline 更新
(global-set-key #\F20 'outline-tree2::outline-tree-create-outline-and-select-node)
(define-key outline-tree2::*outline-tree-map*
                  #\F20  'outline-tree2::outline-tree-create-outline-and-select-node)
;;; outline-tree LaTeX
(in-package "outline-tree2")
(defun my-outline-tree-get-create-outline-function (buffer)
(let ((buffer-name (buffer-name buffer))
(buffer-mode (save-excursion (set-buffer buffer) buffer-mode))
(mode-name (save-excursion (set-buffer buffer) mode-name)))
(cond
((and (symbolp 'outline-tree2::outline-tree-create-outline-LaTeX)
(fboundp 'outline-tree2::outline-tree-create-outline-LaTeX)
(string-matchp "\\.tex$" buffer-name))
'outline-tree2::outline-tree-create-outline-LaTeX)
(t nil))))
(setq *outline-tree-get-default-create-outline-function-advice-func*
'my-outline-tree-get-create-outline-function) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; バックアップディレクトリ
(require "backup")
(setq *backup-directory* "~/backup/")
(setq *hierarchic-backup-directory* t)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
