diff options
| -rw-r--r-- | lisp/textmodes/tex-mode.el | 131 |
1 files changed, 98 insertions, 33 deletions
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index b1fd6568c31..87f7b6b5c04 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el | |||
| @@ -499,7 +499,8 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 499 | (bold (regexp-opt '("textbf" "textsc" "textup" | 499 | (bold (regexp-opt '("textbf" "textsc" "textup" |
| 500 | "boldsymbol" "pmb") t)) | 500 | "boldsymbol" "pmb") t)) |
| 501 | (italic (regexp-opt '("textit" "textsl" "emph") t)) | 501 | (italic (regexp-opt '("textit" "textsl" "emph") t)) |
| 502 | (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t)) | 502 | ;; FIXME: unimplemented yet. |
| 503 | ;; (type (regexp-opt '("texttt" "textmd" "textrm" "textsf") t)) | ||
| 503 | ;; | 504 | ;; |
| 504 | ;; Names of commands whose arg should be fontified as a citation. | 505 | ;; Names of commands whose arg should be fontified as a citation. |
| 505 | (citations (regexp-opt | 506 | (citations (regexp-opt |
| @@ -713,6 +714,7 @@ An alternative value is \" . \", if you use a font with a narrow period." | |||
| 713 | (defvar latex-mode-map | 714 | (defvar latex-mode-map |
| 714 | (let ((map (make-sparse-keymap))) | 715 | (let ((map (make-sparse-keymap))) |
| 715 | (set-keymap-parent map tex-mode-map) | 716 | (set-keymap-parent map tex-mode-map) |
| 717 | (define-key map "\C-c\C-s" 'latex-split-block) | ||
| 716 | map) | 718 | map) |
| 717 | "Keymap for `latex-mode'. See also `tex-mode-map'.") | 719 | "Keymap for `latex-mode'. See also `tex-mode-map'.") |
| 718 | 720 | ||
| @@ -745,15 +747,7 @@ Inherits `shell-mode-map' with a few additions.") | |||
| 745 | 747 | ||
| 746 | ;; This would be a lot simpler if we just used a regexp search, | 748 | ;; This would be a lot simpler if we just used a regexp search, |
| 747 | ;; but then it would be too slow. | 749 | ;; but then it would be too slow. |
| 748 | ;;;###autoload | 750 | (defun tex-guess-mode () |
| 749 | (defun tex-mode () | ||
| 750 | "Major mode for editing files of input for TeX, LaTeX, or SliTeX. | ||
| 751 | Tries to determine (by looking at the beginning of the file) whether | ||
| 752 | this file is for plain TeX, LaTeX, or SliTeX and calls `plain-tex-mode', | ||
| 753 | `latex-mode', or `slitex-mode', respectively. If it cannot be determined, | ||
| 754 | such as if there are no commands in the file, the value of `tex-default-mode' | ||
| 755 | says which mode to use." | ||
| 756 | (interactive) | ||
| 757 | (let ((mode tex-default-mode) slash comment) | 751 | (let ((mode tex-default-mode) slash comment) |
| 758 | (save-excursion | 752 | (save-excursion |
| 759 | (goto-char (point-min)) | 753 | (goto-char (point-min)) |
| @@ -778,6 +772,27 @@ says which mode to use." | |||
| 778 | 'plain-tex-mode)))) | 772 | 'plain-tex-mode)))) |
| 779 | (funcall mode))) | 773 | (funcall mode))) |
| 780 | 774 | ||
| 775 | ;; `tex-mode' plays two roles: it's the parent of several sub-modes | ||
| 776 | ;; but it's also the function that chooses between those submodes. | ||
| 777 | ;; To tell the difference between those two cases where the function | ||
| 778 | ;; might be called, we check `delay-mode-hooks'. | ||
| 779 | ;;;###autoload | ||
| 780 | (define-derived-mode tex-mode text-mode "generic-TeX" | ||
| 781 | (tex-common-initialization)) | ||
| 782 | (fset 'tex-mode | ||
| 783 | `(lambda () | ||
| 784 | "Major mode for editing files of input for TeX, LaTeX, or SliTeX. | ||
| 785 | Tries to determine (by looking at the beginning of the file) whether | ||
| 786 | this file is for plain TeX, LaTeX, or SliTeX and calls `plain-tex-mode', | ||
| 787 | `latex-mode', or `slitex-mode', respectively. If it cannot be determined, | ||
| 788 | such as if there are no commands in the file, the value of `tex-default-mode' | ||
| 789 | says which mode to use." | ||
| 790 | (interactive) | ||
| 791 | (if delay-mode-hooks | ||
| 792 | ;; We're called from one of the children already. | ||
| 793 | (funcall ,(symbol-function 'tex-mode)) | ||
| 794 | (tex-guess-mode)))) | ||
| 795 | |||
| 781 | ;;;###autoload | 796 | ;;;###autoload |
| 782 | (defalias 'TeX-mode 'tex-mode) | 797 | (defalias 'TeX-mode 'tex-mode) |
| 783 | ;;;###autoload | 798 | ;;;###autoload |
| @@ -786,7 +801,7 @@ says which mode to use." | |||
| 786 | (defalias 'LaTeX-mode 'latex-mode) | 801 | (defalias 'LaTeX-mode 'latex-mode) |
| 787 | 802 | ||
| 788 | ;;;###autoload | 803 | ;;;###autoload |
| 789 | (define-derived-mode plain-tex-mode text-mode "TeX" | 804 | (define-derived-mode plain-tex-mode tex-mode "TeX" |
| 790 | "Major mode for editing files of input for plain TeX. | 805 | "Major mode for editing files of input for plain TeX. |
| 791 | Makes $ and } display the characters they match. | 806 | Makes $ and } display the characters they match. |
| 792 | Makes \" insert `` when it seems to be the beginning of a quotation, | 807 | Makes \" insert `` when it seems to be the beginning of a quotation, |
| @@ -826,15 +841,13 @@ tex-show-queue-command | |||
| 826 | Entering Plain-tex mode runs the hook `text-mode-hook', then the hook | 841 | Entering Plain-tex mode runs the hook `text-mode-hook', then the hook |
| 827 | `tex-mode-hook', and finally the hook `plain-tex-mode-hook'. When the | 842 | `tex-mode-hook', and finally the hook `plain-tex-mode-hook'. When the |
| 828 | special subshell is initiated, the hook `tex-shell-hook' is run." | 843 | special subshell is initiated, the hook `tex-shell-hook' is run." |
| 829 | (tex-common-initialization) | 844 | (set (make-local-variable 'tex-command) tex-run-command) |
| 830 | (setq tex-command tex-run-command) | 845 | (set (make-local-variable 'tex-start-of-header) "%\\*\\*start of header") |
| 831 | (setq tex-start-of-header "%\\*\\*start of header") | 846 | (set (make-local-variable 'tex-end-of-header) "%\\*\\*end of header") |
| 832 | (setq tex-end-of-header "%\\*\\*end of header") | 847 | (set (make-local-variable 'tex-trailer) "\\bye\n")) |
| 833 | (setq tex-trailer "\\bye\n") | ||
| 834 | (run-hooks 'tex-mode-hook)) | ||
| 835 | 848 | ||
| 836 | ;;;###autoload | 849 | ;;;###autoload |
| 837 | (define-derived-mode latex-mode text-mode "LaTeX" | 850 | (define-derived-mode latex-mode tex-mode "LaTeX" |
| 838 | "Major mode for editing files of input for LaTeX. | 851 | "Major mode for editing files of input for LaTeX. |
| 839 | Makes $ and } display the characters they match. | 852 | Makes $ and } display the characters they match. |
| 840 | Makes \" insert `` when it seems to be the beginning of a quotation, | 853 | Makes \" insert `` when it seems to be the beginning of a quotation, |
| @@ -874,16 +887,16 @@ tex-show-queue-command | |||
| 874 | Entering Latex mode runs the hook `text-mode-hook', then | 887 | Entering Latex mode runs the hook `text-mode-hook', then |
| 875 | `tex-mode-hook', and finally `latex-mode-hook'. When the special | 888 | `tex-mode-hook', and finally `latex-mode-hook'. When the special |
| 876 | subshell is initiated, `tex-shell-hook' is run." | 889 | subshell is initiated, `tex-shell-hook' is run." |
| 877 | (tex-common-initialization) | 890 | (set (make-local-variable 'tex-command) latex-run-command) |
| 878 | (setq tex-command latex-run-command) | 891 | (set (make-local-variable 'tex-start-of-header) |
| 879 | (setq tex-start-of-header "\\\\document\\(style\\|class\\)") | 892 | "\\\\document\\(style\\|class\\)") |
| 880 | (setq tex-end-of-header "\\\\begin\\s-*{document}") | 893 | (set (make-local-variable 'tex-end-of-header) "\\\\begin\\s-*{document}") |
| 881 | (setq tex-trailer "\\end\\s-*{document}\n") | 894 | (set (make-local-variable 'tex-trailer) "\\end\\s-*{document}\n") |
| 882 | ;; A line containing just $$ is treated as a paragraph separator. | 895 | ;; A line containing just $$ is treated as a paragraph separator. |
| 883 | ;; A line starting with $$ starts a paragraph, | 896 | ;; A line starting with $$ starts a paragraph, |
| 884 | ;; but does not separate paragraphs if it has more stuff on it. | 897 | ;; but does not separate paragraphs if it has more stuff on it. |
| 885 | (setq paragraph-start | 898 | (setq paragraph-start |
| 886 | (concat "[\f%]\\|[ \t]*\\($\\|\\$\\$\\|" | 899 | (concat "[ \t]*\\(\\$\\$\\|" |
| 887 | "\\\\[][]\\|" | 900 | "\\\\[][]\\|" |
| 888 | "\\\\" (regexp-opt (append | 901 | "\\\\" (regexp-opt (append |
| 889 | (mapcar 'car latex-section-alist) | 902 | (mapcar 'car latex-section-alist) |
| @@ -913,8 +926,7 @@ subshell is initiated, `tex-shell-hook' is run." | |||
| 913 | (set (make-local-variable 'outline-regexp) latex-outline-regexp) | 926 | (set (make-local-variable 'outline-regexp) latex-outline-regexp) |
| 914 | (set (make-local-variable 'outline-level) 'latex-outline-level) | 927 | (set (make-local-variable 'outline-level) 'latex-outline-level) |
| 915 | (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp) | 928 | (set (make-local-variable 'forward-sexp-function) 'latex-forward-sexp) |
| 916 | (set (make-local-variable 'skeleton-end-hook) nil) | 929 | (set (make-local-variable 'skeleton-end-hook) nil)) |
| 917 | (run-hooks 'tex-mode-hook)) | ||
| 918 | 930 | ||
| 919 | ;;;###autoload | 931 | ;;;###autoload |
| 920 | (define-derived-mode slitex-mode latex-mode "SliTeX" | 932 | (define-derived-mode slitex-mode latex-mode "SliTeX" |
| @@ -962,7 +974,6 @@ Entering SliTeX mode runs the hook `text-mode-hook', then the hook | |||
| 962 | (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}")) | 974 | (setq tex-start-of-header "\\\\documentstyle{slides}\\|\\\\documentclass{slides}")) |
| 963 | 975 | ||
| 964 | (defun tex-common-initialization () | 976 | (defun tex-common-initialization () |
| 965 | (set-syntax-table tex-mode-syntax-table) | ||
| 966 | ;; Regexp isearch should accept newline and formfeed as whitespace. | 977 | ;; Regexp isearch should accept newline and formfeed as whitespace. |
| 967 | (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+") | 978 | (set (make-local-variable 'search-whitespace-regexp) "[ \t\r\n\f]+") |
| 968 | ;; A line containing just $$ is treated as a paragraph separator. | 979 | ;; A line containing just $$ is treated as a paragraph separator. |
| @@ -1069,8 +1080,7 @@ on the line for the invalidity you want to see." | |||
| 1069 | (num-matches 0)) | 1080 | (num-matches 0)) |
| 1070 | (with-output-to-temp-buffer "*Occur*" | 1081 | (with-output-to-temp-buffer "*Occur*" |
| 1071 | (princ "Mismatches:\n") | 1082 | (princ "Mismatches:\n") |
| 1072 | (save-excursion | 1083 | (with-current-buffer standard-output |
| 1073 | (set-buffer standard-output) | ||
| 1074 | (occur-mode) | 1084 | (occur-mode) |
| 1075 | ;; This won't actually work...Really, this whole thing should | 1085 | ;; This won't actually work...Really, this whole thing should |
| 1076 | ;; be rewritten instead of being a hack on top of occur. | 1086 | ;; be rewritten instead of being a hack on top of occur. |
| @@ -1087,8 +1097,7 @@ on the line for the invalidity you want to see." | |||
| 1087 | (forward-char 2)) | 1097 | (forward-char 2)) |
| 1088 | (goto-char (setq prev-end (point-min)))) | 1098 | (goto-char (setq prev-end (point-min)))) |
| 1089 | (or (tex-validate-region (point) end) | 1099 | (or (tex-validate-region (point) end) |
| 1090 | (let* ((oend end) | 1100 | (let* ((end (line-beginning-position 2)) |
| 1091 | (end (save-excursion (forward-line 1) (point))) | ||
| 1092 | start tem) | 1101 | start tem) |
| 1093 | (beginning-of-line) | 1102 | (beginning-of-line) |
| 1094 | (setq start (point)) | 1103 | (setq start (point)) |
| @@ -1844,7 +1853,6 @@ The last line of the buffer is displayed on | |||
| 1844 | line LINE of the window, or centered if LINE is nil." | 1853 | line LINE of the window, or centered if LINE is nil." |
| 1845 | (interactive "P") | 1854 | (interactive "P") |
| 1846 | (let ((tex-shell (get-buffer "*tex-shell*")) | 1855 | (let ((tex-shell (get-buffer "*tex-shell*")) |
| 1847 | (old-buffer (current-buffer)) | ||
| 1848 | (window)) | 1856 | (window)) |
| 1849 | (if (null tex-shell) | 1857 | (if (null tex-shell) |
| 1850 | (message "No TeX output buffer") | 1858 | (message "No TeX output buffer") |
| @@ -1971,7 +1979,7 @@ Runs the shell command defined by `tex-show-queue-command'." | |||
| 1971 | (defun latex-indent (&optional arg) | 1979 | (defun latex-indent (&optional arg) |
| 1972 | (if (and (eq (get-text-property (line-beginning-position) 'face) | 1980 | (if (and (eq (get-text-property (line-beginning-position) 'face) |
| 1973 | tex-verbatim-face)) | 1981 | tex-verbatim-face)) |
| 1974 | (indent-relative) | 1982 | 'noindent |
| 1975 | (with-syntax-table tex-latex-indent-syntax-table | 1983 | (with-syntax-table tex-latex-indent-syntax-table |
| 1976 | ;; TODO: Rather than ignore $, we should try to be more clever about it. | 1984 | ;; TODO: Rather than ignore $, we should try to be more clever about it. |
| 1977 | (let ((indent | 1985 | (let ((indent |
| @@ -2058,6 +2066,63 @@ There might be text before point." | |||
| 2058 | (min (current-column) (+ tex-indent-arg col)) | 2066 | (min (current-column) (+ tex-indent-arg col)) |
| 2059 | (skip-syntax-forward " ") | 2067 | (skip-syntax-forward " ") |
| 2060 | (current-column)))))))))) | 2068 | (current-column)))))))))) |
| 2069 | ;;; DocTeX support | ||
| 2070 | |||
| 2071 | (defun doctex-font-lock-^^A () | ||
| 2072 | (if (eq (char-after (line-beginning-position)) ?\%) | ||
| 2073 | (progn | ||
| 2074 | (put-text-property | ||
| 2075 | (1- (match-beginning 1)) (match-beginning 1) | ||
| 2076 | 'syntax-table | ||
| 2077 | (if (= (1+ (line-beginning-position)) (match-beginning 1)) | ||
| 2078 | ;; The `%' is a single-char comment, which Emacs | ||
| 2079 | ;; syntax-table can't deal with. We could turn it | ||
| 2080 | ;; into a non-comment, or use `\n%' or `%^' as the comment. | ||
| 2081 | ;; Instead, we include it in the ^^A comment. | ||
| 2082 | (eval-when-compile (string-to-syntax "< b")) | ||
| 2083 | (eval-when-compile (string-to-syntax ">")))) | ||
| 2084 | (let ((end (line-end-position))) | ||
| 2085 | (if (< end (point-max)) | ||
| 2086 | (put-text-property | ||
| 2087 | end (1+ end) | ||
| 2088 | 'syntax-table | ||
| 2089 | (eval-when-compile (string-to-syntax "> b"))))) | ||
| 2090 | (eval-when-compile (string-to-syntax "< b"))))) | ||
| 2091 | |||
| 2092 | (defun doctex-font-lock-syntactic-face-function (state) | ||
| 2093 | ;; Mark DocTeX documentation, which is parsed as a style A comment | ||
| 2094 | ;; starting in column 0. | ||
| 2095 | (if (or (nth 3 state) (nth 7 state) | ||
| 2096 | (not (memq (char-before (nth 8 state)) | ||
| 2097 | '(?\n nil)))) | ||
| 2098 | ;; Anything else is just as for LaTeX. | ||
| 2099 | (tex-font-lock-syntactic-face-function state) | ||
| 2100 | font-lock-doc-face)) | ||
| 2101 | |||
| 2102 | (defvar doctex-font-lock-syntactic-keywords | ||
| 2103 | (append | ||
| 2104 | tex-font-lock-syntactic-keywords | ||
| 2105 | ;; For DocTeX comment-in-doc. | ||
| 2106 | `(("\\(\\^\\)\\^A" (1 (doctex-font-lock-^^A)))))) | ||
| 2107 | |||
| 2108 | (defvar doctex-font-lock-keywords | ||
| 2109 | (append tex-font-lock-keywords | ||
| 2110 | '(("^%<[^>]*>" (0 font-lock-preprocessor-face t))))) | ||
| 2111 | |||
| 2112 | ;;;###autoload | ||
| 2113 | (define-derived-mode doctex-mode latex-mode "DocTeX" | ||
| 2114 | "Major mode to edit DocTeX files." | ||
| 2115 | (setq font-lock-defaults | ||
| 2116 | (cons (append (car font-lock-defaults) '(doctex-font-lock-keywords)) | ||
| 2117 | (mapcar | ||
| 2118 | (lambda (x) | ||
| 2119 | (case (car-safe x) | ||
| 2120 | (font-lock-syntactic-keywords | ||
| 2121 | (cons (car x) 'doctex-font-lock-syntactic-keywords)) | ||
| 2122 | (font-lock-syntactic-face-function | ||
| 2123 | (cons (car x) 'doctex-font-lock-syntactic-face-function)) | ||
| 2124 | (t x))) | ||
| 2125 | (cdr font-lock-defaults))))) | ||
| 2061 | 2126 | ||
| 2062 | (run-hooks 'tex-mode-load-hook) | 2127 | (run-hooks 'tex-mode-load-hook) |
| 2063 | 2128 | ||