yuuji@395: ;;; yatexlib.el --- YaTeX and yahtml common libraries -*- coding: sjis -*- yuuji@287: ;;; yuuji@515: ;;; (c)1994-2018 by HIROSE Yuuji.[yuuji@yatex.org] yuuji@562: ;;; Last modified Wed Jan 16 07:55:43 2019 on firestorm yuuji@366: ;;; $Id$ yuuji@23: yuuji@287: ;;; Code: yuuji@451: yuuji@451: ;; High-precedence compatible function yuuji@451: (fset 'YaTeX-str2int yuuji@451: (if (fboundp 'string-to-number) yuuji@451: (function yuuji@451: (lambda (string &optional base) yuuji@451: (ceiling (string-to-number string base)))) yuuji@451: 'string-to-int)) yuuji@451: yuuji@64: ;; General variables yuuji@64: (defvar YaTeX-dos (memq system-type '(ms-dos windows-nt OS/2))) yuuji@79: (defvar YaTeX-macos (memq system-type '(darwin))) yuuji@451: (defvar YaTeX-emacs-19 (>= (YaTeX-str2int emacs-version) 19)) yuuji@451: (defvar YaTeX-emacs-20 (>= (YaTeX-str2int emacs-version) 20)) yuuji@451: (defvar YaTeX-emacs-21 (>= (YaTeX-str2int emacs-version) 21)) yuuji@64: (defvar YaTeX-user-completion-table yuuji@64: (if YaTeX-dos "~/_yatexrc" "~/.yatexrc") yuuji@64: "*Default filename in which user completion table is saved.") yuuji@64: yuuji@72: (defvar YaTeX-display-color-p yuuji@72: (or (and (fboundp 'display-color-p) (display-color-p)) yuuji@72: (and (fboundp 'device-class) yuuji@72: (eq 'color (device-class (selected-device)))) yuuji@72: window-system) ; falls down lazy check.. yuuji@72: "Current display's capability of expressing colors.") yuuji@72: yuuji@79: (defvar YaTeX-japan yuuji@79: (or (boundp 'NEMACS) yuuji@79: (boundp 'MULE) yuuji@79: (and (boundp 'current-language-environment) yuuji@79: (string-match "[Jj]apanese" current-language-environment))) yuuji@64: "Whether yatex mode is running on Japanese environment or not.") yuuji@64: yuuji@70: ;; autoload from yahtml.el yuuji@70: (autoload 'yahtml-inner-environment-but "yahtml" "yahtml internal func." t) yuuji@70: yuuji@80: (defvar latex-message-kanji-code 2 yuuji@80: "*Kanji coding system latex command types out. yuuji@80: 1 = Shift JIS, 2 = JIS, 3 = EUC. 4 = UTF-8") yuuji@80: yuuji@64: (defvar YaTeX-kanji-code-alist yuuji@64: (cond yuuji@64: ((boundp '*junet*) yuuji@77: (list '(0 . *noconv*) yuuji@77: (cons yuuji@64: 1 yuuji@79: (cond yuuji@79: (YaTeX-dos (if (boundp '*sjis-dos*) *sjis-dos* *sjis*dos)) yuuji@79: (YaTeX-macos (if (boundp '*sjis-mac*) *sjis-mac* *sjis*mac)) yuuji@79: (t *sjis*))) yuuji@64: '(2 . *junet*) '(3 . *euc-japan*))) yuuji@80: ((and YaTeX-emacs-20 (featurep 'mule)) yuuji@64: ;;(cdr-safe(assq 'coding-system (assoc "Japanese" language-info-alist))) yuuji@77: (list '(0 . no-conversion) yuuji@77: (cons yuuji@64: 1 (cond (YaTeX-dos 'shift_jis-dos) yuuji@79: (YaTeX-macos 'shift_jis-mac) yuuji@64: ((member 'shift_jis (coding-system-list)) 'shift_jis-unix) yuuji@64: (t 'sjis))) yuuji@68: '(2 . iso-2022-jp-unix) yuuji@80: '(3 . euc-jp-unix) yuuji@80: '(4 . utf-8)))) yuuji@64: "Kanji-code expression translation table.") yuuji@64: (defvar YaTeX-inhibit-prefix-letter nil yuuji@64: "*T for changing key definitions from [prefix] Letter to [prefix] C-Letter.") yuuji@64: yuuji@64: (defvar YaTeX-no-begend-shortcut nil yuuji@64: "*T for disabling shortcut of begin-type completion, [prefix] b d, etc.") yuuji@64: yuuji@64: (defvar YaTeX-default-pop-window-height 10 yuuji@64: "Default typesetting buffer height. yuuji@64: If integer, sets the window-height of typesetting buffer. yuuji@64: If string, sets the percentage of it. yuuji@64: If nil, use default pop-to-buffer.") yuuji@64: yuuji@64: (defvar YaTeX-create-file-prefix-g nil yuuji@64: "*Non-nil creates new file when [prefix] g on \\include{foo}.") yuuji@64: yuuji@64: (defvar YaTeX-nervous t yuuji@64: "*If you are nervous about maintenance of yatexrc, set this value to T. yuuji@64: And you will have the local dictionary.") yuuji@64: yuuji@72: (defvar YaTeX-use-italic-bold (string< "20" emacs-version) yuuji@72: "*Non-nil tries to find italic/bold fontset. yuuji@72: This variable is effective when font-lock is used. yuuji@72: \it, \bf 内部での日本語が□になってしまう場合はこれをnilにして下さい。") yuuji@72: yuuji@64: ;----------- work variables ---------------------------------------- yuuji@80: (defvar YaTeX-minibuffer-completion-map nil yuuji@80: "Minibuffer completion key map that allows comma completion.") yuuji@80: (if YaTeX-minibuffer-completion-map nil yuuji@80: (setq YaTeX-minibuffer-completion-map yuuji@80: (copy-keymap minibuffer-local-completion-map)) yuuji@80: (define-key YaTeX-minibuffer-completion-map " " yuuji@80: 'YaTeX-minibuffer-complete) yuuji@80: (define-key YaTeX-minibuffer-completion-map "\t" yuuji@80: 'YaTeX-minibuffer-complete)) yuuji@80: yuuji@64: (defvar YaTeX-typesetting-mode-map nil yuuji@69: "Keymap used in YaTeX typesetting buffer") yuuji@69: yuuji@64: (if YaTeX-typesetting-mode-map nil yuuji@64: (setq YaTeX-typesetting-mode-map (make-keymap)) yuuji@64: ;(suppress-keymap YaTeX-typesetting-mode-map t) yuuji@64: (define-key YaTeX-typesetting-mode-map " " 'YaTeX-jump-error-line) yuuji@64: (define-key YaTeX-typesetting-mode-map "\C-m" 'YaTeX-send-string) yuuji@64: (define-key YaTeX-typesetting-mode-map "1" 'delete-other-windows) yuuji@64: (define-key YaTeX-typesetting-mode-map "0" 'delete-window) yuuji@64: (define-key YaTeX-typesetting-mode-map "q" 'delete-window)) yuuji@64: yuuji@64: (defvar YaTeX-parent-file nil yuuji@64: "*Main LaTeX source file name used when %#! expression doesn't exist.") yuuji@64: (make-variable-buffer-local 'YaTeX-parent-file) yuuji@64: yuuji@64: ;---------- Define default key bindings on YaTeX mode map ---------- yuuji@64: ;;;###autoload yuuji@503: (defun YaTeX-kanji-ptex-mnemonic () yuuji@503: "Return the kanji-mnemonic of pTeX from current buffer's coding-system." yuuji@503: (if (boundp 'NEMACS) yuuji@503: (or (cdr-safe (assq kanji-fileio-code yuuji@503: '((1 . "sjis") (2 . "jis") (3 . "euc")))) yuuji@503: "") yuuji@503: (let ((coding yuuji@503: (cond yuuji@503: ((boundp 'buffer-file-coding-system) yuuji@562: (symbol-name (if (fboundp 'coding-system-name) yuuji@562: (coding-system-name buffer-file-coding-system) yuuji@562: buffer-file-coding-system))) yuuji@503: ((boundp 'file-coding-system) (symbol-name file-coding-system)))) yuuji@503: (case-fold-search t)) yuuji@529: (cond ((string-match "utf-8\\>" coding) "utf8") yuuji@503: ((string-match "shift.jis\\|cp932\\>" coding) "sjis") yuuji@503: ((string-match "junet\\|iso.2022" coding) "jis") yuuji@503: ((string-match "euc.jp\\|ja.*iso.8bit" coding) "euc") yuuji@503: (t ""))))) yuuji@503: yuuji@503: ;;;###autoload yuuji@64: (defun YaTeX-define-key (key binding &optional map) yuuji@64: "Define key on YaTeX-prefix-map." yuuji@64: (if YaTeX-inhibit-prefix-letter yuuji@64: (let ((c (aref key 0))) yuuji@64: (cond yuuji@64: ((and (>= c ?a) (<= c ?z)) (aset key 0 (1+ (- c ?a)))) yuuji@64: ((and (>= c ?A) (<= c ?Z) (numberp YaTeX-inhibit-prefix-letter)) yuuji@64: (aset key 0 (1+ (- c ?A)))) yuuji@64: (t nil)))) yuuji@64: (define-key (or map YaTeX-prefix-map) key binding)) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-local-table-symbol (symbol) yuuji@64: "Return the lisp symbol which keeps local completion table of SYMBOL." yuuji@64: (intern (concat "YaTeX$" yuuji@64: default-directory yuuji@64: (symbol-name symbol)))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-sync-local-table (symbol) yuuji@64: "Synchronize local variable SYMBOL. yuuji@64: Copy its corresponding directory dependent completion table to SYMBOL." yuuji@64: (if (boundp (YaTeX-local-table-symbol symbol)) yuuji@64: (set symbol (symbol-value (YaTeX-local-table-symbol symbol))))) yuuji@64: yuuji@64: (defvar YaTeX-user-table-is-read nil yuuji@64: "Flag that means whether user completion table has been read or not.") yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-read-user-completion-table (&optional forcetoread) yuuji@64: "Append user completion table of LaTeX macros" yuuji@80: (interactive) yuuji@64: (let*((user-table (expand-file-name YaTeX-user-completion-table)) yuuji@64: (local-table (expand-file-name (file-name-nondirectory user-table))) yuuji@64: var localvar localbuf (curbuf (current-buffer)) sexp) yuuji@64: (if YaTeX-user-table-is-read nil yuuji@64: (message "Loading user completion table") yuuji@64: (if (file-exists-p user-table) (load-file user-table) yuuji@64: (message "Welcome to the field of YaTeX. I'm glad to see you!"))) yuuji@64: (setq YaTeX-user-table-is-read t) yuuji@64: (cond yuuji@64: ((file-exists-p local-table) yuuji@64: (set-buffer (setq localbuf (find-file-noselect local-table))) yuuji@64: (widen) yuuji@64: (goto-char (point-min)) yuuji@80: (while (re-search-forward "(setq \\([^ \t\n]+\\)" nil t) yuuji@64: (setq var (intern (buffer-substring yuuji@64: (match-beginning 1) (match-end 1))) yuuji@64: localvar (YaTeX-local-table-symbol var)) yuuji@64: (goto-char (match-beginning 0)) yuuji@64: (setq sexp (buffer-substring (point) yuuji@64: (progn (forward-sexp) (point)))) yuuji@64: (set-buffer curbuf) yuuji@64: (or (assq var (buffer-local-variables)) (make-local-variable var)) yuuji@64: (eval (read sexp)) yuuji@64: (or (and (boundp localvar) yuuji@64: (symbol-value localvar) yuuji@64: (not forcetoread)) yuuji@64: (set localvar (symbol-value var))) yuuji@64: (set-buffer localbuf)) yuuji@64: (kill-buffer localbuf))) yuuji@64: (set-buffer curbuf))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-reload-dictionary () yuuji@64: "Reload local dictionary. yuuji@64: Use this function after editing ./.yatexrc." yuuji@64: (interactive) yuuji@64: (let ((YaTeX-user-table-is-read nil)) yuuji@64: (YaTeX-read-user-completion-table t))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-lookup-table (word type) yuuji@64: "Lookup WORD in completion table whose type is TYPE. yuuji@64: This function refers the symbol tmp-TYPE-table, user-TYPE-table, TYPE-table. yuuji@64: Typically, TYPE is one of 'env, 'section, 'fontsize, 'singlecmd." yuuji@64: (if (symbolp type) (setq type (symbol-name type))) yuuji@64: (or (assoc word (symbol-value (intern (concat "tmp-" type "-table")))) yuuji@64: (assoc word (symbol-value (intern (concat "user-" type "-table")))) yuuji@64: (assoc word (symbol-value (intern (concat type "-table")))))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-update-table (vallist default-table user-table local-table) yuuji@64: "Update completion table if the car of VALLIST is not in current tables. yuuji@64: Second argument DEFAULT-TABLE is the quoted symbol of default completion yuuji@64: table, third argument USER-TABLE is user table which will be saved in yuuji@64: YaTeX-user-completion-table, fourth argument LOCAL-TABLE should have the yuuji@64: completion which is valid during current Emacs's session. If you yuuji@64: want to make LOCAL-TABLE valid longer span (but restrict in this directory) yuuji@64: create the file in current directory which has the same name with yuuji@64: YaTeX-user-completion-table." yuuji@64: (let ((car-v (car vallist)) key answer yuuji@64: (file (file-name-nondirectory YaTeX-user-completion-table))) yuuji@64: (cond yuuji@64: ((assoc car-v (symbol-value default-table)) yuuji@64: nil) ;Nothing to do yuuji@64: ((setq key (assoc car-v (symbol-value user-table))) yuuji@64: (if (equal (cdr vallist) (cdr key)) nil yuuji@64: ;; if association hits, but contents differ. yuuji@64: (message yuuji@64: "%s's attributes turned into %s" (car vallist) (cdr vallist)) yuuji@64: (set user-table (delq key (symbol-value user-table))) yuuji@64: (set user-table (cons vallist (symbol-value user-table))) yuuji@64: (YaTeX-update-dictionary yuuji@64: YaTeX-user-completion-table user-table "user"))) yuuji@64: ((setq key (assoc car-v (symbol-value local-table))) yuuji@64: (if (equal (cdr vallist) (cdr key)) nil yuuji@64: (message yuuji@64: "%s's attributes turned into %s" (car vallist) (cdr vallist)) yuuji@64: (set local-table (delq key (symbol-value local-table))) yuuji@64: (set local-table (cons vallist (symbol-value local-table))) yuuji@64: (set (YaTeX-local-table-symbol local-table) (symbol-value local-table)) yuuji@64: (YaTeX-update-dictionary file local-table))) yuuji@64: ;; All of above cases, there are some completion in tables. yuuji@64: ;; Then update tables. yuuji@64: (t yuuji@64: (if (not YaTeX-nervous) yuuji@64: (setq answer "u") yuuji@64: (message yuuji@64: (cond yuuji@64: (YaTeX-japan yuuji@68: "`%s'の登録先: U)ユーザ辞書 L)ローカル辞書 N)メモリ D)しない") yuuji@64: (t yuuji@64: "Register `%s' into: U)serDic L)ocalDic N)one D)iscard")) yuuji@64: (if (> (length car-v) 23) yuuji@68: (concat (substring car-v 0 10) "..." (substring car-v -9)) yuuji@64: car-v)) yuuji@64: (setq answer (char-to-string (read-char)))) yuuji@64: (cond yuuji@64: ((string-match answer "uy") yuuji@64: (set user-table (cons vallist (symbol-value user-table))) yuuji@64: (YaTeX-update-dictionary YaTeX-user-completion-table user-table "user") yuuji@64: ) yuuji@64: ((string-match answer "tl") yuuji@64: (set local-table (cons vallist (symbol-value local-table))) yuuji@64: (set (YaTeX-local-table-symbol local-table) (symbol-value local-table)) yuuji@64: (YaTeX-update-dictionary file local-table)) yuuji@64: ((string-match answer "d") nil) ;discard it yuuji@64: (t (set default-table yuuji@64: (cons vallist (symbol-value default-table))))))))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-cplread-with-learning yuuji@64: (prom default-table user-table local-table yuuji@64: &optional pred reqmatch init hsym) yuuji@64: "Completing read with learning. yuuji@64: Do a completing read with prompt PROM. Completion table is what yuuji@64: DEFAULT-TABLE, USER-TABLE, LOCAL table are appended in reverse order. yuuji@64: Note that these tables are passed by the symbol. yuuji@64: Optional arguments PRED, REQMATH and INIT are passed to completing-read yuuji@64: as its arguments PREDICATE, REQUIRE-MATCH and INITIAL-INPUT respectively. yuuji@64: If optional 8th argument HSYM, history symbol, is passed, use it as yuuji@64: history list variable." yuuji@64: (YaTeX-sync-local-table local-table) yuuji@64: (let*((table (append (symbol-value local-table) yuuji@64: (symbol-value user-table) yuuji@64: (symbol-value default-table))) yuuji@64: (word (completing-read-with-history yuuji@64: prom table pred reqmatch init hsym))) yuuji@64: (if (and (string< "" word) (not (assoc word table))) yuuji@64: (YaTeX-update-table (list word) default-table user-table local-table)) yuuji@64: word)) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-update-dictionary (file symbol &optional type) yuuji@64: (let ((local-table-buf (find-file-noselect file)) yuuji@64: (name (symbol-name symbol)) yuuji@64: (value (symbol-value symbol))) yuuji@64: (save-excursion yuuji@64: (message "Updating %s dictionary..." (or type "local")) yuuji@64: (set-buffer local-table-buf) yuuji@64: (goto-char (point-max)) yuuji@64: (search-backward (concat "(setq " name) nil t) yuuji@64: (delete-region (point) (progn (forward-sexp) (point))) yuuji@64: (delete-blank-lines) yuuji@64: (insert "(setq " name " '(\n") yuuji@353: (mapcar (function (lambda (s) yuuji@353: (insert (format "%s\n" (prin1-to-string s))))) yuuji@64: value) yuuji@64: (insert "))\n\n") yuuji@64: (delete-blank-lines) yuuji@64: (basic-save-buffer) yuuji@64: (kill-buffer local-table-buf) yuuji@64: (message "Updating %s dictionary...Done" (or type "local"))))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-define-begend-key-normal (key env &optional map) yuuji@64: "Define short cut YaTeX-make-begin-end key." yuuji@64: (YaTeX-define-key yuuji@64: key yuuji@64: (list 'lambda '(arg) '(interactive "P") yuuji@64: (list 'YaTeX-insert-begin-end env 'arg)) yuuji@64: map)) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-define-begend-region-key (key env &optional map) yuuji@64: "Define short cut YaTeX-make-begin-end-region key." yuuji@64: (YaTeX-define-key key (list 'lambda nil '(interactive) yuuji@64: (list 'YaTeX-insert-begin-end env t)) map)) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun YaTeX-define-begend-key (key env &optional map) yuuji@86: "Define short cut key for begin type completion. yuuji@86: Define both strokes for normal and region mode. yuuji@86: To customize YaTeX, user should use this function." yuuji@64: (YaTeX-define-begend-key-normal key env map) yuuji@64: (if YaTeX-inhibit-prefix-letter nil yuuji@64: (YaTeX-define-begend-region-key yuuji@64: (concat (upcase (substring key 0 1)) (substring key 1)) env))) yuuji@64: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-search-active-forward (string cmntrx &optional bound err cnt func) yuuji@23: "Search STRING which is not commented out by CMNTRX. yuuji@23: Optional arguments after BOUND, ERR, CNT are passed literally to search-forward yuuji@23: or search-backward. yuuji@23: Optional sixth argument FUNC changes search-function." yuuji@49: (let ((sfunc (or func 'search-forward)) found md) yuuji@23: (while (and (prog1 yuuji@23: (setq found (funcall sfunc string bound err cnt)) yuuji@23: (setq md (match-data))) yuuji@23: (or yuuji@64: (and (eq major-mode 'yatex-mode) yuuji@64: (YaTeX-in-verb-p (match-beginning 0))) yuuji@23: (save-excursion yuuji@72: (goto-char (match-beginning 0)) yuuji@23: (beginning-of-line) yuuji@23: (re-search-forward cmntrx (match-beginning 0) t))))) yuuji@23: (store-match-data md) yuuji@69: found)) yuuji@23: yuuji@23: (defun YaTeX-re-search-active-forward (regexp cmntrx &optional bound err cnt) yuuji@23: "Search REGEXP backward which is not commented out by regexp CMNTRX. yuuji@23: See also YaTeX-search-active-forward." yuuji@69: (YaTeX-search-active-forward regexp cmntrx bound err cnt 're-search-forward)) yuuji@69: yuuji@23: (defun YaTeX-search-active-backward (string cmntrx &optional bound err cnt) yuuji@23: "Search STRING backward which is not commented out by regexp CMNTRX. yuuji@23: See also YaTeX-search-active-forward." yuuji@69: (YaTeX-search-active-forward string cmntrx bound err cnt 'search-backward)) yuuji@69: yuuji@23: (defun YaTeX-re-search-active-backward (regexp cmntrx &optional bound err cnt) yuuji@23: "Search REGEXP backward which is not commented out by regexp CMNTRX. yuuji@23: See also YaTeX-search-active-forward." yuuji@69: (YaTeX-search-active-forward yuuji@69: regexp cmntrx bound err cnt 're-search-backward)) yuuji@23: yuuji@80: (defun YaTeX-relative-path-p (path) yuuji@80: "Return non-nil if PATH is not absolute one." yuuji@80: (let ((md (match-data))) yuuji@80: (unwind-protect yuuji@80: (not (string-match "^\\(/\\|[a-z]:\\|\\\\\\).*/" file)) yuuji@80: (store-match-data md)))) yuuji@80: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-switch-to-buffer (file &optional setbuf) yuuji@23: "Switch to buffer if buffer exists, find file if not. yuuji@23: Optional second arg SETBUF t make use set-buffer instead of switch-to-buffer." yuuji@23: (interactive "Fswitch to file: ") yuuji@70: (if (bufferp file) yuuji@70: (setq file (buffer-file-name file)) yuuji@80: (and (YaTeX-relative-path-p file) yuuji@70: (eq major-mode 'yatex-mode) yuuji@70: YaTeX-search-file-from-top-directory yuuji@70: (save-excursion yuuji@70: (YaTeX-visit-main t) yuuji@70: (setq file (expand-file-name file))))) yuuji@52: (let (buf (hilit-auto-highlight (not setbuf))) yuuji@52: (cond yuuji@52: ((setq buf (get-file-buffer file)) yuuji@52: (funcall (if setbuf 'set-buffer 'switch-to-buffer) yuuji@52: (get-file-buffer file)) yuuji@52: buf) yuuji@52: ((or YaTeX-create-file-prefix-g (file-exists-p file)) yuuji@52: (or ;find-file returns nil but set current-buffer... yuuji@52: (if setbuf (set-buffer (find-file-noselect file)) yuuji@52: (find-file file)) yuuji@52: (current-buffer))) yuuji@52: (t (message "%s was not found in this directory." file) yuuji@69: nil)))) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-switch-to-buffer-other-window (file) yuuji@23: "Switch to buffer if buffer exists, find file if not." yuuji@23: (interactive "Fswitch to file: ") yuuji@70: (and (eq major-mode 'yatex-mode) yuuji@70: (stringp file) yuuji@80: (YaTeX-relative-path-p file) yuuji@70: YaTeX-search-file-from-top-directory yuuji@70: (save-excursion yuuji@70: (YaTeX-visit-main t) yuuji@70: (setq file (expand-file-name file)))) yuuji@52: (if (bufferp file) (setq file (buffer-file-name file))) yuuji@52: (cond yuuji@52: ((get-file-buffer file) yuuji@52: (switch-to-buffer-other-window (get-file-buffer file)) yuuji@52: t) yuuji@52: ((or YaTeX-create-file-prefix-g (file-exists-p file)) yuuji@52: (find-file-other-window file) t) yuuji@52: (t (message "%s was not found in this directory." file) yuuji@69: nil))) yuuji@23: yuuji@70: (defun YaTeX-get-file-buffer (file) yuuji@70: "Return the FILE's buffer. yuuji@70: Base directory is that of main file or current directory." yuuji@70: (let (dir main (cdir default-directory)) yuuji@70: (or (and (eq major-mode 'yatex-mode) yuuji@70: YaTeX-search-file-from-top-directory yuuji@70: (save-excursion yuuji@70: (YaTeX-visit-main t) yuuji@70: (get-file-buffer file))) yuuji@70: (get-file-buffer file)))) yuuji@70: yuuji@23: (defun YaTeX-replace-format-sub (string format repl) yuuji@23: (let ((beg (or (string-match (concat "^\\(%" format "\\)") string) yuuji@23: (string-match (concat "[^%]\\(%" format "\\)") string))) yuuji@23: (len (length format))) yuuji@23: (if (null beg) string ;no conversion yuuji@23: (concat yuuji@70: (substring string 0 (match-beginning 1)) (or repl "") yuuji@69: (substring string (match-end 1)))))) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-replace-format (string format repl) yuuji@23: "In STRING, replace first appearance of FORMAT to REPL as if yuuji@23: function `format' does. FORMAT does not contain `%'" yuuji@80: (let ((ans string) (case-fold-search nil)) yuuji@23: (while (not (string= yuuji@23: ans (setq string (YaTeX-replace-format-sub ans format repl)))) yuuji@23: (setq ans string)) yuuji@69: string)) yuuji@23: yuuji@23: ;;;###autoload yuuji@70: (defun YaTeX-replace-formats (string replace-list) yuuji@70: (let ((list replace-list)) yuuji@70: (while list yuuji@70: (setq string (YaTeX-replace-format yuuji@70: string (car (car list)) (cdr (car list))) yuuji@70: list (cdr list))) yuuji@70: string)) yuuji@70: yuuji@70: ;;;###autoload yuuji@23: (defun YaTeX-replace-format-args (string &rest args) yuuji@23: "Translate the argument mark #1, #2, ... #n in the STRING into the yuuji@23: corresponding real arguments ARGS." yuuji@23: (let ((argp 1)) yuuji@23: (while args yuuji@23: (setq string yuuji@23: (YaTeX-replace-format string (int-to-string argp) (car args))) yuuji@23: (setq args (cdr args) argp (1+ argp)))) yuuji@69: string) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun rindex (string char) yuuji@226: "Return the last position of STRING where character CHAR found." yuuji@23: (let ((pos (1- (length string)))(index -1)) yuuji@174: (catch 'rindex yuuji@174: (while (>= pos 0) yuuji@174: (cond yuuji@174: ((= (aref string pos) char) yuuji@174: (throw 'rindex pos)) yuuji@174: (t (setq pos (1- pos)))))))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun point-beginning-of-line () yuuji@64: (save-excursion (beginning-of-line)(point))) yuuji@64: yuuji@64: ;;;###autoload yuuji@64: (defun point-end-of-line () yuuji@64: (save-excursion (end-of-line)(point))) yuuji@64: yuuji@354: (defun YaTeX-showup-buffer-bottom-most (x) (nth 3 (window-edges x))) yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-showup-buffer (buffer &optional func select) yuuji@23: "Make BUFFER show up in certain window (but current window) yuuji@23: that gives the maximum value by the FUNC. FUNC should take an argument yuuji@23: of its window object. Non-nil for optional third argument SELECT selects yuuji@49: that window. This function never selects minibuffer window." yuuji@86: (or (and (if (and YaTeX-emacs-19 select window-system) yuuji@47: (get-buffer-window buffer t) yuuji@47: (get-buffer-window buffer)) yuuji@47: (progn yuuji@47: (if select yuuji@51: (goto-buffer-window buffer)) yuuji@47: t)) yuuji@23: (let ((window (selected-window)) yuuji@23: (wlist (YaTeX-window-list)) win w (x 0)) yuuji@23: (cond yuuji@23: ((> (length wlist) 2) yuuji@23: (if func yuuji@23: (while wlist yuuji@23: (setq w (car wlist)) yuuji@23: (if (and (not (eq window w)) yuuji@23: (> (funcall func w) x)) yuuji@23: (setq win w x (funcall func w))) yuuji@23: (setq wlist (cdr wlist))) yuuji@23: (setq win (get-lru-window))) yuuji@23: (select-window win) yuuji@23: (switch-to-buffer buffer) yuuji@23: (or select (select-window window))) yuuji@23: ((= (length wlist) 2) yuuji@49: ;(other-window 1);This does not work properly on Emacs-19 yuuji@49: (select-window (get-lru-window)) yuuji@23: (switch-to-buffer buffer) yuuji@354: (if (< (window-height) (/ YaTeX-default-pop-window-height 2)) yuuji@354: (enlarge-window (- YaTeX-default-pop-window-height yuuji@354: (window-height)))) yuuji@23: (or select (select-window window))) yuuji@23: (t ;if one-window yuuji@23: (cond yuuji@86: ((and YaTeX-emacs-19 window-system (get-buffer-window buffer t)) yuuji@47: nil) ;if found in other frame yuuji@23: (YaTeX-default-pop-window-height yuuji@51: (split-window-calculate-height YaTeX-default-pop-window-height) yuuji@59: ;;(pop-to-buffer buffer) ;damn! emacs-19.30 yuuji@59: (select-window (next-window nil 1)) yuuji@59: (switch-to-buffer (get-buffer-create buffer)) yuuji@23: (or select (select-window window))) yuuji@23: (t nil))) yuuji@69: )))) yuuji@69: yuuji@69: (cond yuuji@69: ((fboundp 'screen-height) yuuji@69: (fset 'YaTeX-screen-height 'screen-height) yuuji@182: (fset 'YaTeX-screen-width 'screen-width) yuuji@182: (fset 'YaTeX-set-screen-height 'set-screen-height) yuuji@182: (fset 'YaTeX-set-screen-width 'set-screen-width)) yuuji@69: ((fboundp 'frame-height) yuuji@69: (fset 'YaTeX-screen-height 'frame-height) yuuji@182: (fset 'YaTeX-screen-width 'frame-width) yuuji@182: (fset 'YaTeX-set-screen-height 'set-frame-height) yuuji@182: (fset 'YaTeX-set-screen-width 'set-frame-width)) yuuji@182: (t (error "I don't know how to run YaTeX on this Emacs..."))) yuuji@23: yuuji@23: ;;;###autoload yuuji@51: (defun split-window-calculate-height (height) yuuji@51: "Split current window wight specified HEIGHT. yuuji@59: If HEIGHT is number, make a new window that has HEIGHT lines. yuuji@59: If HEIGHT is string, make a new window that occupies HEIGT % of screen height. yuuji@51: Otherwise split window conventionally." yuuji@59: (if (one-window-p t) yuuji@51: (split-window yuuji@51: (selected-window) yuuji@51: (max yuuji@51: (min yuuji@69: (- (YaTeX-screen-height) yuuji@59: (if (numberp height) yuuji@59: (+ height 2) yuuji@69: (/ (* (YaTeX-screen-height) yuuji@451: (YaTeX-str2int height)) yuuji@51: 100))) yuuji@69: (- (YaTeX-screen-height) window-min-height 1)) yuuji@69: window-min-height)))) yuuji@51: yuuji@51: ;;;###autoload yuuji@23: (defun YaTeX-window-list () yuuji@23: (let*((curw (selected-window)) (win curw) (wlist (list curw))) yuuji@23: (while (not (eq curw (setq win (next-window win)))) yuuji@23: (or (eq win (minibuffer-window)) yuuji@23: (setq wlist (cons win wlist)))) yuuji@69: wlist)) yuuji@23: yuuji@72: (if YaTeX-emacs-21 yuuji@72: ;; Emacs-21's next-window returns other frame's window even if called yuuji@72: ;; with argument ALL-FRAMES nil, when called from minibuffer context. yuuji@72: ;; Therefore, check frame identity here. yuuji@72: (defun YaTeX-window-list () yuuji@72: (let*((curw (selected-window)) (win curw) (wlist (list curw)) yuuji@72: (curf (window-frame curw))) yuuji@72: (while (and (not (eq curw (setq win (next-window win)))) yuuji@72: (eq curf (window-frame win))) yuuji@72: (or (eq win (minibuffer-window)) yuuji@72: (setq wlist (cons win wlist)))) yuuji@72: wlist))) yuuji@72: yuuji@23: ;;;###autoload yuuji@23: (defun substitute-all-key-definition (olddef newdef keymap) yuuji@23: "Replace recursively OLDDEF with NEWDEF for any keys in KEYMAP now yuuji@23: defined as OLDDEF. In other words, OLDDEF is replaced with NEWDEF yuuji@23: where ever it appears." yuuji@68: (if YaTeX-emacs-19 yuuji@68: (substitute-key-definition olddef newdef keymap global-map) yuuji@68: (mapcar yuuji@68: (function (lambda (key) (define-key keymap key newdef))) yuuji@68: (where-is-internal olddef keymap)))) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-match-string (n &optional m) yuuji@23: "Return (buffer-substring (match-beginning n) (match-beginning m))." yuuji@23: (if (match-beginning n) yuuji@80: (YaTeX-buffer-substring (match-beginning n) yuuji@69: (match-end (or m n))))) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-minibuffer-complete () yuuji@49: "Complete in minibuffer. yuuji@51: If the symbol 'delim is bound and is string, its value is assumed to be yuuji@49: the character class of delimiters. Completion will be performed on yuuji@51: the last field separated by those delimiters. yuuji@51: If the symbol 'quick is bound and is 't, when the try-completion results yuuji@51: in t, exit minibuffer immediately." yuuji@23: (interactive) yuuji@72: (save-restriction yuuji@72: (narrow-to-region yuuji@72: (if (fboundp 'field-beginning) (field-beginning (point-max)) (point-min)) yuuji@72: (point-max)) yuuji@72: (let ((md (match-data)) beg word compl yuuji@72: (quick (and (boundp 'quick) (eq quick t))) yuuji@72: (displist ;function to display completion-list yuuji@72: (function yuuji@72: (lambda () yuuji@72: (with-output-to-temp-buffer "*Completions*" yuuji@72: (display-completion-list yuuji@72: (all-completions word minibuffer-completion-table))))))) yuuji@72: (setq beg (if (and (boundp 'delim) (stringp delim)) yuuji@72: (save-excursion yuuji@72: (skip-chars-backward (concat "^" delim)) yuuji@72: (point)) yuuji@72: (point-min)) yuuji@72: word (buffer-substring beg (point-max)) yuuji@72: compl (try-completion word minibuffer-completion-table)) yuuji@72: (cond yuuji@72: ((eq compl t) yuuji@72: (if quick (exit-minibuffer) yuuji@72: (let ((p (point)) (max (point-max))) yuuji@72: (unwind-protect yuuji@72: (progn yuuji@72: (goto-char max) yuuji@72: (insert " [Sole completion]") yuuji@72: (goto-char p) yuuji@72: (sit-for 1)) yuuji@72: (delete-region max (point-max)) yuuji@72: (goto-char p))))) yuuji@72: ((eq compl nil) yuuji@72: (ding) yuuji@72: (save-excursion yuuji@72: (let (p) yuuji@72: (unwind-protect yuuji@72: (progn yuuji@72: (goto-char (setq p (point-max))) yuuji@72: (insert " [No match]") yuuji@72: (goto-char p) yuuji@72: (sit-for 2)) yuuji@72: (delete-region p (point-max)))))) yuuji@72: ((string= compl word) yuuji@72: (funcall displist)) yuuji@72: (t (delete-region beg (point-max)) yuuji@72: (insert compl) yuuji@72: (if quick yuuji@72: (if (eq (try-completion compl minibuffer-completion-table) t) yuuji@72: (exit-minibuffer) yuuji@72: (funcall displist))))) yuuji@72: (store-match-data md)))) yuuji@23: yuuji@51: (defun YaTeX-minibuffer-quick-complete () yuuji@51: "Set 'quick to 't and call YaTeX-minibuffer-complete. yuuji@51: See documentation of YaTeX-minibuffer-complete." yuuji@51: (interactive) yuuji@51: (let ((quick t)) yuuji@51: (self-insert-command 1) yuuji@51: (YaTeX-minibuffer-complete))) yuuji@51: yuuji@168: (defun YaTeX-yatex-buffer-list () yuuji@168: (save-excursion yuuji@168: (delq nil (mapcar (function (lambda (buf) yuuji@168: (set-buffer buf) yuuji@168: (if (eq major-mode 'yatex-mode) buf))) yuuji@168: (buffer-list))))) yuuji@168: yuuji@51: (defun foreach-buffers (pattern job) yuuji@51: "For each buffer which matches with PATTERN, do JOB." yuuji@51: (let ((list (buffer-list))) yuuji@51: (save-excursion yuuji@51: (while list yuuji@51: (set-buffer (car list)) yuuji@51: (if (or (and (stringp pattern) yuuji@51: (buffer-file-name) yuuji@51: (string-match pattern (buffer-file-name))) yuuji@51: (and (symbolp pattern) major-mode (eq major-mode pattern))) yuuji@51: (eval job)) yuuji@69: (setq list (cdr list)))))) yuuji@51: yuuji@51: (defun goto-buffer-window (buffer) yuuji@51: "Select window which is bound to BUFFER. yuuji@51: If no such window exist, switch to buffer BUFFER." yuuji@52: (interactive "BGoto buffer: ") yuuji@51: (if (stringp buffer) yuuji@51: (setq buffer (or (get-file-buffer buffer) (get-buffer buffer)))) yuuji@51: (if (get-buffer buffer) yuuji@51: (cond yuuji@51: ((get-buffer-window buffer) yuuji@51: (select-window (get-buffer-window buffer))) yuuji@51: ((and YaTeX-emacs-19 (get-buffer-window buffer t)) yuuji@51: (let*((win (get-buffer-window buffer t)) yuuji@51: (frame (window-frame win))) yuuji@51: (select-frame frame) yuuji@51: (raise-frame frame) yuuji@51: (focus-frame frame) yuuji@51: (select-window win) yuuji@51: (set-mouse-position frame 0 0) yuuji@51: (and (featurep 'windows) (fboundp 'win:adjust-window) yuuji@51: (win:adjust-window)))) yuuji@54: ((and (featurep 'windows) (fboundp 'win:get-buffer-window) yuuji@56: (let ((w (win:get-buffer-window buffer))) yuuji@56: (and w (win:switch-window w)))) yuuji@54: (select-window (get-buffer-window buffer))) yuuji@69: (t (switch-to-buffer buffer))))) yuuji@51: yuuji@51: ;; Here starts the functions which support gmhist-vs-Emacs19 compatible yuuji@51: ;; reading with history. yuuji@51: ;;;###autoload yuuji@51: (defun completing-read-with-history yuuji@51: (prompt table &optional predicate must-match initial hsym) yuuji@51: "Completing read with general history: gmhist, Emacs-19." yuuji@51: (let ((minibuffer-history yuuji@51: (or (symbol-value hsym) yuuji@51: (and (boundp 'minibuffer-history) minibuffer-history))) yuuji@51: (minibuffer-history-symbol (or hsym 'minibuffer-history))) yuuji@51: (prog1 yuuji@51: (if (fboundp 'completing-read-with-history-in) yuuji@51: (completing-read-with-history-in yuuji@51: minibuffer-history-symbol prompt table predicate must-match initial) yuuji@393: (save-excursion ;work around to avoid cursor warp yuuji@393: (completing-read prompt table predicate must-match initial))) yuuji@51: (if (and YaTeX-emacs-19 hsym) (set hsym minibuffer-history))))) yuuji@51: yuuji@51: ;;;###autoload yuuji@51: (defun read-from-minibuffer-with-history (prompt &optional init map read hsym) yuuji@51: "Read from minibuffer with general history: gmhist, Emacs-19." yuuji@51: (cond yuuji@51: (YaTeX-emacs-19 yuuji@393: (save-excursion ;work around to avoid cursor warp yuuji@393: (read-from-minibuffer prompt init map read hsym))) yuuji@51: (t yuuji@51: (let ((minibuffer-history-symbol hsym)) yuuji@51: (read-from-minibuffer prompt init map read))))) yuuji@51: yuuji@51: ;;;###autoload yuuji@51: (defun read-string-with-history (prompt &optional init hsym) yuuji@51: "Read string with history: gmhist(Emacs-18) and Emacs-19." yuuji@51: (cond yuuji@51: (YaTeX-emacs-19 yuuji@393: (save-excursion ;work around to avoid cursor warp yuuji@393: (read-from-minibuffer prompt init minibuffer-local-map nil hsym))) yuuji@51: ((featurep 'gmhist-mh) yuuji@51: (read-with-history-in hsym prompt init)) yuuji@51: (t (read-string prompt init)))) yuuji@23: yuuji@234: (defvar YaTeX-skip-next-reader-char ?\C-j) yuuji@237: (defun YaTeX-read-string-or-skip (&rest args) yuuji@237: "Read string, or skip if last input char is \C-j." yuuji@293: (if (equal (if (boundp 'last-input-event) last-input-event last-input-char) yuuji@293: YaTeX-skip-next-reader-char) yuuji@237: "" yuuji@393: (save-excursion ;work around to avoid cursor warp yuuji@393: (apply 'read-string args)))) yuuji@234: yuuji@244: (defun YaTeX-completing-read-or-skip (&rest args) yuuji@244: "Do completing-read, or skip if last input char is \C-j." yuuji@293: (if (equal (if (boundp 'last-input-event) last-input-event last-input-char) yuuji@293: YaTeX-skip-next-reader-char) yuuji@244: "" yuuji@393: (save-excursion ;work around to avoid cursor warp yuuji@393: (apply 'completing-read args)))) yuuji@244: yuuji@69: ;;;###autoload yuuji@69: (fset 'YaTeX-rassoc yuuji@69: (if (and nil (fboundp 'rassoc) (subrp (symbol-function 'rassoc))) yuuji@69: (symbol-function 'rassoc) yuuji@70: (function yuuji@70: (lambda (key list) yuuji@70: (let ((l list)) yuuji@70: (catch 'found yuuji@70: (while l yuuji@70: (if (equal key (cdr (car l))) yuuji@70: (throw 'found (car l))) yuuji@70: (setq l (cdr l))))))))) yuuji@70: yuuji@354: (defun YaTeX-set-file-coding-system (code coding) yuuji@354: "Set current buffer's coding system according to symbol." yuuji@354: (cond ((null code) yuuji@354: nil) yuuji@354: ((boundp 'MULE) yuuji@354: (set-file-coding-system coding)) yuuji@354: ((and YaTeX-emacs-20 (boundp 'buffer-file-coding-system)) yuuji@354: (setq buffer-file-coding-system yuuji@354: (or (and (fboundp 'set-auto-coding) buffer-file-name yuuji@354: (save-excursion yuuji@354: (goto-char (point-min)) yuuji@354: (set-auto-coding buffer-file-name (buffer-size)))) yuuji@354: coding))) yuuji@354: ((featurep 'mule) yuuji@354: (set-file-coding-system coding)) yuuji@354: ((boundp 'NEMACS) yuuji@354: (make-local-variable 'kanji-fileio-code) yuuji@354: (setq kanji-fileio-code code)))) yuuji@354: yuuji@70: (defun YaTeX-insert-file-contents (file visit &optional beg end) yuuji@70: (cond yuuji@72: ((and (string< "19" emacs-version) (not (featurep 'xemacs))) yuuji@70: (insert-file-contents file visit beg end)) yuuji@77: ((string-match "unix\\|linux" (symbol-name system-type)) yuuji@70: (let ((default-process-coding-system yuuji@72: (and (boundp '*noconv*) (list '*noconv*))) yuuji@72: (file-coding-system (and (boundp '*noconv*) '*noconv*)) yuuji@70: kanji-fileio-code yuuji@70: (default-process-kanji-code 0)) yuuji@70: (call-process shell-file-name file (current-buffer) nil yuuji@70: (or (and (boundp 'shell-command-option) yuuji@70: shell-command-option) yuuji@70: "-c") yuuji@77: (format "dd bs=1 count=%d | tail -c +%d" end beg)))) yuuji@70: (t (insert-file-contents file)))) yuuji@70: yuuji@70: (defun YaTeX-split-string (str &optional sep null) yuuji@70: "Split string STR by every occurrence of SEP(regexp). yuuji@70: If the optional second argument SEP is nil, it defaults to \"[ \f\t\n\r\v]+\". yuuji@70: Do not include null string by default. Non-nil for optional third argument yuuji@70: NULL includes null string in a list." yuuji@70: (let ((sep (or sep "[ \f\t\n\r\v]+")) yuuji@70: list m) yuuji@70: (while str yuuji@70: (if (setq m (string-match sep str)) yuuji@70: (progn yuuji@70: (if (or (> m 0) null) yuuji@70: (setq list (cons (substring str 0 m) list))) yuuji@70: (setq str (substring str (match-end 0)))) yuuji@70: (if (or null (string< "" str)) yuuji@70: (setq list (cons str list))) yuuji@70: (setq str nil))) yuuji@70: (nreverse list))) yuuji@69: yuuji@73: ;;;###autoload yuuji@73: (defun YaTeX-delete1 (elt list) yuuji@73: "Delete" yuuji@73: (let (e) yuuji@73: (while (setq e (YaTeX-member elt list)) yuuji@73: (setq list (delq (car e) list)))) yuuji@73: list) yuuji@73: (if (fboundp 'delete) yuuji@73: (fset 'YaTeX-delete (symbol-function 'delete)) yuuji@73: (fset 'YaTeX-delete (symbol-function 'YaTeX-delete1))) yuuji@73: yuuji@73: (defun YaTeX-member1 (elt list) yuuji@73: (catch 'found yuuji@73: (while list yuuji@73: (if (equal elt (car list)) yuuji@73: (throw 'found list)) yuuji@73: (setq list (cdr list))))) yuuji@73: yuuji@73: (if (and (fboundp 'member) (subrp (symbol-function 'member))) yuuji@73: (fset 'YaTeX-member (symbol-function 'member)) yuuji@73: (fset 'YaTeX-member (symbol-function 'YaTeX-member1))) yuuji@73: yuuji@53: ;;; yuuji@53: ;; Interface function for windows.el yuuji@53: ;;; yuuji@53: ;;;###autoload yuuji@290: (fset 'YaTeX-last-key yuuji@290: (if (fboundp 'win:last-key) yuuji@290: 'win:last-key yuuji@353: (function (lambda () (if (boundp 'last-command-char) yuuji@353: last-command-char yuuji@353: last-command-event))))) yuuji@53: (defun YaTeX-switch-to-window () yuuji@53: "Switch to windows.el's window decided by last pressed key." yuuji@53: (interactive) yuuji@53: (or (featurep 'windows) (error "Why don't you use `windows.el'?")) yuuji@290: (win-switch-to-window 1 (- (YaTeX-last-key) win:base-key))) yuuji@290: yuuji@53: yuuji@64: ;;;###autoload yuuji@138: (defun YaTeX-command-to-string (cmd) yuuji@138: (if (fboundp 'shell-command-to-string) yuuji@138: (funcall 'shell-command-to-string cmd) yuuji@138: (let ((tbuf " *tmpout*")) yuuji@138: (if (get-buffer-create tbuf) (kill-buffer tbuf)) yuuji@138: (let ((standard-output (get-buffer-create tbuf))) yuuji@138: (unwind-protect yuuji@138: (save-excursion yuuji@138: (call-process yuuji@138: shell-file-name nil tbuf nil YaTeX-shell-command-option cmd) yuuji@138: (set-buffer tbuf) yuuji@138: (buffer-string)) yuuji@138: (kill-buffer tbuf)))))) yuuji@138: yuuji@372: ;;; (defun YaTeX-executable-find(cmd)...) yuuji@372: (fset 'YaTeX-executable-find yuuji@372: (if (fboundp 'executable-find) yuuji@372: 'executable-find yuuji@372: (function (lambda (cmd) yuuji@372: (let ((list exec-path) path) yuuji@372: (catch 'exec yuuji@372: (while list yuuji@372: (if (file-executable-p yuuji@372: (setq path (expand-file-name cmd (car list)))) yuuji@372: (throw 'exec path)) yuuji@372: (setq list (cdr list))))))))) yuuji@372: yuuji@138: ;;;###autoload yuuji@64: (defun YaTeX-reindent (col) yuuji@64: "Remove current indentation and reindento to COL column." yuuji@64: (save-excursion yuuji@64: (beginning-of-line) yuuji@64: (skip-chars-forward " \t") yuuji@64: (if (/= col (current-column)) yuuji@64: (progn yuuji@64: (delete-region (point) (progn (beginning-of-line) (point))) yuuji@64: (indent-to col)))) yuuji@64: (skip-chars-forward " \t" (point-end-of-line))) yuuji@64: yuuji@64: (defun YaTeX-inner-environment (&optional quick) yuuji@64: "Return current inner-most environment. yuuji@64: Non-nil for optional argument QUICK restricts search bound to most yuuji@64: recent sectioning command. Matching point is stored to property 'point yuuji@64: of 'YaTeX-inner-environment, which can be referred by yuuji@64: (get 'YaTeX-inner-environment 'point)." yuuji@73: (put 'YaTeX-inner-environment 'point (point-min)) yuuji@73: (put 'YaTeX-inner-environment 'indent 0) yuuji@64: (let*((nest 0) yuuji@64: (beg (YaTeX-replace-format-args yuuji@64: (regexp-quote YaTeX-struct-begin) yuuji@64: ;YaTeX-struct-begin ;=== TENTATIVE!! == yuuji@64: YaTeX-struct-name-regexp yuuji@64: (if (eq major-mode 'yahtml-mode) "\\s *.*" "") yuuji@64: "")) yuuji@64: (end (YaTeX-replace-format-args yuuji@64: (regexp-quote YaTeX-struct-end) yuuji@64: YaTeX-struct-name-regexp "" "")) yuuji@64: (begend (concat "\\(" beg "\\)\\|\\(" end "\\)")) yuuji@64: bound m0 yuuji@64: (htmlp (eq major-mode 'yahtml-mode)) yuuji@64: (open yuuji@64: (concat "^" (or (cdr (assq major-mode '((yahtml-mode . "<")))) "{"))) yuuji@64: (close yuuji@64: (concat "^" yuuji@64: (or (cdr(assq major-mode '((yahtml-mode . "\n\t >")))) "}")))) yuuji@64: (save-excursion yuuji@64: (if quick yuuji@64: (setq bound yuuji@64: (save-excursion yuuji@64: (if htmlp yuuji@64: ;;(re-search-backward YaTeX-sectioning-regexp nil 1) yuuji@73: ;;(goto-char (point-min)) ;Is this enough? 97/6/26 yuuji@73: (re-search-backward yahtml-indentation-boundary nil 1) yuuji@64: (YaTeX-re-search-active-backward yuuji@64: (concat YaTeX-ec-regexp yuuji@64: "\\(" YaTeX-sectioning-regexp "\\)\\*?{") yuuji@64: YaTeX-comment-prefix nil 1)) yuuji@64: (or (bobp) (end-of-line)) yuuji@64: (point)))) yuuji@64: (if (catch 'begin yuuji@64: (if (and (numberp bound) (< (point) bound)) (throw 'begin nil)) yuuji@64: (while (YaTeX-re-search-active-backward yuuji@64: begend YaTeX-comment-prefix bound t) yuuji@64: (setq m0 (match-beginning 0)) yuuji@64: (if (looking-at end) ;;(match-beginning 2) yuuji@64: (setq nest (1+ nest)) yuuji@64: (setq nest (1- nest))) yuuji@64: (if (< nest 0) yuuji@64: (progn yuuji@64: (put 'YaTeX-inner-environment 'point m0) yuuji@64: (goto-char m0) yuuji@64: (put 'YaTeX-inner-environment 'indent (current-column)) yuuji@64: (throw 'begin t))))) yuuji@187: (YaTeX-buffer-substring yuuji@64: (progn (skip-chars-forward open) (1+ (point))) yuuji@69: (progn (skip-chars-forward close) (point))))))) yuuji@64: yuuji@392: (defun YaTeX-in-environment-p (env) yuuji@392: "Return if current LaTeX environment is ENV. yuuji@392: ENV is given in the form of environment's name or its list." yuuji@392: (let ((md (match-data)) (nest 0) p envrx) yuuji@392: (cond yuuji@392: ((atom env) yuuji@392: (setq envrx yuuji@392: (concat "\\(" yuuji@392: (regexp-quote yuuji@392: (YaTeX-replace-format-args yuuji@392: YaTeX-struct-begin env "" "")) yuuji@392: "\\>\\)\\|\\(" yuuji@392: (regexp-quote yuuji@392: (YaTeX-replace-format-args yuuji@392: YaTeX-struct-end env "" "")) yuuji@392: "\\)")) yuuji@392: (save-excursion yuuji@392: (setq p (catch 'open yuuji@392: (while (YaTeX-re-search-active-backward yuuji@392: envrx YaTeX-comment-prefix nil t) yuuji@392: (if (match-beginning 2) yuuji@392: (setq nest (1+ nest)) yuuji@392: (setq nest (1- nest))) yuuji@392: (if (< nest 0) yuuji@392: (throw 'open (cons env (match-beginning 0))))))))) yuuji@392: ((listp env) yuuji@392: (setq p yuuji@392: (or (YaTeX-in-environment-p (car env)) yuuji@392: (and (cdr env) (YaTeX-in-environment-p (cdr env))))))) yuuji@392: (store-match-data md) yuuji@392: p;(or p (YaTeX-in-verb-p (match-beginning 0))) yuuji@392: )) yuuji@392: yuuji@392: (defun YaTeX-quick-in-environment-p (env) yuuji@392: "Check quickly but unsure if current environment is ENV. yuuji@392: ENV is given in the form of environment's name or its list. yuuji@392: This function returns correct result only if ENV is NOT nested." yuuji@392: (save-excursion yuuji@392: (let ((md (match-data)) m0 (p (point)) rc clfound) yuuji@392: (cond yuuji@392: ((listp env) yuuji@392: (or (YaTeX-quick-in-environment-p (car env)) yuuji@392: (and (cdr env) (YaTeX-quick-in-environment-p (cdr env))))) yuuji@392: (t yuuji@392: (unwind-protect yuuji@392: (if (prog1 yuuji@392: (YaTeX-search-active-backward yuuji@392: (YaTeX-replace-format-args YaTeX-struct-begin env "" "") yuuji@392: YaTeX-comment-prefix nil t) yuuji@392: (setq m0 (match-beginning 0))) yuuji@392: (if (YaTeX-search-active-forward yuuji@392: (YaTeX-replace-format-args yuuji@392: YaTeX-struct-end env) yuuji@392: YaTeX-comment-prefix p t nil) yuuji@392: nil ;if \end{env} found, return nil yuuji@392: (cons env m0))) ;else, return meaningful values yuuji@392: (store-match-data md))))))) yuuji@392: yuuji@451: (defun YaTeX-goto-corresponding-environment (&optional allow-mismatch noerr bg) yuuji@73: "Go to corresponding begin/end enclosure. yuuji@73: Optional argument ALLOW-MISMATCH allows mismatch open/clese. Use this yuuji@73: for \left(, \right). yuuji@73: Optional third argument NOERR causes no error for unballanced environment." yuuji@73: (interactive) yuuji@73: (if (not (YaTeX-on-begin-end-p)) nil yuuji@73: (let ((p (match-end 0)) b0 b1 env (nest 0) regexp re-s (op (point)) yuuji@73: (m0 (match-beginning 0)) ;whole matching yuuji@73: (m1 (match-beginning 1)) ;environment in \begin{} yuuji@73: (m2 (match-beginning 2)) ;environment in \end{} yuuji@73: (m3 (match-beginning 3))) ;environment in \[ \] \( \) yuuji@451: ;(setq env (regexp-quote (buffer-substring p (match-beginning 0)))) yuuji@73: (if (cond yuuji@73: (m1 ;if begin{xxx} yuuji@73: (setq env yuuji@73: (if allow-mismatch YaTeX-struct-name-regexp yuuji@73: (regexp-quote (buffer-substring m1 (match-end 1))))) yuuji@451: ; (setq regexp (concat "\\(\\\\end{" env "}\\)\\|" yuuji@451: ; "\\(\\\\begin{" env "}\\)")) yuuji@73: (setq regexp yuuji@73: (concat yuuji@73: "\\(" yuuji@73: (YaTeX-replace-format-args yuuji@73: (regexp-quote YaTeX-struct-end) env "" "") yuuji@73: "\\)\\|\\(" yuuji@73: (YaTeX-replace-format-args yuuji@73: (regexp-quote YaTeX-struct-begin) env "" "") yuuji@73: "\\)")) yuuji@73: (setq re-s 're-search-forward)) yuuji@73: (m2 ;if end{xxx} yuuji@73: (setq env yuuji@73: (if allow-mismatch YaTeX-struct-name-regexp yuuji@73: (regexp-quote (buffer-substring m2 (match-end 2))))) yuuji@451: ; (setq regexp (concat "\\(\\\\begin{" env "}\\)\\|" yuuji@451: ; "\\(\\\\end{" env "}\\)")) yuuji@73: (setq regexp yuuji@73: (concat yuuji@73: "\\(" yuuji@73: (YaTeX-replace-format-args yuuji@73: (regexp-quote YaTeX-struct-begin) env "" "") yuuji@73: "\\)\\|\\(" yuuji@73: (YaTeX-replace-format-args yuuji@73: (regexp-quote YaTeX-struct-end) env "" "") yuuji@73: "\\)")) yuuji@73: (setq re-s 're-search-backward)) yuuji@73: (m3 ;math environment yuuji@73: (setq env (char-after (1+ m3)) yuuji@73: regexp (format "\\(%s%s\\)\\|\\(%s%s\\)" yuuji@73: YaTeX-ec-regexp yuuji@73: (regexp-quote yuuji@561: (cdr (assq env '((?\( . ")") (?\) . "(") yuuji@561: (?\[ . "]") (?\] . "["))))) yuuji@73: YaTeX-ec-regexp yuuji@73: (regexp-quote (char-to-string env))) yuuji@73: re-s (if (memq env '(?\( ?\[)) yuuji@73: 're-search-forward yuuji@73: 're-search-backward))) yuuji@73: (t (if noerr nil (error "Corresponding environment not found.")))) yuuji@73: (progn yuuji@73: (while (and (>= nest 0) (funcall re-s regexp nil t)) yuuji@73: (setq b0 (match-beginning 0) b1 (match-beginning 1)) yuuji@73: (if (or (equal b0 m0) yuuji@73: (YaTeX-literal-p b0)) yuuji@73: nil yuuji@73: (setq nest (if (equal b0 b1) yuuji@73: (1- nest) (1+ nest))))) yuuji@73: (if (< nest 0) yuuji@73: (goto-char (match-beginning 0)) ;found. yuuji@73: (goto-char op) yuuji@73: (funcall yuuji@73: (if noerr 'message 'error) yuuji@73: "Corresponding environment `%s' not found." env) yuuji@451: (or bg (sit-for 1)) yuuji@73: nil)))))) yuuji@73: yuuji@64: (defun YaTeX-end-environment () yuuji@64: "Close opening environment" yuuji@64: (interactive) yuuji@64: (let ((env (YaTeX-inner-environment))) yuuji@64: (if (not env) (error "No premature environment") yuuji@64: (save-excursion yuuji@187: (if (and yuuji@187: (YaTeX-re-search-active-forward yuuji@187: (concat yuuji@187: "\\(" (YaTeX-replace-format-args yuuji@187: YaTeX-struct-end env "" "") yuuji@187: "\\)\\|\\(" (YaTeX-replace-format-args yuuji@187: YaTeX-struct-begin env "" "") yuuji@187: "\\)") yuuji@187: YaTeX-comment-prefix nil t) yuuji@187: (match-beginning 1)) ;is closing struc. yuuji@64: (if (y-or-n-p yuuji@64: (concat "Environment `" env yuuji@64: "' may be already closed. Force close?")) yuuji@64: nil yuuji@64: (error "end environment aborted.")))) yuuji@64: (message "") ;Erase (y or n) message. yuuji@64: (YaTeX-insert-struc 'end env) yuuji@64: (save-excursion yuuji@64: (goto-char (or (get 'YaTeX-inner-environment 'point) (match-end 0))) yuuji@64: (if (pos-visible-in-window-p) yuuji@64: (sit-for (if YaTeX-dos 2 1)) yuuji@64: (message "Matches with %s at line %d" yuuji@64: (YaTeX-replace-format-args YaTeX-struct-begin env "" "") yuuji@69: (count-lines (point-min) (point)))))))) yuuji@64: yuuji@70: (defun YaTeX-beginning-of-environment (&optional limit-search-bound end) yuuji@70: "Goto the beginning of the current environment. yuuji@70: Optional argument LIMIT-SEARCH-BOUND non-nil limits the search bound to yuuji@70: most recent sectioning command. Non-nil for optional third argument END yuuji@70: goes to end of environment." yuuji@70: (interactive) yuuji@70: (let ((op (point))) yuuji@70: (if (YaTeX-inner-environment limit-search-bound) yuuji@70: (progn yuuji@70: (goto-char (get 'YaTeX-inner-environment 'point)) yuuji@70: (and end (YaTeX-goto-corresponding-environment)) yuuji@70: (if (interactive-p) (push-mark op)) yuuji@80: (point))))) yuuji@70: yuuji@70: (defun YaTeX-end-of-environment (&optional limit-search-bound) yuuji@70: "Goto the end of the current environment. yuuji@70: Optional argument LIMIT-SEARCH-BOUND non-nil limits the search bound yuuji@70: to most recent sectioning command." yuuji@70: (interactive) yuuji@70: (YaTeX-beginning-of-environment limit-search-bound t)) yuuji@70: yuuji@70: (defun YaTeX-mark-environment () yuuji@70: "Mark current position and move point to end of environment." yuuji@70: (interactive) yuuji@130: (require 'yatexmth) yuuji@70: (let ((curp (point))) yuuji@130: (if (YaTeX-in-math-mode-p) yuuji@130: (YaTeX-mark-mathenv) yuuji@130: (if (and (YaTeX-on-begin-end-p) (match-beginning 1)) ;if on \\begin yuuji@130: (progn (goto-char (match-end 0))) yuuji@130: (if (= (char-after (point)) ?\\) nil ;if on \\end yuuji@130: (skip-chars-backward "^\n\\\\") yuuji@130: (or (bolp) (forward-char -1)))) yuuji@130: (if (not (YaTeX-end-of-environment)) ;arg1 turns to match-beginning 1 yuuji@70: (progn yuuji@130: (goto-char curp) yuuji@130: (error "Cannot found the end of current environment.")) yuuji@130: (YaTeX-goto-corresponding-environment) yuuji@380: ;;(beginning-of-line) ;for confirmation ;OUT 2015/1/4 yuuji@130: (if (< curp (point)) yuuji@130: (progn yuuji@130: (message "Mark this environment?(y or n): ") yuuji@130: (if (= (read-char) ?y) nil yuuji@130: (goto-char curp) yuuji@130: (error "Abort. Please call again at more proper position.")))) yuuji@130: (set-mark-command nil) yuuji@130: (YaTeX-goto-corresponding-environment) yuuji@380: (goto-char (match-end 0)) yuuji@380: ;;(end-of-line) ;OUT 2015/1/5 yuuji@380: ;;(if (eobp) nil (forward-char 1)) ;OUT 2015/1/5 yuuji@380: )))) yuuji@70: yuuji@524: (defun YaTeX-in-BEGEND-p (&optional pt) yuuji@524: "Check if the point (or PT) is in a %#BEGIN...%#END region. yuuji@515: Return the list of beginning and ending point of the region and arg-string yuuji@515: if the point is in BEGEND. Otherwise nil." yuuji@515: (let ((b "%#BEGIN") bp args (e "%#END") (p (point))) yuuji@515: (save-excursion yuuji@515: (save-match-data ;emacs-19+ yatex1.80+ yuuji@515: (and (re-search-backward b nil t) yuuji@515: (progn yuuji@515: (setq bp (match-beginning 0)) yuuji@515: (goto-char (match-end 0)) ;Start to get args of %#BEGIN yuuji@515: (skip-chars-forward " \t") yuuji@515: (setq args (YaTeX-buffer-substring (point) (point-end-of-line)))) yuuji@515: (re-search-forward e nil t) yuuji@515: (> (point) p) yuuji@515: (list bp (match-end 0) args)))))) yuuji@515: yuuji@72: (defun YaTeX-kill-buffer (buffer) yuuji@72: "Make effort to show parent buffer after kill." yuuji@72: (interactive "bKill buffer: ") yuuji@72: (or (get-buffer buffer) yuuji@72: (error "No such buffer %s" buffer)) yuuji@72: (let ((pf YaTeX-parent-file)) yuuji@72: (kill-buffer buffer) yuuji@72: (and pf yuuji@72: (get-file-buffer pf) yuuji@72: (switch-to-buffer (get-file-buffer pf))))) yuuji@70: yuuji@225: (defun YaTeX-getset-builtin (key &optional value) yuuji@142: "Read source built-in command of %# usage." yuuji@142: (catch 'builtin yuuji@225: (let*((bl (delq nil (list (current-buffer) yuuji@142: (and YaTeX-parent-file yuuji@142: (get-file-buffer YaTeX-parent-file))))) yuuji@225: (tuple (cdr (assq major-mode yuuji@225: '((yatex-mode "%#" . "\n") yuuji@225: (yahtml-mode "\\|\n"))))) yuuji@225: (leader (or (car tuple) "")) yuuji@225: (closer (or (cdr tuple) "")) yuuji@225: (prompt (format "Built-in for %s: " key))) yuuji@142: (save-excursion yuuji@142: (while bl yuuji@142: (set-buffer (car bl)) yuuji@142: (save-excursion yuuji@142: (goto-char (point-min)) yuuji@142: (if (and (re-search-forward yuuji@142: (concat "^" (regexp-quote (concat leader key))) nil t) yuuji@142: (not (eolp))) yuuji@142: (throw 'builtin yuuji@225: (let (b e w) yuuji@225: (skip-chars-forward " \t" (point-end-of-line)) yuuji@225: (setq b (point) yuuji@225: e (if (re-search-forward closer nil t) yuuji@225: (match-beginning 0) yuuji@225: (point-end-of-line)) yuuji@225: w (YaTeX-buffer-substring b e)) yuuji@225: (if (null value) yuuji@225: w yuuji@225: (delete-region b e) yuuji@225: (goto-char b) yuuji@225: (if (symbolp value) yuuji@225: (setq value (read-string prompt w))) yuuji@225: (insert value) yuuji@225: value))))) yuuji@225: (setq bl (cdr bl))) yuuji@225: ; not found yuuji@225: (if (null value) yuuji@225: nil ;not set mode, return simply nil yuuji@225: (if (symbolp value) yuuji@225: (setq value (read-string prompt))) yuuji@225: (save-excursion yuuji@225: (goto-char (point-min)) yuuji@225: (insert leader key " " value "\n") yuuji@225: value)))))) ;on set mode, return set value yuuji@225: yuuji@225: (defun YaTeX-get-builtin (key) yuuji@225: "Read source built-in command of %# usage." yuuji@225: (YaTeX-getset-builtin key)) yuuji@142: yuuji@64: ;;;VER2 yuuji@64: (defun YaTeX-insert-struc (what env) yuuji@64: (cond yuuji@64: ((eq what 'begin) yuuji@64: (insert (YaTeX-replace-format-args yuuji@64: YaTeX-struct-begin env (YaTeX-addin env)))) yuuji@64: ((eq what 'end) yuuji@64: (insert (YaTeX-replace-format-args YaTeX-struct-end env))) yuuji@69: (t nil))) yuuji@64: yuuji@80: (defun YaTeX-string-width (str) yuuji@80: "Return the display width of string." yuuji@80: (if (fboundp 'string-width) yuuji@80: (string-width str) yuuji@80: (length str))) yuuji@80: (defun YaTeX-truncate-string-width (str width) yuuji@80: (cond yuuji@80: ((fboundp 'truncate-string-to-width) (truncate-string-to-width str width)) yuuji@80: ((fboundp 'truncate-string) (truncate-string str width)) yuuji@80: (t (substring str 0 width)))) yuuji@80: yuuji@142: (defun YaTeX-hex (str) yuuji@142: "Return int expressed by hexadecimal string STR." yuuji@142: (if (string< "20" emacs-version) yuuji@142: (string-to-number str 16) yuuji@142: (let ((md (match-data))) yuuji@142: (unwind-protect yuuji@142: (if (string-match "[^0-9a-f]" str) yuuji@142: (error "Non hexadecimal character in %s" str) yuuji@142: (let ((i 0) d) yuuji@142: (setq str (downcase str)) yuuji@142: (while (string< "" str) yuuji@142: (setq d (+ 0 (string-to-char str)) ; + 0 for XEmacs yuuji@142: i (+ (* 16 i) (- d (if (<= d ?9) ?0 (- ?a 10)))) yuuji@142: str (substring str 1))) yuuji@142: i)) yuuji@142: (store-match-data md))))) yuuji@142: yuuji@142: yuuji@64: ;;; Function for menu support yuuji@64: (defun YaTeX-define-menu (keymap bindlist) yuuji@64: "Define KEYMAP(symbol)'s menu-bindings according to BINDLIST. yuuji@64: KEYMAP should be a quoted symbol of newly allocated keymap. yuuji@64: BINDLIST consists of binding list. Each element is as follows. yuuji@64: yuuji@64: '(menusymbol DOC_String . contents) yuuji@64: yuuji@64: CONTENTS is one of lambda-form, interactive function, or other keymap. yuuji@64: See yatex19.el for example." yuuji@64: (cond yuuji@64: ((featurep 'xemacs) yuuji@64: (let (name) yuuji@64: (if (keymapp (symbol-value keymap)) yuuji@64: (progn yuuji@64: (setq name (keymap-name (symbol-value keymap))) yuuji@64: (set keymap nil)) yuuji@64: (setq name (car (symbol-value keymap))) yuuji@64: (set keymap (cdr (symbol-value keymap)))) yuuji@64: (mapcar yuuji@64: (function yuuji@64: (lambda (bind) yuuji@64: (setq bind (cdr bind)) yuuji@64: (if (eq (car-safe (cdr bind)) 'lambda) yuuji@64: (setcar (cdr bind) 'progn)) yuuji@64: (if (stringp (car-safe (cdr bind))) yuuji@64: (set keymap yuuji@64: (cons (cdr bind) (symbol-value keymap))) yuuji@64: (set keymap yuuji@64: (cons (vector (car bind) (cdr bind) t) yuuji@64: (symbol-value keymap)))))) yuuji@64: bindlist) yuuji@64: (set keymap (cons name (symbol-value keymap))))) yuuji@64: (t yuuji@64: (mapcar yuuji@64: (function yuuji@64: (lambda (bind) yuuji@64: (define-key (symbol-value keymap) (vector (car bind)) (cdr bind)))) yuuji@64: bindlist)))) yuuji@64: yuuji@72: ;;; yuuji@72: ;; Emacs 21 compensational wrapper yuuji@72: ;;; yuuji@72: (defun YaTeX-minibuffer-begin () yuuji@72: (if (fboundp 'field-beginning) yuuji@72: (field-beginning (point-max)) yuuji@72: (point-min))) yuuji@72: yuuji@72: (defun YaTeX-minibuffer-end () yuuji@72: (if (fboundp 'field-end) yuuji@72: (field-end (point-max)) yuuji@72: (point-max))) yuuji@72: yuuji@72: (defun YaTeX-minibuffer-string () yuuji@72: (buffer-substring (YaTeX-minibuffer-begin) (YaTeX-minibuffer-end))) yuuji@72: yuuji@72: (defun YaTeX-minibuffer-erase () yuuji@72: (if (eq (selected-window) (minibuffer-window)) yuuji@72: (if (fboundp 'delete-field) (delete-field) (erase-buffer)))) yuuji@72: yuuji@80: (fset 'YaTeX-buffer-substring yuuji@80: (if (fboundp 'buffer-substring-no-properties) yuuji@80: 'buffer-substring-no-properties yuuji@80: 'buffer-substring)) yuuji@80: yuuji@392: (defun YaTeX-region-active-p () yuuji@392: (and (fboundp 'region-active-p) (region-active-p))) yuuji@392: yuuji@72: ;;; yuuji@72: ;; hilit19 vs. font-lock yuuji@72: ;;; yuuji@80: (defvar YaTeX-19-functions-font-lock-direct yuuji@80: '(YaTeX-19-re-search-in-env)) yuuji@80: yuuji@72: (defun YaTeX-convert-pattern-hilit2fontlock (h19pa) yuuji@72: "Convert hilit19's H19PA patterns alist to font-lock's one. yuuji@72: This function is a makeshift for YaTeX and yahtml." yuuji@72: (let ((ignorecase (not (null (car h19pa)))) yuuji@72: (palist (cdr h19pa)) yuuji@72: flpa i newface yuuji@72: (mapping yuuji@72: '((bold . YaTeX-font-lock-bold-face) yuuji@72: (italic . YaTeX-font-lock-italic-face) yuuji@73: (defun . font-lock-function-name-face) yuuji@73: (define . font-lock-variable-name-face) yuuji@72: (keyword . font-lock-keyword-face) yuuji@72: (decl . YaTeX-font-lock-declaration-face) yuuji@72: (label . YaTeX-font-lock-label-face) yuuji@72: (crossref . YaTeX-font-lock-crossref-face) yuuji@72: (include . YaTeX-font-lock-include-face) yuuji@72: (formula . YaTeX-font-lock-formula-face) yuuji@80: (delimiter . YaTeX-font-lock-delimiter-face) yuuji@72: (string . ignore) (comment . ignore) yuuji@72: ))) yuuji@72: (while (setq i (car palist)) yuuji@72: (setq newface (nth 2 i) yuuji@72: newface (or (cdr (assq newface mapping)) newface)) yuuji@72: (cond yuuji@72: ((eq newface 'ignore) nil) ;no translation yuuji@72: ((stringp (car i)) ;hiliting by regexp yuuji@72: (setq flpa yuuji@72: (cons yuuji@72: (if (numberp (car (cdr i))) yuuji@72: (list (car i) ;regexp yuuji@72: (car (cdr i)) ;matching group number yuuji@73: newface nil) ;'keep) ;keep is hilit19 taste yuuji@72: (list yuuji@72: (concat yuuji@72: (car i) ;original regexp and.. yuuji@72: ;;"[^" yuuji@72: ;;(regexp-quote (substring (car (cdr i)) 0 1)) yuuji@72: ;;"]+" ;for shortest match yuuji@72: ".*" yuuji@72: (car (cdr i))) yuuji@73: 0 (list 'quote newface) nil)) ;;'keep)) yuuji@72: flpa))) yuuji@72: ((and (symbolp (car i)) (fboundp (car i))) yuuji@80: (if (memq (car i) YaTeX-19-functions-font-lock-direct) yuuji@80: ;; Put direct function call for it. yuuji@80: ;; When calling this function, fontify entire matched string. yuuji@80: (setq flpa yuuji@80: (cons yuuji@80: (list yuuji@80: (list 'lambda (list 'dummy) ;dummy should be boundary yuuji@80: (list (car i) (list 'quote (car (cdr i))))) yuuji@80: (list 0 newface)) yuuji@80: flpa)) yuuji@80: (setq flpa yuuji@80: (cons yuuji@80: (list (car (cdr i)) ;regexp yuuji@72: (list yuuji@72: (list yuuji@80: 'lambda (list 'dummy) yuuji@80: '(goto-char (match-beginning 0)) yuuji@80: (if (eq (nth 3 i) 'overwrite) yuuji@80: nil yuuji@80: '(remove-text-properties yuuji@80: (point) (min (point-max) (1+ (point))) yuuji@80: '(face nil font-lock-multiline nil))) yuuji@72: (list yuuji@80: 'let (list '(e (match-end 0)) yuuji@80: (list 'm (list (car i) (car (cdr i))))) yuuji@80: (list yuuji@80: 'if 'm yuuji@80: (list yuuji@80: 'YaTeX-font-lock-fillin yuuji@80: (list 'car 'm) yuuji@80: (list 'cdr 'm) yuuji@80: (list 'quote 'face) yuuji@80: (list 'quote 'font-lock) yuuji@80: (list 'quote newface)) yuuji@80: '(goto-char e) yuuji@80: )) yuuji@80: nil) ;retun nil to cheat font-lock yuuji@80: nil nil)) ;pre-match, post-match both nil yuuji@80: flpa))))) yuuji@72: (setq palist (cdr palist)));while yuuji@72: (if (featurep 'xemacsp) yuuji@72: (nreverse flpa) yuuji@72: flpa))) yuuji@72: yuuji@73: (if (and (boundp 'YaTeX-use-font-lock) yuuji@73: YaTeX-use-font-lock) yuuji@73: (require 'font-lock)) yuuji@73: yuuji@72: (cond yuuji@73: ((and (featurep 'font-lock) (fboundp 'defface)) yuuji@72: ;; In each defface, '(class static-color) is for Emacs-21 -nw yuuji@72: ;; '(class tty) is for XEmacs-21 -nw yuuji@72: (defface YaTeX-font-lock-label-face yuuji@72: '((((class static-color)) (:foreground "yellow" :underline t)) yuuji@72: (((type tty)) (:foreground "yellow" :underline t)) yuuji@72: (((class color) (background dark)) (:foreground "pink" :underline t)) yuuji@72: (((class color) (background light)) (:foreground "red" :underline t)) yuuji@72: (t (:bold t :underline t))) yuuji@72: "Font Lock mode face used to highlight labels." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-label-face 'YaTeX-font-lock-label-face) yuuji@72: yuuji@72: (defface YaTeX-font-lock-declaration-face yuuji@72: '((((class color) (background dark)) (:foreground "cyan")) yuuji@72: (((class color) (background light)) (:foreground "RoyalBlue")) yuuji@72: (t (:bold t :underline t))) yuuji@72: "Font Lock mode face used to highlight some declarations." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-declaration-face 'YaTeX-font-lock-declaration-face) yuuji@72: yuuji@72: (defface YaTeX-font-lock-include-face yuuji@72: '((((class color) (background dark)) (:foreground "Plum1")) yuuji@72: (((class color) (background light)) (:foreground "purple")) yuuji@72: (t (:bold t :underline t))) yuuji@72: "Font Lock mode face used to highlight expression for including." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-include-face 'YaTeX-font-lock-include-face) yuuji@72: yuuji@72: (defface YaTeX-font-lock-formula-face yuuji@72: '((((class static-color)) (:bold t)) yuuji@72: (((type tty)) (:bold t)) yuuji@72: (((class color) (background dark)) (:foreground "khaki" :bold t)) yuuji@376: (((class color) (background light)) (:foreground "DarkGoldenrod4")) yuuji@72: (t (:bold t :underline t))) yuuji@72: "Font Lock mode face used to highlight formula." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-formula-face 'YaTeX-font-lock-formula-face) yuuji@72: yuuji@80: (defface YaTeX-font-lock-delimiter-face yuuji@80: '((((class static-color)) (:bold t)) yuuji@80: (((type tty)) (:bold t)) yuuji@80: (((class color) (background dark)) yuuji@376: (:foreground "lightyellow3" :background "navy" :bold t)) yuuji@80: (((class color) (background light)) (:foreground "red")) yuuji@80: (t (:bold t :underline t))) yuuji@80: "Font Lock mode face used to highlight delimiters." yuuji@80: :group 'font-lock-faces) yuuji@80: (defvar YaTeX-font-lock-delimiter-face 'YaTeX-font-lock-delimiter-face) yuuji@80: yuuji@80: (defface YaTeX-font-lock-math-sub-face yuuji@80: '((((class static-color)) (:bold t)) yuuji@80: (((type tty)) (:bold t)) yuuji@80: (((class color) (background dark)) yuuji@80: (:foreground "khaki" :bold t :underline t)) yuuji@80: (((class color) (background light)) yuuji@376: (:foreground "DarkGoldenrod4" :underline t)) yuuji@80: (t (:bold t :underline t))) yuuji@80: "Font Lock mode face used to highlight subscripts in formula." yuuji@80: :group 'font-lock-faces) yuuji@80: (defvar YaTeX-font-lock-math-sub-face 'YaTeX-font-lock-math-sub-face) yuuji@80: yuuji@80: (defface YaTeX-font-lock-math-sup-face yuuji@80: '((((class static-color)) (:bold t)) yuuji@80: (((type tty)) (:bold t)) yuuji@80: (((class color) (background dark)) yuuji@80: (:bold nil :foreground "ivory" :background "lightyellow4")) yuuji@80: (((class color) (background light)) yuuji@376: (:underline t :foreground "DarkGoldenrod3")) yuuji@80: (t (:bold t :underline t))) yuuji@80: "Font Lock mode face used to highlight superscripts in formula." yuuji@80: :group 'font-lock-faces) yuuji@80: (defvar YaTeX-font-lock-math-sup-face 'YaTeX-font-lock-math-sup-face) yuuji@80: yuuji@72: (defface YaTeX-font-lock-crossref-face yuuji@72: '((((class color) (background dark)) (:foreground "lightgoldenrod")) yuuji@72: (((class color) (background light)) (:foreground "DarkGoldenrod")) yuuji@72: (t (:bold t :underline t))) yuuji@80: "Font Lock mode face used to highlight cross references." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-crossref-face 'YaTeX-font-lock-crossref-face) yuuji@72: yuuji@72: (defface YaTeX-font-lock-bold-face yuuji@72: '((t (:bold t))) yuuji@72: "Font Lock mode face used to express bold itself." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-bold-face 'YaTeX-font-lock-bold-face) yuuji@72: yuuji@72: (defface YaTeX-font-lock-italic-face yuuji@72: '((t (:italic t))) yuuji@72: "Font Lock mode face used to express italic itself." yuuji@72: :group 'font-lock-faces) yuuji@72: (defvar YaTeX-font-lock-italic-face 'YaTeX-font-lock-italic-face) yuuji@72: yuuji@72: ;; Make sure the 'YaTeX-font-lock-{italic,bold}-face is bound with yuuji@72: ;; italic/bold fontsets yuuji@72: (if (and (fboundp 'fontset-list) YaTeX-use-italic-bold) yuuji@73: (let ((flist (fontset-list)) fnt italic bold yuuji@73: (df (or (and (fboundp 'face-font-name) (face-font-name 'default)) yuuji@73: (face-font 'default) yuuji@73: (face-font 'italic) yuuji@73: (face-font 'bold) yuuji@73: "giveup!")) yuuji@73: sz medium-i bold-r) yuuji@310: (if (string-match yuuji@310: "^-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-[^-]*-\\(\\([0-9]+\\)\\)" df) yuuji@310: (setq sz (or (match-string 1 df) "16")) yuuji@310: (setq sz "16")) yuuji@73: (setq medium-i (format "-medium-i-[^-]+--%s" sz) yuuji@73: bold-r (format "-bold-r-[^-]+--%s" sz)) yuuji@72: (while flist yuuji@72: (setq fnt (car flist)) yuuji@72: (condition-case err yuuji@72: (cond yuuji@73: ((and (string-match medium-i fnt) yuuji@73: (null italic)) yuuji@72: (set-face-font 'YaTeX-font-lock-italic-face (setq italic fnt))) yuuji@73: ((and (string-match bold-r fnt) (null bold)) yuuji@72: (set-face-font 'YaTeX-font-lock-bold-face (setq bold fnt)))) yuuji@72: (error nil)) yuuji@72: (setq flist (cdr flist))))) yuuji@72: yuuji@72: ;;Borrowed from XEmacs's font-lock.el yuuji@72: (defsubst YaTeX-font-lock-fillin (start end setprop markprop value &optional object) yuuji@72: "Fill in one property of the text from START to END. yuuji@72: Arguments PROP and VALUE specify the property and value to put where none are yuuji@72: already in place. Therefore existing property values are not overwritten. yuuji@72: Optional argument OBJECT is the string or buffer containing the text." yuuji@72: (let ((start (text-property-any start end markprop nil object)) next yuuji@72: (putfunc (if (fboundp 'put-nonduplicable-text-property) yuuji@72: 'put-nonduplicable-text-property yuuji@72: 'put-text-property))) yuuji@72: (if (eq putfunc 'put-text-property) yuuji@72: (setq markprop setprop)) yuuji@72: (while start yuuji@72: (setq next (next-single-property-change start markprop object end)) yuuji@72: (funcall putfunc start next setprop value object) yuuji@72: (funcall putfunc start next markprop value object) yuuji@72: (setq start (text-property-any next end markprop nil object))))) yuuji@72: yuuji@72: (defun YaTeX-warning-font-lock (mode) yuuji@72: (let ((sw (selected-window))) yuuji@72: ;;(pop-to-buffer (format " *%s warning*" mode)) yuuji@72: ;;(erase-buffer) yuuji@72: (momentary-string-display yuuji@72: (cond yuuji@72: (YaTeX-japan yuuji@72: (concat mode " は、既に font-lock に対応しました。\n" yuuji@72: "~/.emacs などにある\n" yuuji@72: "\t(put 'yatex-mode 'font-lock-keywords 'tex-mode)\n" yuuji@72: "\t(put 'yahtml-mode 'font-lock-keywords 'html-mode)\n" yuuji@72: "などの間に合わせの記述はもはや不要です。")) yuuji@72: (t yuuji@72: (concat mode " now supports the font-lock by itself.\n" yuuji@72: "So you can remove the descriptions such as\n" yuuji@72: "\t(put 'yatex-mode 'font-lock-keywords 'tex-mode)\n" yuuji@72: "\t(put 'yahtml-mode 'font-lock-keywords 'html-mode)\n" yuuji@72: "in your ~/.emacs file. Thank you."))) (point)) yuuji@72: (select-window sw))) yuuji@72: )) yuuji@72: yuuji@80: (defun YaTeX-assoc-regexp (elt alist) yuuji@80: "Like assoc, return a list of whose car match with ELT. Search from ALIST. yuuji@80: Note that each car of cons-cell is regexp. ELT is a plain text to be yuuji@80: compared by regexp." yuuji@80: (let (x) yuuji@80: (catch 'found yuuji@80: (while alist yuuji@80: (setq x (car (car alist))) yuuji@80: (if (string-match x elt) yuuji@80: (throw 'found (car alist))) yuuji@80: (setq alist (cdr alist)))))) yuuji@64: yuuji@247: (defun YaTeX-push-to-kill-ring (string) yuuji@247: "Push STRING to kill-ring, then show guidance message." yuuji@247: (and (stringp string) (string< "" string) yuuji@247: (let ((key (key-description (where-is-internal 'yank nil t))) yuuji@247: (msg yuuji@247: (if YaTeX-japan yuuji@247: " をkill-ringに入れました。次のyank(%s)で貼付できます" yuuji@247: " is stored into kill-ring. Paste it by yank(%s)."))) yuuji@247: (kill-new string) yuuji@247: (message (concat "`%s'" msg) string key)))) yuuji@247: yuuji@262: (defun YaTeX-elapsed-time (before after) yuuji@262: "Get elapsed time from BEFORE and AFTER, which are given from currente-time." yuuji@262: (if (fboundp 'float) ;Then, current-time function should be. yuuji@262: (let ((mil (float 1000000))) ;To protect parse error before 19 yuuji@262: (+ (* (- (nth 0 after) (nth 0 before)) 65536) yuuji@262: (- (nth 1 after) (nth 1 before)) yuuji@262: (- (/ (nth 2 after) mil) yuuji@262: (/ (nth 2 before) mil)))))) yuuji@262: yuuji@68: ;;; yuuji@482: ;; Moved from comment.el yuuji@482: ;;; yuuji@482: (defun YaTeX-comment-region-sub (string &optional beg end once) yuuji@483: "Insert STRING at the beginning of every line between BEG and END." yuuji@482: (if (not (stringp string)) (setq string YaTeX-comment-prefix)) yuuji@482: (let ((b (or beg (region-beginning))) (e (or end (region-end)))) yuuji@482: (save-excursion yuuji@482: (goto-char (max b e)) yuuji@482: (if (bolp) yuuji@482: (forward-line -1)) yuuji@482: (save-restriction yuuji@482: (narrow-to-region (min b e) (point)) yuuji@482: (goto-char (point-min)) yuuji@482: (message "%s" string) yuuji@482: (while (re-search-forward "^" nil t) yuuji@482: (insert string)))))) yuuji@482: yuuji@482: (defun YaTeX-uncomment-region-sub (string &optional beg end once) yuuji@483: "Delete STRING from the beginning of every line between BEG and END. yuuji@483: BEG and END are optional. If omitted, active region used. yuuji@483: Non-nil for optional 4th argument ONCE withholds from removing yuuji@483: successive comment chars at the beggining of lines." yuuji@482: (save-excursion yuuji@482: (save-restriction yuuji@482: (narrow-to-region (or beg (region-beginning)) (or end (region-end))) yuuji@482: (goto-char (point-min)) yuuji@482: (while (re-search-forward (concat "^" string) nil t) yuuji@482: (replace-match "") yuuji@482: (if once (end-of-line)))))) yuuji@482: yuuji@482: ;;; yuuji@68: ;; Functions for the Installation time yuuji@68: ;;; yuuji@64: yuuji@58: (defun bcf-and-exit () yuuji@58: "Byte compile rest of argument and kill-emacs." yuuji@58: (if command-line-args-left yuuji@68: (let ((load-path (cons "." load-path))) yuuji@68: (and (fboundp 'set-language-environment) yuuji@68: (featurep 'mule) yuuji@68: (set-language-environment "Japanese")) yuuji@58: (mapcar 'byte-compile-file command-line-args-left) yuuji@58: (kill-emacs)))) yuuji@64: yuuji@80: (defun tfb-and-exit () yuuji@80: "Texinfo-format-buffer and kill-emacs." yuuji@80: (if command-line-args-left yuuji@80: (let ((load-path (cons ".." load-path))) yuuji@80: (and (fboundp 'set-language-environment) yuuji@80: (featurep 'mule) yuuji@80: (set-language-environment "Japanese")) yuuji@80: (mapcar (function yuuji@80: (lambda (arg) yuuji@80: (find-file arg) yuuji@80: (texinfo-format-buffer) yuuji@266: (cond yuuji@266: ((fboundp 'set-buffer-file-coding-system) yuuji@266: (set-buffer-file-coding-system 'sjis-dos)) yuuji@266: ((fboundp 'set-file-coding-system) yuuji@266: (set-file-coding-system '*sjis*dos)) yuuji@266: ((boundp 'NEMACS) yuuji@266: (set (make-local-variable 'kanji-fileio-code) 1))) yuuji@266: (let ((coding-system-for-write buffer-file-coding-system)) yuuji@266: (basic-save-buffer)))) yuuji@80: command-line-args-left) yuuji@80: (kill-emacs)))) yuuji@80: yuuji@23: (provide 'yatexlib)