summaryrefslogtreecommitdiff
path: root/lisp/textmodes/tex-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/textmodes/tex-mode.el')
-rw-r--r--lisp/textmodes/tex-mode.el203
1 files changed, 153 insertions, 50 deletions
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index a42a195b8ec..ffb06061bb6 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -1,7 +1,8 @@
;;; tex-mode.el --- TeX, LaTeX, and SliTeX mode commands -*- coding: utf-8 -*-
-;; Copyright (C) 1985, 1986, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1989, 1992, 1994, 1995, 1996, 1997, 1998
+;; 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;; Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: tex
@@ -243,6 +244,24 @@ Normally set to either `plain-tex-mode' or `latex-mode'."
:options '("''" "\">" "\"'" ">>" "ยป")
:group 'tex)
+(defcustom tex-fontify-script t
+ "If non-nil, fontify subscript and superscript strings."
+ :type 'boolean
+ :group 'tex
+ :version "23.1")
+(put 'tex-fontify-script 'safe-local-variable 'booleanp)
+
+(defcustom tex-font-script-display '(-0.2 0.2)
+ "How much to lower and raise subscript and superscript content.
+This is a list of two floats. The first is negative and
+specifies how much subscript is lowered, the second is positive
+and specifies how much superscript is raised. Heights are
+measured relative to that of the normal text."
+ :group 'tex
+ :type '(list (float :tag "Subscript")
+ (float :tag "Superscript"))
+ :version "23.1")
+
(defvar tex-last-temp-file nil
"Latest temporary file generated by \\[tex-region] and \\[tex-buffer].
Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the
@@ -527,6 +546,8 @@ An alternative value is \" . \", if you use a font with a narrow period."
(citations (regexp-opt
'("label" "ref" "pageref" "vref" "eqref"
"cite" "nocite" "index" "glossary" "bibitem"
+ ;; natbib's two variants of \cite:
+ "citep" "citet"
;; These are text, rather than citations.
;; "caption" "footnote" "footnotemark" "footnotetext"
)
@@ -591,13 +612,14 @@ An alternative value is \" . \", if you use a font with a narrow period."
(setq pos (1- pos) odd (not odd)))
odd))
(if (eq (char-after pos) ?_)
- '(face subscript display (raise -0.3))
- '(face superscript display (raise +0.3)))))
+ `(face subscript display (raise ,(car tex-font-script-display)))
+ `(face superscript display (raise ,(cadr tex-font-script-display))))))
(defun tex-font-lock-match-suscript (limit)
"Match subscript and superscript patterns up to LIMIT."
- (when (re-search-forward "[_^] *\\([^\n\\{}]\\|\
-\\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t)
+ (when (and tex-fontify-script
+ (re-search-forward "[_^] *\\([^\n\\{}]\\|\
+\\\\\\([a-zA-Z@]+\\|[^ \t\n]\\)\\|\\({\\)\\)" limit t))
(when (match-end 3)
(let ((beg (match-beginning 3))
(end (save-restriction
@@ -619,26 +641,31 @@ An alternative value is \" . \", if you use a font with a narrow period."
(defvar tex-verbatim-environments
'("verbatim" "verbatim*"))
+(put 'tex-verbatim-environments 'safe-local-variable
+ (lambda (x) (null (delq t (mapcar 'stringp x)))))
(defvar tex-font-lock-syntactic-keywords
- (let ((verbs (regexp-opt tex-verbatim-environments t)))
- `((,(concat "^\\\\begin *{" verbs "}.*\\(\n\\)") 2 "|")
- ;; Technically, we'd like to put the "|" property on the \n preceding
- ;; the \end, but this would have 2 disadvantages:
- ;; 1 - it's wrong if the verbatim env is empty (the same \n is used to
- ;; start and end the fenced-string).
- ;; 2 - font-lock considers the preceding \n as being part of the
- ;; preceding line, so things gets screwed every time the previous
- ;; line is re-font-locked on its own.
- ;; There's a hack in tex-font-lock-keywords-1 to remove the verbatim
- ;; face from the \ but C-M-f still jumps to the wrong spot :-( --Stef
- (,(concat "^\\(\\\\\\)end *{" verbs "}\\(.?\\)") (1 "|") (3 "<"))
- ;; ("^\\(\\\\\\)begin *{comment}" 1 "< b")
- ;; ("^\\\\end *{comment}.*\\(\n\\)" 1 "> b")
- ("\\\\verb\\**\\([^a-z@*]\\)"
- ;; Do it last, because it uses syntax-ppss which needs the
- ;; syntax-table properties of previous entries.
- 1 (tex-font-lock-verb (match-end 1))))))
+ '((eval . `(,(concat "^\\\\begin *{"
+ (regexp-opt tex-verbatim-environments t)
+ "}.*\\(\n\\)") 2 "|"))
+ ;; Technically, we'd like to put the "|" property on the \n preceding
+ ;; the \end, but this would have 2 disadvantages:
+ ;; 1 - it's wrong if the verbatim env is empty (the same \n is used to
+ ;; start and end the fenced-string).
+ ;; 2 - font-lock considers the preceding \n as being part of the
+ ;; preceding line, so things gets screwed every time the previous
+ ;; line is re-font-locked on its own.
+ ;; There's a hack in tex-font-lock-keywords-1 to remove the verbatim
+ ;; face from the \ but C-M-f still jumps to the wrong spot :-( --Stef
+ (eval . `(,(concat "^\\(\\\\\\)end *{"
+ (regexp-opt tex-verbatim-environments t)
+ "}\\(.?\\)") (1 "|") (3 "<")))
+ ;; ("^\\(\\\\\\)begin *{comment}" 1 "< b")
+ ;; ("^\\\\end *{comment}.*\\(\n\\)" 1 "> b")
+ ("\\\\verb\\**\\([^a-z@*]\\)"
+ ;; Do it last, because it uses syntax-ppss which needs the
+ ;; syntax-table properties of previous entries.
+ 1 (tex-font-lock-verb (match-end 1)))))
(defun tex-font-lock-unfontify-region (beg end)
(font-lock-default-unfontify-region beg end)
@@ -646,17 +673,47 @@ An alternative value is \" . \", if you use a font with a narrow period."
(let ((next (next-single-property-change beg 'display nil end))
(prop (get-text-property beg 'display)))
(if (and (eq (car-safe prop) 'raise)
- (member (car-safe (cdr prop)) '(-0.3 +0.3))
+ (member (car-safe (cdr prop)) tex-font-script-display)
(null (cddr prop)))
(put-text-property beg next 'display nil))
(setq beg next))))
+(defcustom tex-suscript-height-ratio 0.8
+ "Ratio of subscript/superscript height to that of the preceding text.
+In nested subscript/superscript, this factor is applied repeatedly,
+subject to the limit set by `tex-suscript-height-minimum'."
+ :type 'float
+ :group 'tex
+ :version "23.1")
+
+(defcustom tex-suscript-height-minimum 0.0
+ "Integer or float limiting the minimum size of subscript/superscript text.
+An integer is an absolute height in units of 1/10 point, a float
+is a height relative to that of the default font. Zero means no minimum."
+ :type '(choice (integer :tag "Integer height in 1/10 point units")
+ (float :tag "Fraction of default font height"))
+ :group 'tex
+ :version "23.1")
+
+(defun tex-suscript-height (height)
+ "Return the integer height of subscript/superscript font in 1/10 points.
+Not smaller than the value set by `tex-suscript-height-minimum'."
+ (ceiling (max (if (integerp tex-suscript-height-minimum)
+ tex-suscript-height-minimum
+ ;; For bootstrapping.
+ (condition-case nil
+ (* tex-suscript-height-minimum
+ (face-attribute 'default :height))
+ (error 0)))
+ ;; NB assumes height is integer.
+ (* height tex-suscript-height-ratio))))
+
(defface superscript
- '((t :height 0.8)) ;; :raise 0.3
+ '((t :height tex-suscript-height)) ;; :raise 0.2
"Face used for superscripts."
:group 'tex)
(defface subscript
- '((t :height 0.8)) ;; :raise -0.3
+ '((t :height tex-suscript-height)) ;; :raise -0.2
"Face used for subscripts."
:group 'tex)
@@ -1169,14 +1226,14 @@ on the line for the invalidity you want to see."
(backward-paragraph)
(forward-paragraph)
(while (not (bobp))
- ;; Scan the previous paragraph for invalidities.
+ ;; Scan the previous paragraph for invalidities.
(backward-paragraph)
(save-excursion
(or (tex-validate-region (point) (save-excursion
(forward-paragraph)
(point)))
(let ((end (line-beginning-position 2))
- start tem)
+ start tem)
(beginning-of-line)
(setq start (point))
;; Keep track of line number as we scan,
@@ -1240,6 +1297,7 @@ area if a mismatch is found."
(save-excursion
(let ((pos (match-beginning 0)))
(goto-char pos)
+ (skip-chars-backward "\\\\") ; escaped parens
(forward-sexp 1)
(or (eq (preceding-char) (cdr (syntax-after pos)))
(eq (char-after pos) (cdr (syntax-after (1- (point)))))
@@ -1378,6 +1436,34 @@ Return the value returned by the last execution of BODY."
(looking-at "\\\\begin")))
(tex-next-unmatched-end)))
+(defun tex-next-unmatched-eparen (otype)
+ "Leave point after the next unmatched escaped closing parenthesis.
+The string OTYPE is an opening parenthesis type: `(', `{', or `['."
+ (condition-case nil
+ (let ((ctype (char-to-string (cdr (aref (syntax-table)
+ (string-to-char otype))))))
+ (while (and (tex-search-noncomment
+ (re-search-forward (format "\\\\[%s%s]" ctype otype)))
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (looking-at (format "\\\\%s" (regexp-quote otype)))))
+ (tex-next-unmatched-eparen otype)))
+ (wrong-type-argument (error "Unknown opening parenthesis type: %s" otype))
+ (search-failed (error "Couldn't find closing escaped paren"))))
+
+(defun tex-last-unended-eparen (ctype)
+ "Leave point at the start of the last unended escaped opening parenthesis.
+The string CTYPE is a closing parenthesis type: `)', `}', or `]'."
+ (condition-case nil
+ (let ((otype (char-to-string (cdr (aref (syntax-table)
+ (string-to-char ctype))))))
+ (while (and (tex-search-noncomment
+ (re-search-backward (format "\\\\[%s%s]" ctype otype)))
+ (looking-at (format "\\\\%s" (regexp-quote ctype))))
+ (tex-last-unended-eparen ctype)))
+ (wrong-type-argument (error "Unknown opening parenthesis type: %s" ctype))
+ (search-failed (error "Couldn't find unended escaped paren"))))
+
(defun tex-goto-last-unclosed-latex-block ()
"Move point to the last unclosed \\begin{...}.
Mark is left at original location."
@@ -1389,26 +1475,34 @@ Mark is left at original location."
(push-mark)
(goto-char spot)))
+;; Don't think this one actually _needs_ (for the purposes of
+;; tex-mode) to handle escaped parens.
(defun latex-backward-sexp-1 ()
- "Like (backward-sexp 1) but aware of multi-char elements."
+ "Like (backward-sexp 1) but aware of multi-char elements and escaped parens."
(let ((pos (point))
(forward-sexp-function))
(backward-sexp 1)
- (if (looking-at "\\\\begin\\>")
- (signal 'scan-error
- (list "Containing expression ends prematurely"
- (point) (prog1 (point) (goto-char pos))))
- (when (eq (char-after) ?{)
- (let ((newpos (point)))
- (when (ignore-errors (backward-sexp 1) t)
- (if (or (looking-at "\\\\end\\>")
- ;; In case the \\ ends a verbatim section.
- (and (looking-at "end\\>") (eq (char-before) ?\\)))
- (tex-last-unended-begin)
- (goto-char newpos))))))))
-
+ (cond ((looking-at "\\\\\\(begin\\>\\|[[({]\\)")
+ (signal 'scan-error
+ (list "Containing expression ends prematurely"
+ (point) (prog1 (point) (goto-char pos)))))
+ ((looking-at "\\\\\\([])}]\\)")
+ (tex-last-unended-eparen (match-string 1)))
+ ((eq (char-after) ?{)
+ (let ((newpos (point)))
+ (when (ignore-errors (backward-sexp 1) t)
+ (if (or (looking-at "\\\\end\\>")
+ ;; In case the \\ ends a verbatim section.
+ (and (looking-at "end\\>") (eq (char-before) ?\\)))
+ (tex-last-unended-begin)
+ (goto-char newpos))))))))
+
+;; Note this does not handle things like mismatched brackets inside
+;; begin/end blocks.
+;; Needs to handle escaped parens for tex-validate-*.
+;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2007-09/msg00038.html
(defun latex-forward-sexp-1 ()
- "Like (forward-sexp 1) but aware of multi-char elements."
+ "Like (forward-sexp 1) but aware of multi-char elements and escaped parens."
(let ((pos (point))
(forward-sexp-function))
(forward-sexp 1)
@@ -1425,10 +1519,19 @@ Mark is left at original location."
((looking-at "\\\\begin\\>")
(goto-char (match-end 0))
(tex-next-unmatched-end))
+ ;; A better way to handle this, \( .. \) etc, is probably to
+ ;; temporarily change the syntax of the \ in \( to punctuation.
+ ((looking-back "\\\\[])}]")
+ (signal 'scan-error
+ (list "Containing expression ends prematurely"
+ (- (point) 2) (prog1 (point)
+ (goto-char pos)))))
+ ((looking-back "\\\\\\([({[]\\)")
+ (tex-next-unmatched-eparen (match-string 1)))
(t (goto-char newpos))))))
(defun latex-forward-sexp (&optional arg)
- "Like `forward-sexp' but aware of multi-char elements."
+ "Like `forward-sexp' but aware of multi-char elements and escaped parens."
(interactive "P")
(unless arg (setq arg 1))
(let ((pos (point)))
@@ -2169,7 +2272,7 @@ start of the header is required to be within the first 100 lines."
(widen)
(goto-char (point-min))
(let ((search-end (save-excursion
- (forward-line 100)
+ (forward-line 100)
(point)))
(already-output 0)
hbeg hend)
@@ -2186,11 +2289,11 @@ start of the header is required to be within the first 100 lines."
(and tex-start-of-header
(re-search-forward tex-start-of-header search-end t)
(progn
- (beginning-of-line)
- (setq hbeg (point)) ;mark beginning of header
+ (beginning-of-line)
+ (setq hbeg (point)) ; mark beginning of header
(when (re-search-forward tex-end-of-header nil t)
- (forward-line 1)
- (setq hend (point)) ;mark end of header
+ (forward-line 1)
+ (setq hend (point)) ; mark end of header
(write-region
(max (if beg
(min hbeg beg)