1 |
;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands |
;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands -*- coding: utf-8 -*- |
2 |
|
|
3 |
;; Copyright (C) 1985, 86, 89, 92, 94, 95, 96, 97, 98, 1999, 2002 |
;; Copyright (C) 1985, 86, 89, 92, 94, 95, 96, 97, 98, 1999, 2002 |
4 |
;; Free Software Foundation, Inc. |
;; Free Software Foundation, Inc. |
120 |
:group 'tex-run) |
:group 'tex-run) |
121 |
|
|
122 |
;;;###autoload |
;;;###autoload |
123 |
(defcustom tex-start-options nil |
(defcustom tex-start-options "" |
124 |
"*TeX options to use when starting TeX. |
"*TeX options to use when starting TeX. |
125 |
These precede the commands in `tex-start-options' |
These immediately precede the commands in `tex-start-commands' |
126 |
and the input file name. If nil, TeX runs with no options. |
and the input file name, with no separating space and are not shell-quoted. |
127 |
See the documentation of `tex-command'." |
If nil, TeX runs with no options. See the documentation of `tex-command'." |
128 |
:type '(radio (const :tag "Interactive \(nil\)" nil) |
:type 'string |
|
(const :tag "Nonstop \(\"\\nonstopmode\\input\"\)" |
|
|
"\\nonstopmode\\input") |
|
|
(string :tag "String at your choice")) |
|
129 |
:group 'tex-run |
:group 'tex-run |
130 |
:version "21.4") |
:version "21.4") |
131 |
|
|
132 |
;;;###autoload |
;;;###autoload |
133 |
(defcustom tex-start-commands "\\nonstopmode\\input" |
(defcustom tex-start-commands "\\nonstopmode\\input" |
134 |
"*TeX commands to use when starting TeX. |
"*TeX commands to use when starting TeX. |
135 |
These precede the input file name. If nil, no commands are used. |
They are shell-quoted and precede the input file name, with a separating space. |
136 |
See the documentation of `tex-command'." |
If nil, no commands are used. See the documentation of `tex-command'." |
137 |
:type '(radio (const :tag "Interactive \(nil\)" nil) |
:type '(radio (const :tag "Interactive \(nil\)" nil) |
138 |
(const :tag "Nonstop \(\"\\nonstopmode\\input\"\)" |
(const :tag "Nonstop \(\"\\nonstopmode\\input\"\)" |
139 |
"\\nonstopmode\\input") |
"\\nonstopmode\\input") |
141 |
:group 'tex-run |
:group 'tex-run |
142 |
:version "21.4") |
:version "21.4") |
143 |
|
|
144 |
(defvar standard-latex-block-names |
(defvar latex-standard-block-names |
145 |
'("abstract" "array" "center" "description" |
'("abstract" "array" "center" "description" |
146 |
"displaymath" "document" "enumerate" "eqnarray" |
"displaymath" "document" "enumerate" "eqnarray" |
147 |
"eqnarray*" "equation" "figure" "figure*" |
"eqnarray*" "equation" "figure" "figure*" |
156 |
;;;###autoload |
;;;###autoload |
157 |
(defcustom latex-block-names nil |
(defcustom latex-block-names nil |
158 |
"*User defined LaTeX block names. |
"*User defined LaTeX block names. |
159 |
Combined with `standard-latex-block-names' for minibuffer completion." |
Combined with `latex-standard-block-names' for minibuffer completion." |
160 |
:type '(repeat string) |
:type '(repeat string) |
161 |
:group 'tex-run) |
:group 'tex-run) |
162 |
|
|
196 |
:group 'tex-view) |
:group 'tex-view) |
197 |
|
|
198 |
;;;###autoload |
;;;###autoload |
199 |
(defcustom tex-dvi-view-command nil |
(defcustom tex-dvi-view-command '(if (eq window-system 'x) \"xdvi\" \"dvi2tty * | cat -s\") |
200 |
"*Command used by \\[tex-view] to display a `.dvi' file. |
"*Command used by \\[tex-view] to display a `.dvi' file. |
201 |
|
If it is a string, that specifies the command directly. |
202 |
If this string contains an asterisk (`*'), that is replaced by the file name; |
If this string contains an asterisk (`*'), that is replaced by the file name; |
203 |
otherwise, the file name, preceded by blank, is added at the end. |
otherwise, the file name, preceded by a space, is added at the end. |
204 |
|
|
205 |
This can be set conditionally so that the previewer used is suitable for the |
If the value is a form, it is evaluated to get the command to use." |
206 |
window system being used. For example, |
:type '(choice (const nil) string sexp) |
|
|
|
|
(setq tex-dvi-view-command |
|
|
(if (eq window-system 'x) \"xdvi\" \"dvi2tty * | cat -s\")) |
|
|
|
|
|
would tell \\[tex-view] to use xdvi under X windows and to use dvi2tty |
|
|
otherwise." |
|
|
:type '(choice (const nil) string) |
|
207 |
:group 'tex-view) |
:group 'tex-view) |
208 |
|
|
209 |
;;;###autoload |
;;;###autoload |
226 |
(defcustom tex-open-quote "``" |
(defcustom tex-open-quote "``" |
227 |
"*String inserted by typing \\[tex-insert-quote] to open a quotation." |
"*String inserted by typing \\[tex-insert-quote] to open a quotation." |
228 |
:type 'string |
:type 'string |
229 |
|
:options '("``" "\"<" "\"`" "<<" "«") |
230 |
:group 'tex) |
:group 'tex) |
231 |
|
|
232 |
;;;###autoload |
;;;###autoload |
233 |
(defcustom tex-close-quote "''" |
(defcustom tex-close-quote "''" |
234 |
"*String inserted by typing \\[tex-insert-quote] to close a quotation." |
"*String inserted by typing \\[tex-insert-quote] to close a quotation." |
235 |
:type 'string |
:type 'string |
236 |
|
:options '("''" "\">" "\"'" ">>" "»") |
237 |
:group 'tex) |
:group 'tex) |
238 |
|
|
239 |
(defvar tex-last-temp-file nil |
(defvar tex-last-temp-file nil |
241 |
Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the |
Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the |
242 |
tex shell terminates.") |
tex shell terminates.") |
243 |
|
|
244 |
(defvar tex-command nil |
(defvar tex-command "tex" |
245 |
"*Command to run TeX. |
"*Command to run TeX. |
246 |
If this string contains an asterisk \(`*'\), that is replaced by the file name\; |
If this string contains an asterisk \(`*'\), that is replaced by the file name; |
247 |
otherwise the value of `tex-start-options', the \(shell-quoted\) |
otherwise the value of `tex-start-options', the \(shell-quoted\) |
248 |
value of `tex-start-commands', and the file name are added at the end |
value of `tex-start-commands', and the file name are added at the end |
249 |
with blanks as separators. |
with blanks as separators. |
437 |
'("title" "begin" "end" "chapter" "part" |
'("title" "begin" "end" "chapter" "part" |
438 |
"section" "subsection" "subsubsection" |
"section" "subsection" "subsubsection" |
439 |
"paragraph" "subparagraph" "subsubparagraph" |
"paragraph" "subparagraph" "subsubparagraph" |
440 |
"newcommand" "renewcommand" "newenvironment" |
"newcommand" "renewcommand" "providecommand" |
441 |
"newtheorem") |
"newenvironment" "renewenvironment" |
442 |
|
"newtheorem" "renewtheorem") |
443 |
t)) |
t)) |
444 |
(variables (regexp-opt |
(variables (regexp-opt |
445 |
'("newcounter" "newcounter*" "setcounter" "addtocounter" |
'("newcounter" "newcounter*" "setcounter" "addtocounter" |
459 |
;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)")) |
;; (arg "\\(?:{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)\\|\\\\[a-z*]+\\)")) |
460 |
(arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
(arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
461 |
(list |
(list |
462 |
|
;; display $$ math $$ |
463 |
|
;; We only mark the match between $$ and $$ because the $$ delimiters |
464 |
|
;; themselves have already been marked (along with $..$) by syntactic |
465 |
|
;; fontification. Also this is done at the very beginning so as to |
466 |
|
;; interact with the other keywords in the same way as $...$ does. |
467 |
|
(list "\\$\\$\\([^$]+\\)\\$\\$" 1 'tex-math-face) |
468 |
;; Heading args. |
;; Heading args. |
469 |
(list (concat slash headings "\\*?" opt arg) |
(list (concat slash headings "\\*?" opt arg) |
470 |
;; If ARG ends up matching too much (if the {} don't match, f.ex) |
;; If ARG ends up matching too much (if the {} don't match, f.ex) |
480 |
;; as improves the behavior in the very rare case where you do |
;; as improves the behavior in the very rare case where you do |
481 |
;; have a comment in ARG. |
;; have a comment in ARG. |
482 |
3 'font-lock-function-name-face 'keep) |
3 'font-lock-function-name-face 'keep) |
483 |
(list (concat slash "\\(re\\)?newcommand\\** *\\(\\\\[A-Za-z@]+\\)") |
(list (concat slash "\\(?:provide\\|\\(?:re\\)?new\\)command\\** *\\(\\\\[A-Za-z@]+\\)") |
484 |
2 'font-lock-function-name-face 'keep) |
1 'font-lock-function-name-face 'keep) |
485 |
;; Variable args. |
;; Variable args. |
486 |
(list (concat slash variables " *" arg) 2 'font-lock-variable-name-face) |
(list (concat slash variables " *" arg) 2 'font-lock-variable-name-face) |
487 |
;; Include args. |
;; Include args. |
522 |
;; Miscellany. |
;; Miscellany. |
523 |
(slash "\\\\") |
(slash "\\\\") |
524 |
(opt " *\\(\\[[^]]*\\] *\\)*") |
(opt " *\\(\\[[^]]*\\] *\\)*") |
525 |
|
(args "\\(\\(?:[^{}&\\]+\\|\\\\.\\|{[^}]*}\\)+\\)") |
526 |
(arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
(arg "{\\(\\(?:[^{}\\]+\\|\\\\.\\|{[^}]*}\\)+\\)")) |
527 |
(list |
(list |
528 |
;; |
;; |
530 |
(list (concat slash citations opt arg) 3 'font-lock-constant-face) |
(list (concat slash citations opt arg) 3 'font-lock-constant-face) |
531 |
;; |
;; |
532 |
;; Text between `` quotes ''. |
;; Text between `` quotes ''. |
533 |
(cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "") t) |
(cons (concat (regexp-opt `("``" "\"<" "\"`" "<<" "«") t) |
534 |
"[^'\">]+" ;a bit pessimistic |
"[^'\">{]+" ;a bit pessimistic |
535 |
(regexp-opt `("''" "\">" "\"'" ">>" "") t)) |
(regexp-opt `("''" "\">" "\"'" ">>" "»") t)) |
536 |
'font-lock-string-face) |
'font-lock-string-face) |
537 |
;; |
;; |
538 |
;; Command names, special and general. |
;; Command names, special and general. |
548 |
;; (list (concat slash type arg) 2 '(quote bold-italic) 'append) |
;; (list (concat slash type arg) 2 '(quote bold-italic) 'append) |
549 |
;; |
;; |
550 |
;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. |
;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for tables. |
551 |
(list (concat "\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>" |
(list (concat "\\\\\\(em\\|it\\|sl\\)\\>" args) |
552 |
"\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)") |
2 '(quote italic) 'append) |
553 |
3 '(if (match-beginning 2) 'bold 'italic) 'append))))) |
;; This is separate from the previous one because of cases like |
554 |
|
;; {\em foo {\bf bar} bla} where both match. |
555 |
|
(list (concat "\\\\bf\\>" args) 1 '(quote bold) 'append))))) |
556 |
"Gaudy expressions to highlight in TeX modes.") |
"Gaudy expressions to highlight in TeX modes.") |
557 |
|
|
558 |
|
(defun tex-font-lock-suscript (pos) |
559 |
|
(unless (or (memq (get-text-property pos 'face) |
560 |
|
'(font-lock-constant-face font-lock-builtin-face |
561 |
|
font-lock-comment-face tex-verbatim-face)) |
562 |
|
;; Check for backslash quoting |
563 |
|
(let ((odd nil) |
564 |
|
(pos pos)) |
565 |
|
(while (eq (char-before pos) ?\\) |
566 |
|
(setq pos (1- pos) odd (not odd))) |
567 |
|
odd)) |
568 |
|
(if (eq (char-after pos) ?_) |
569 |
|
'(face subscript display (raise -0.3)) |
570 |
|
'(face superscript display (raise +0.3))))) |
571 |
|
|
572 |
|
(defconst tex-font-lock-keywords-3 |
573 |
|
(append tex-font-lock-keywords-2 |
574 |
|
(eval-when-compile |
575 |
|
(let ((general "\\([a-zA-Z@]+\\|[^ \t\n]\\)") |
576 |
|
(slash "\\\\") |
577 |
|
;; This is not the same regexp as before: it has a `+' removed. |
578 |
|
;; The + makes the matching faster in the above cases (where we can |
579 |
|
;; exit as soon as the match fails) but would make this matching |
580 |
|
;; degenerate to nasty complexity (because we try to match the |
581 |
|
;; closing brace, which forces trying all matching combinations). |
582 |
|
(arg "{\\(?:[^{}\\]\\|\\\\.\\|{[^}]*}\\)*")) |
583 |
|
`((,(concat "[_^] *\\([^\n\\{}]\\|" slash general "\\|" arg "}\\)") |
584 |
|
(1 (tex-font-lock-suscript (match-beginning 0)) |
585 |
|
append)))))) |
586 |
|
"Experimental expressions to highlight in TeX modes.") |
587 |
|
|
588 |
(defvar tex-font-lock-keywords tex-font-lock-keywords-1 |
(defvar tex-font-lock-keywords tex-font-lock-keywords-1 |
589 |
"Default expressions to highlight in TeX modes.") |
"Default expressions to highlight in TeX modes.") |
590 |
|
|
591 |
|
(defvar tex-verbatim-environments |
592 |
|
'("verbatim" "verbatim*")) |
593 |
|
|
594 |
|
(defvar tex-font-lock-syntactic-keywords |
595 |
|
(let ((verbs (regexp-opt tex-verbatim-environments t))) |
596 |
|
`((,(concat "^\\\\begin *{" verbs "}.*\\(\n\\)") 2 "|") |
597 |
|
(,(concat "^\\\\end *{" verbs "}\\(.?\\)") 2 |
598 |
|
(unless (<= (match-beginning 0) (point-min)) |
599 |
|
(put-text-property (1- (match-beginning 0)) (match-beginning 0) |
600 |
|
'syntax-table (string-to-syntax "|")) |
601 |
|
"<")) |
602 |
|
;; ("^\\(\\\\\\)begin *{comment}" 1 "< b") |
603 |
|
;; ("^\\\\end *{comment}.*\\(\n\\)" 1 "> b") |
604 |
|
("\\\\verb\\**\\([^a-z@*]\\)" 1 "\"")))) |
605 |
|
|
606 |
|
(defun tex-font-lock-unfontify-region (beg end) |
607 |
|
(font-lock-default-unfontify-region beg end) |
608 |
|
(while (< beg end) |
609 |
|
(let ((next (next-single-property-change beg 'display nil end)) |
610 |
|
(prop (get-text-property beg 'display))) |
611 |
|
(if (and (eq (car-safe prop) 'raise) |
612 |
|
(member (car-safe (cdr prop)) '(-0.3 +0.3)) |
613 |
|
(null (cddr prop))) |
614 |
|
(put-text-property beg next 'display nil)) |
615 |
|
(setq beg next)))) |
616 |
|
|
617 |
|
(defface superscript |
618 |
|
'((t :height 0.8)) ;; :raise 0.3 |
619 |
|
"Face used for superscripts.") |
620 |
|
(defface subscript |
621 |
|
'((t :height 0.8)) ;; :raise -0.3 |
622 |
|
"Face used for subscripts.") |
623 |
|
|
624 |
(defface tex-math-face |
(defface tex-math-face |
625 |
'((t :inherit font-lock-string-face)) |
'((t :inherit font-lock-string-face)) |
626 |
"Face used to highlight TeX math expressions.") |
"Face used to highlight TeX math expressions.") |
627 |
(defvar tex-math-face 'tex-math-face) |
(defvar tex-math-face 'tex-math-face) |
628 |
|
(defface tex-verbatim-face |
629 |
|
;; '((t :inherit font-lock-string-face)) |
630 |
|
'((t :family "courier")) |
631 |
|
"Face used to highlight TeX verbatim environments.") |
632 |
|
(defvar tex-verbatim-face 'tex-verbatim-face) |
633 |
|
|
634 |
;; Use string syntax but math face for $...$. |
;; Use string syntax but math face for $...$. |
635 |
(defun tex-font-lock-syntactic-face-function (state) |
(defun tex-font-lock-syntactic-face-function (state) |
636 |
(if (nth 3 state) tex-math-face font-lock-comment-face)) |
(let ((char (nth 3 state))) |
637 |
|
(cond |
638 |
|
((not char) font-lock-comment-face) |
639 |
|
((eq char ?$) tex-math-face) |
640 |
|
(t |
641 |
|
(when (char-valid-p char) |
642 |
|
;; This is a \verb?...? construct. Let's find the end and mark it. |
643 |
|
(save-excursion |
644 |
|
(skip-chars-forward (string ?^ char)) ;; Use `end' ? |
645 |
|
(when (eq (char-syntax (preceding-char)) ?/) |
646 |
|
(put-text-property (1- (point)) (point) 'syntax-table '(1))) |
647 |
|
(unless (eobp) |
648 |
|
(put-text-property (point) (1+ (point)) 'syntax-table '(7))))) |
649 |
|
tex-verbatim-face)))) |
650 |
|
|
651 |
|
|
652 |
(defun tex-define-common-keys (keymap) |
(defun tex-define-common-keys (keymap) |
684 |
(define-key map "[" 'skeleton-pair-insert-maybe) |
(define-key map "[" 'skeleton-pair-insert-maybe) |
685 |
(define-key map "$" 'skeleton-pair-insert-maybe) |
(define-key map "$" 'skeleton-pair-insert-maybe) |
686 |
(define-key map "\n" 'tex-terminate-paragraph) |
(define-key map "\n" 'tex-terminate-paragraph) |
|
(define-key map "\t" 'indent-for-tab-command) |
|
687 |
(define-key map "\M-\r" 'latex-insert-item) |
(define-key map "\M-\r" 'latex-insert-item) |
688 |
(define-key map "\C-c}" 'up-list) |
(define-key map "\C-c}" 'up-list) |
689 |
(define-key map "\C-c{" 'tex-insert-braces) |
(define-key map "\C-c{" 'tex-insert-braces) |
691 |
(define-key map "\C-c\C-b" 'tex-buffer) |
(define-key map "\C-c\C-b" 'tex-buffer) |
692 |
(define-key map "\C-c\C-f" 'tex-file) |
(define-key map "\C-c\C-f" 'tex-file) |
693 |
(define-key map "\C-c\C-i" 'tex-bibtex-file) |
(define-key map "\C-c\C-i" 'tex-bibtex-file) |
694 |
(define-key map "\C-c\C-o" 'tex-latex-block) |
(define-key map "\C-c\C-o" 'latex-insert-block) |
695 |
(define-key map "\C-c\C-e" 'tex-close-latex-block) |
(define-key map "\C-c\C-e" 'latex-close-block) |
696 |
(define-key map "\C-c\C-u" 'tex-goto-last-unclosed-latex-block) |
(define-key map "\C-c\C-u" 'tex-goto-last-unclosed-latex-block) |
697 |
(define-key map "\C-c\C-m" 'tex-feed-input) |
(define-key map "\C-c\C-m" 'tex-feed-input) |
698 |
(define-key map [(control return)] 'tex-feed-input) |
(define-key map [(control return)] 'tex-feed-input) |
768 |
(eval-when-compile |
(eval-when-compile |
769 |
(concat |
(concat |
770 |
(regexp-opt '("documentstyle" "documentclass" |
(regexp-opt '("documentstyle" "documentclass" |
771 |
"begin" "section" "part" "chapter") 'words) |
"begin" "subsection" "section" |
772 |
|
"part" "chapter" "newcommand") 'words) |
773 |
"\\|NeedsTeXFormat{LaTeX"))) |
"\\|NeedsTeXFormat{LaTeX"))) |
774 |
(if (looking-at |
(if (looking-at |
775 |
"document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}") |
"document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}") |
907 |
(set (make-local-variable 'imenu-create-index-function) |
(set (make-local-variable 'imenu-create-index-function) |
908 |
'latex-imenu-create-index) |
'latex-imenu-create-index) |
909 |
(set (make-local-variable 'tex-face-alist) tex-latex-face-alist) |
(set (make-local-variable 'tex-face-alist) tex-latex-face-alist) |
910 |
(set (make-local-variable 'fill-nobreak-predicate) |
(add-hook 'fill-nobreak-predicate 'latex-fill-nobreak-predicate nil t) |
|
'latex-fill-nobreak-predicate) |
|
911 |
(set (make-local-variable 'indent-line-function) 'latex-indent) |
(set (make-local-variable 'indent-line-function) 'latex-indent) |
912 |
(set (make-local-variable 'fill-indent-according-to-mode) t) |
(set (make-local-variable 'fill-indent-according-to-mode) t) |
913 |
(set (make-local-variable 'outline-regexp) latex-outline-regexp) |
(set (make-local-variable 'outline-regexp) latex-outline-regexp) |
975 |
(set (make-local-variable 'comment-start) "%") |
(set (make-local-variable 'comment-start) "%") |
976 |
(set (make-local-variable 'comment-add) 1) |
(set (make-local-variable 'comment-add) 1) |
977 |
(set (make-local-variable 'comment-start-skip) |
(set (make-local-variable 'comment-start-skip) |
978 |
"\\(\\(^\\|[^\\]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") |
"\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)") |
979 |
(set (make-local-variable 'parse-sexp-ignore-comments) t) |
(set (make-local-variable 'parse-sexp-ignore-comments) t) |
980 |
(set (make-local-variable 'compare-windows-whitespace) |
(set (make-local-variable 'compare-windows-whitespace) |
981 |
'tex-categorize-whitespace) |
'tex-categorize-whitespace) |
988 |
(set (make-local-variable 'facemenu-end-add-face) "}") |
(set (make-local-variable 'facemenu-end-add-face) "}") |
989 |
(set (make-local-variable 'facemenu-remove-face-function) t) |
(set (make-local-variable 'facemenu-remove-face-function) t) |
990 |
(set (make-local-variable 'font-lock-defaults) |
(set (make-local-variable 'font-lock-defaults) |
991 |
'((tex-font-lock-keywords |
'((tex-font-lock-keywords tex-font-lock-keywords-1 |
992 |
tex-font-lock-keywords-1 tex-font-lock-keywords-2) |
tex-font-lock-keywords-2 tex-font-lock-keywords-3) |
993 |
nil nil ((?$ . "\"")) nil |
nil nil ((?$ . "\"")) nil |
994 |
;; Who ever uses that anyway ??? |
;; Who ever uses that anyway ??? |
995 |
(font-lock-mark-block-function . mark-paragraph) |
(font-lock-mark-block-function . mark-paragraph) |
996 |
(font-lock-syntactic-face-function |
(font-lock-syntactic-face-function |
997 |
. tex-font-lock-syntactic-face-function))) |
. tex-font-lock-syntactic-face-function) |
998 |
|
(font-lock-unfontify-region-function |
999 |
|
. tex-font-lock-unfontify-region) |
1000 |
|
(font-lock-syntactic-keywords |
1001 |
|
. tex-font-lock-syntactic-keywords) |
1002 |
|
(parse-sexp-lookup-properties . t))) |
1003 |
|
;; TABs in verbatim environments don't do what you think. |
1004 |
|
(set (make-local-variable 'indent-tabs-mode) nil) |
1005 |
|
;; Other vars that should be buffer-local. |
1006 |
(make-local-variable 'tex-command) |
(make-local-variable 'tex-command) |
1007 |
(make-local-variable 'tex-start-of-header) |
(make-local-variable 'tex-start-of-header) |
1008 |
(make-local-variable 'tex-end-of-header) |
(make-local-variable 'tex-end-of-header) |
1044 |
\(normally '') depending on the context. With prefix argument, always |
\(normally '') depending on the context. With prefix argument, always |
1045 |
inserts \" characters." |
inserts \" characters." |
1046 |
(interactive "*P") |
(interactive "*P") |
1047 |
(if arg |
(if (or arg (memq (char-syntax (preceding-char)) '(?/ ?\\)) |
1048 |
|
(eq (get-text-property (point) 'face) 'tex-verbatim-face) |
1049 |
|
(save-excursion |
1050 |
|
(backward-char (length tex-open-quote)) |
1051 |
|
(when (or (looking-at (regexp-quote tex-open-quote)) |
1052 |
|
(looking-at (regexp-quote tex-close-quote))) |
1053 |
|
(delete-char (length tex-open-quote)) |
1054 |
|
t))) |
1055 |
(self-insert-command (prefix-numeric-value arg)) |
(self-insert-command (prefix-numeric-value arg)) |
1056 |
(insert |
(insert (if (memq (char-syntax (preceding-char)) '(?\( ?> ?\ )) |
1057 |
(cond ((= (preceding-char) ?\\) ?\") |
tex-open-quote tex-close-quote)))) |
|
((memq (char-syntax (preceding-char)) '(?\( ?> ?\ )) tex-open-quote) |
|
|
(t tex-close-quote))))) |
|
1058 |
|
|
1059 |
(defun tex-validate-buffer () |
(defun tex-validate-buffer () |
1060 |
"Check current buffer for paragraphs containing mismatched braces or $s. |
"Check current buffer for paragraphs containing mismatched braces or $s. |
1171 |
(message "Paragraph being closed appears to contain a mismatch")) |
(message "Paragraph being closed appears to contain a mismatch")) |
1172 |
(insert "\n\n")) |
(insert "\n\n")) |
1173 |
|
|
1174 |
(defun tex-insert-braces () |
(define-skeleton tex-insert-braces |
1175 |
"Make a pair of braces and be poised to type inside of them." |
"Make a pair of braces and be poised to type inside of them." |
1176 |
(interactive "*") |
nil |
1177 |
(insert ?\{) |
?\{ _ ?}) |
|
(save-excursion |
|
|
(insert ?}))) |
|
1178 |
|
|
1179 |
;; This function is used as the value of fill-nobreak-predicate |
;; This function is used as the value of fill-nobreak-predicate |
1180 |
;; in LaTeX mode. Its job is to prevent line-breaking inside |
;; in LaTeX mode. Its job is to prevent line-breaking inside |
1181 |
;; of a \verb construct. |
;; of a \verb construct. |
1182 |
(defun latex-fill-nobreak-predicate () |
(defun latex-fill-nobreak-predicate () |
1183 |
(let ((opoint (point)) |
(save-excursion |
1184 |
inside) |
(skip-chars-backward " ") |
1185 |
(save-excursion |
;; Don't break after \ since `\ ' has special meaning. |
1186 |
(save-restriction |
(or (and (not (bobp)) (memq (char-syntax (char-before)) '(?\\ ?/))) |
1187 |
(beginning-of-line) |
(let ((opoint (point)) |
1188 |
(narrow-to-region (point) opoint) |
inside) |
1189 |
(while (re-search-forward "\\\\verb\\(.\\)" nil t) |
(beginning-of-line) |
1190 |
(unless (re-search-forward (regexp-quote (match-string 1)) nil t) |
(while (re-search-forward "\\\\verb\\(.\\)" opoint t) |
1191 |
(setq inside t))))) |
(unless (re-search-forward (regexp-quote (match-string 1)) opoint t) |
1192 |
inside)) |
(setq inside t))) |
1193 |
|
inside)))) |
1194 |
|
|
1195 |
(defvar latex-block-default "enumerate") |
(defvar latex-block-default "enumerate") |
1196 |
|
|
1197 |
;; Like tex-insert-braces, but for LaTeX. |
;; Like tex-insert-braces, but for LaTeX. |
1198 |
(define-skeleton tex-latex-block |
(defalias 'tex-latex-block 'latex-insert-block) |
1199 |
|
(define-skeleton latex-insert-block |
1200 |
"Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. |
"Create a matching pair of lines \\begin[OPT]{NAME} and \\end{NAME} at point. |
1201 |
Puts point on a blank line between them." |
Puts point on a blank line between them." |
1202 |
(let ((choice (completing-read (format "LaTeX block name [%s]: " |
(let ((choice (completing-read (format "LaTeX block name [%s]: " |
1203 |
latex-block-default) |
latex-block-default) |
1204 |
(mapcar 'list |
(append latex-block-names |
1205 |
(append standard-latex-block-names |
latex-standard-block-names) |
|
latex-block-names)) |
|
1206 |
nil nil nil nil latex-block-default))) |
nil nil nil nil latex-block-default))) |
1207 |
(setq latex-block-default choice) |
(setq latex-block-default choice) |
1208 |
(unless (or (member choice standard-latex-block-names) |
(unless (or (member choice latex-standard-block-names) |
1209 |
(member choice latex-block-names)) |
(member choice latex-block-names)) |
1210 |
;; Remember new block names for later completion. |
;; Remember new block names for later completion. |
1211 |
(push choice latex-block-names)) |
(push choice latex-block-names)) |
1212 |
choice) |
choice) |
1213 |
\n "\\begin{" str ?\} |
\n "\\begin{" str "}" |
1214 |
?\[ (skeleton-read "[options]: ") & ?\] | -1 |
?\[ (skeleton-read "[options]: ") & ?\] | -1 |
1215 |
> \n _ \n |
> \n _ \n |
1216 |
"\\end{" str ?\} > \n) |
"\\end{" str "}" > \n) |
1217 |
|
|
1218 |
(define-skeleton latex-insert-item |
(define-skeleton latex-insert-item |
1219 |
"Insert a \item macro." |
"Insert a \item macro." |
1227 |
|
|
1228 |
(defun tex-last-unended-begin () |
(defun tex-last-unended-begin () |
1229 |
"Leave point at the beginning of the last `\\begin{...}' that is unended." |
"Leave point at the beginning of the last `\\begin{...}' that is unended." |
1230 |
(while (and (re-search-backward "\\\\\\(begin\\|end\\)\\s *{") |
(condition-case nil |
1231 |
(looking-at "\\\\end")) |
(while (and (re-search-backward "\\\\\\(begin\\|end\\)\\s *{") |
1232 |
(tex-last-unended-begin))) |
(looking-at "\\\\end")) |
1233 |
|
(tex-last-unended-begin)) |
1234 |
|
(search-failed (error "Couldn't find unended \\begin")))) |
1235 |
|
|
1236 |
(defun tex-next-unmatched-end () |
(defun tex-next-unmatched-end () |
1237 |
"Leave point at the end of the next `\\end' that is unended." |
"Leave point at the end of the next `\\end' that is unended." |
1246 |
(interactive) |
(interactive) |
1247 |
(let ((spot)) |
(let ((spot)) |
1248 |
(save-excursion |
(save-excursion |
1249 |
(condition-case nil |
(tex-last-unended-begin) |
|
(tex-last-unended-begin) |
|
|
(error (error "Couldn't find unended \\begin"))) |
|
1250 |
(setq spot (point))) |
(setq spot (point))) |
1251 |
(push-mark) |
(push-mark) |
1252 |
(goto-char spot))) |
(goto-char spot))) |
1321 |
(down-list 1) |
(down-list 1) |
1322 |
(forward-sexp 1) |
(forward-sexp 1) |
1323 |
;; Skip arguments. |
;; Skip arguments. |
1324 |
(while (looking-at "[ \t]*\\s(") (forward-sexp))))) |
(while (looking-at "[ \t]*[[{(]") |
1325 |
|
(with-syntax-table tex-mode-syntax-table |
1326 |
|
(forward-sexp)))))) |
1327 |
|
|
1328 |
|
(defalias 'tex-close-latex-block 'latex-close-block) |
1329 |
|
(define-skeleton latex-close-block |
1330 |
|
"Create an \\end{...} to match the last unclosed \\begin{...}." |
1331 |
|
(save-excursion |
1332 |
|
(tex-last-unended-begin) |
1333 |
|
(if (not (looking-at "\\\\begin\\(\\s *{[^}\n]*}\\)")) '("{" _ "}") |
1334 |
|
(match-string 1))) |
1335 |
|
\n "\\end" str > \n) |
1336 |
|
|
1337 |
(defun tex-close-latex-block () |
(define-skeleton latex-split-block |
1338 |
"Creates an \\end{...} to match the last unclosed \\begin{...}." |
"Split the enclosing environment by inserting \\end{..}\\begin{..} at point." |
1339 |
(interactive "*") |
(save-excursion |
1340 |
(let ((new-line-needed (bolp)) |
(tex-last-unended-begin) |
1341 |
text indentation) |
(if (not (looking-at "\\\\begin\\(\\s *{[^}\n]*}\\)")) '("{" _ "}") |
1342 |
(save-excursion |
(prog1 (match-string 1) |
1343 |
(condition-case nil |
(goto-char (match-end 1)) |
1344 |
(tex-last-unended-begin) |
(setq v1 (buffer-substring (point) |
1345 |
(error (error "Couldn't find unended \\begin"))) |
(progn |
1346 |
(setq indentation (current-column)) |
(while (looking-at "[ \t]*[[{]") |
1347 |
(re-search-forward "\\\\begin\\(\\s *{[^}\n]*}\\)") |
(forward-sexp 1)) |
1348 |
(setq text (buffer-substring (match-beginning 1) (match-end 1)))) |
(point))))))) |
1349 |
(indent-to indentation) |
\n "\\end" str > \n _ \n "\\begin" str v1 > \n) |
|
(insert "\\end" text) |
|
|
(if new-line-needed (insert ?\n)))) |
|
1350 |
|
|
1351 |
(defconst tex-discount-args-cmds |
(defconst tex-discount-args-cmds |
1352 |
'("begin" "end" "input" "special" "cite" "ref" "include" "includeonly" |
'("begin" "end" "input" "special" "cite" "ref" "include" "includeonly" |
1531 |
(save-restriction |
(save-restriction |
1532 |
(widen) |
(widen) |
1533 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1534 |
(re-search-forward header-re 10000 t)))) |
(re-search-forward |
1535 |
|
header-re (+ (point) 10000) t)))) |
1536 |
(throw 'found (expand-file-name buffer-file-name)))))))) |
(throw 'found (expand-file-name buffer-file-name)))))))) |
1537 |
|
|
1538 |
(defun tex-main-file () |
(defun tex-main-file () |
1547 |
(file-relative-name |
(file-relative-name |
1548 |
(if (save-excursion |
(if (save-excursion |
1549 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1550 |
(re-search-forward tex-start-of-header 10000 t)) |
(re-search-forward tex-start-of-header |
1551 |
|
(+ (point) 10000) t)) |
1552 |
;; This is the main file. |
;; This is the main file. |
1553 |
buffer-file-name |
buffer-file-name |
1554 |
;; This isn't the main file, let's try to find better, |
;; This isn't the main file, let's try to find better, |
1567 |
(comint-quote-filename file) |
(comint-quote-filename file) |
1568 |
(substring command (1+ star))) |
(substring command (1+ star))) |
1569 |
(concat command " " |
(concat command " " |
1570 |
|
tex-start-options |
1571 |
(if (< 0 (length tex-start-commands)) |
(if (< 0 (length tex-start-commands)) |
1572 |
(concat |
(concat |
1573 |
(shell-quote-argument tex-start-commands) " ")) |
(shell-quote-argument tex-start-commands) " ")) |
|
tex-start-options |
|
1574 |
(comint-quote-filename file))))) |
(comint-quote-filename file))))) |
1575 |
(tex-send-tex-command compile-command dir))) |
(tex-send-tex-command compile-command dir))) |
1576 |
|
|
1783 |
This function is more useful than \\[tex-buffer] when you need the |
This function is more useful than \\[tex-buffer] when you need the |
1784 |
`.aux' file of LaTeX to have the correct name." |
`.aux' file of LaTeX to have the correct name." |
1785 |
(interactive) |
(interactive) |
1786 |
|
(when tex-offer-save |
1787 |
|
(save-some-buffers)) |
1788 |
(let* ((source-file (tex-main-file)) |
(let* ((source-file (tex-main-file)) |
1789 |
(file-dir (file-name-directory (expand-file-name source-file)))) |
(file-dir (file-name-directory (expand-file-name source-file)))) |
|
(if tex-offer-save |
|
|
(save-some-buffers)) |
|
1790 |
(if (tex-shell-running) |
(if (tex-shell-running) |
1791 |
(tex-kill-job) |
(tex-kill-job) |
1792 |
(tex-start-shell)) |
(tex-start-shell)) |
1878 |
(tex-start-shell)) |
(tex-start-shell)) |
1879 |
(tex-send-command |
(tex-send-command |
1880 |
(if alt tex-alt-dvi-print-command tex-dvi-print-command) |
(if alt tex-alt-dvi-print-command tex-dvi-print-command) |
1881 |
print-file-name-dvi t)))) |
(shell-quote-argument |
1882 |
|
print-file-name-dvi) |
1883 |
|
t)))) |
1884 |
|
|
1885 |
(defun tex-alt-print () |
(defun tex-alt-print () |
1886 |
"Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file]. |
"Print the .dvi file made by \\[tex-region], \\[tex-buffer] or \\[tex-file]. |
1897 |
(interactive) |
(interactive) |
1898 |
(or tex-dvi-view-command |
(or tex-dvi-view-command |
1899 |
(error "You must set `tex-dvi-view-command'")) |
(error "You must set `tex-dvi-view-command'")) |
1900 |
(let ((tex-dvi-print-command tex-dvi-view-command)) |
(let ((tex-dvi-print-command (eval tex-dvi-view-command))) |
1901 |
(tex-print))) |
(tex-print))) |
1902 |
|
|
1903 |
(defun tex-append (file-name suffix) |
(defun tex-append (file-name suffix) |
1969 |
:copy tex-mode-syntax-table) |
:copy tex-mode-syntax-table) |
1970 |
|
|
1971 |
(defun latex-indent (&optional arg) |
(defun latex-indent (&optional arg) |
1972 |
(with-syntax-table tex-latex-indent-syntax-table |
(if (and (eq (get-text-property (line-beginning-position) 'face) |
1973 |
;; TODO: Rather than ignore $, we should try to be more clever about it. |
tex-verbatim-face)) |
1974 |
(let ((indent |
(indent-relative) |
1975 |
(save-excursion |
(with-syntax-table tex-latex-indent-syntax-table |
1976 |
(beginning-of-line) |
;; TODO: Rather than ignore $, we should try to be more clever about it. |
1977 |
(latex-find-indent)))) |
(let ((indent |
1978 |
(if (< indent 0) (setq indent 0)) |
(save-excursion |
1979 |
(if (<= (current-column) (current-indentation)) |
(beginning-of-line) |
1980 |
(indent-line-to indent) |
(latex-find-indent)))) |
1981 |
(save-excursion (indent-line-to indent)))))) |
(if (< indent 0) (setq indent 0)) |
1982 |
|
(if (<= (current-column) (current-indentation)) |
1983 |
|
(indent-line-to indent) |
1984 |
|
(save-excursion (indent-line-to indent))))))) |
1985 |
|
|
1986 |
(defun latex-find-indent (&optional virtual) |
(defun latex-find-indent (&optional virtual) |
1987 |
"Find the proper indentation of text after point. |
"Find the proper indentation of text after point. |
1991 |
(save-excursion |
(save-excursion |
1992 |
(skip-chars-forward " \t") |
(skip-chars-forward " \t") |
1993 |
(or |
(or |
1994 |
|
;; Stick the first line at column 0. |
1995 |
|
(and (= (point-min) (line-beginning-position)) 0) |
1996 |
;; Trust the current indentation, if such info is applicable. |
;; Trust the current indentation, if such info is applicable. |
1997 |
(and virtual (>= (current-indentation) (current-column)) |
(and virtual (save-excursion (skip-chars-backward " \t&") (bolp)) |
1998 |
(current-indentation)) |
(current-column)) |
1999 |
|
;; Stick verbatim environments to the left margin. |
2000 |
|
(and (looking-at "\\\\\\(begin\\|end\\) *{\\([^\n}]+\\)") |
2001 |
|
(member (match-string 2) tex-verbatim-environments) |
2002 |
|
0) |
2003 |
;; Put leading close-paren where the matching open brace would be. |
;; Put leading close-paren where the matching open brace would be. |
2004 |
(and (eq (latex-syntax-after) ?\)) |
(and (eq (latex-syntax-after) ?\)) |
2005 |
(ignore-errors |
(ignore-errors |
2030 |
(> pos (progn (latex-down-list) |
(> pos (progn (latex-down-list) |
2031 |
(forward-comment (point-max)) |
(forward-comment (point-max)) |
2032 |
(point)))) |
(point)))) |
2033 |
;; Align with the first element after the open-paren. |
;; Align with the first element after the open-paren. |
2034 |
(current-column) |
(current-column) |
2035 |
;; We're the first element after a hanging brace. |
;; We're the first element after a hanging brace. |
2036 |
(goto-char up-list-pos) |
(goto-char up-list-pos) |
2040 |
;; Nothing particular here: just keep the same indentation. |
;; Nothing particular here: just keep the same indentation. |
2041 |
(+ indent (current-column))) |
(+ indent (current-column))) |
2042 |
;; We're now looking at a macro call. |
;; We're now looking at a macro call. |
2043 |
((looking-at tex-indent-item-re) |
((looking-at tex-indent-item-re) |
2044 |
;; Indenting relative to an item, have to re-add the outdenting. |
;; Indenting relative to an item, have to re-add the outdenting. |
2045 |
(+ indent (current-column) tex-indent-item)) |
(+ indent (current-column) tex-indent-item)) |
2046 |
(t |
(t |
2047 |
(let ((col (current-column))) |
(let ((col (current-column))) |
2049 |
;; If the first char was not an open-paren, there's |
;; If the first char was not an open-paren, there's |
2050 |
;; a risk that this is really not an argument to the |
;; a risk that this is really not an argument to the |
2051 |
;; macro at all. |
;; macro at all. |
2052 |
(+ indent col) |
(+ indent col) |
2053 |
(forward-sexp 1) |
(forward-sexp 1) |
2054 |
(if (< (line-end-position) |
(if (< (line-end-position) |
2055 |
(save-excursion (forward-comment (point-max)) |
(save-excursion (forward-comment (point-max)) |
2056 |
(point))) |
(point))) |
2057 |
;; we're indenting the first argument. |
;; we're indenting the first argument. |
2058 |
(min (current-column) (+ tex-indent-arg col)) |
(min (current-column) (+ tex-indent-arg col)) |
2059 |
(skip-syntax-forward " ") |
(skip-syntax-forward " ") |