Anonymous avatar Anonymous committed 769067e

font-latex-0.603

Comments (0)

Files changed (3)

+1998-04-10  SL Baur  <steve@altair.xemacs.org>
+
+	* font-latex.el-0.603.
+
 1998-04-10  SL Baur  <steve@altair.xemacs.org>
 
 	* font-latex.el-0.512.
 
 # remove the MULE_ELCS line for building without Mule.
 
-VERSION = 1.08
+VERSION = 1.09
 AUTHOR_VERSION = 9.7p
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = auctex
 ;;             Simon Marshall <Simon.Marshall@esrin.esa.it>
 ;; Maintainer: Peter S. Galbraith <GalbraithP@df0-mpo.gc.ca>
 ;; Created:    06 July 1996
-;; Version:    0.512 (7 Apr 98)
+;; Version:    0.603 (02 July 1998)
 ;; Keywords:   LaTeX faces
 
 ;; RCS $Id$
 ;; LaTeX fontification for font-lock|
 ;; 06-Jul-1996|0.01|~/modes/font-latex.el|
 
-;; The archive is archive.cis.ohio-state.edu in /pub/gnu/emacs/elisp-archive.
+;; The archive is ftp://archive.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive/
+;;            or http://ftp.digital.com/pub/GNU/elisp-archive/
 
 ;;; This file is not part of GNU Emacs.
 
 ;;    instead of `highlighting 1: \(^\|[^\\]\)\(\\[a-zA-Z\\]+\)'
 ;; ----------------------------------------------------------------------------
 ;;; Change log:
+;; V0.603 02July98 PSG (RCS V1.61)
+;;    Squashed another infinite loop.
+;; V0.602 02July98 PSG (RCS V1.60)
+;;    Added 'font and 'infont keywords to narrow cache triggers.
+;; V0.601 02July98 PSG (RCS V1.59)
+;;    Added new font-latex-find-matching-close function to replace scan-sexp.
+;;    It now searches for matching {} or [] when scan-sexp fails.
+;; V0.600 16June98 PSG (RCS V1.58)
+;;    Rewrote the cache method again.
 ;; V0.512 07Apr98 Stephen R. Anderson <sra@bloch.ling.yale.edu> (RCS V1.57)
 ;;    xemacs beta 20.5 sets the major version to 21.
 ;; V0.511 07Apr98 PSG (RCS V1.55)
 ;; is used like scan-sexp.  It skips over matching
 ;; pairs of '{' and '}'.  As an added benefit, it ignores any characters
 ;; which occur after the tex comment character %.
-(defun font-latex-find-matching-close (closechar)
-"*Skip over matching pairs of '{' and '}', ignoring
-any characters in comments, until closechar is found.  If the end of file
-is reached, return nil."
-  (save-excursion
-    (save-match-data
-      (let ((mycount 1))
-	(while (and (> mycount 0)
-		    (progn
-		      (backward-char 1)
-		      (re-search-forward
-		       (concat "[^\\\\]["
-			       ;; closechar might be ]
-			       ;; and therefor must be first in regexp
-			       (char-to-string closechar)
-			       "{}%]")
-		       nil t)))
-	  (if (= (preceding-char) ?%) ;; Found a comment
-	      (forward-line 1)
-	    (setq mycount (if (= (preceding-char) ?{)
-			      (+ mycount 1)
-			    (- mycount 1)))))
-	(if (= mycount 0)
-            (point)
-          (error ""))))))
+(defun font-latex-find-matching-close (openchar closechar)
+  "Skip over matching pairs of { } or [ ], ignoring comments"
+  (let ((parse-sexp-ignore-comments t) ; scan-sexps ignores comments
+        (init-point (point))
+        (status))
+    (if (condition-case nil
+            (goto-char (scan-sexps (point) 1))
+          (error))
+        ;; No error code.  See if closechar is quoted
+        (if (save-excursion (backward-char 1) (= (preceding-char) ?\\))
+            (setq status nil)
+          (setq status t))
+      ;; Terminated in error -- Try ourselves
+      (setq status nil))
+    (if status
+        t
+      (goto-char init-point)
+      (let ((target)
+            (mycount 1))
+        (save-excursion
+          (save-match-data
+            (forward-char 1)
+            (while (and (> mycount 0)
+                        (progn
+                          (re-search-forward
+                           (concat "["
+                                   ;; closechar might be ]
+                                   ;; and therefor must be first in regexp
+                                   (char-to-string closechar)
+                                   (char-to-string openchar)
+                                   "]")
+                           nil t)))
+              (cond 
+               ((font-latex-commented-outp)
+                (forward-line 1))
+               ((save-excursion (backward-char 1) (= (preceding-char) ?\\))
+                nil)
+               (t
+                (setq mycount (if (= (preceding-char) openchar)
+                                  (+ mycount 1)
+                                (- mycount 1))))))
+            (setq target (point))
+            (if (not (= mycount 0))
+                nil)))
+        (if (= mycount 0)
+            (goto-char target))))))
 
 ;; FIXME: --About font-latex-commented-outp--
 ;; Fontification is *slower* for affected functions (in particular
             t
           nil)))))
 
-(defvar font-latex-match-command-cache-start nil
-  "Cache start of unterminated match to fontify")
-(defvar font-latex-match-command-cache-end nil
-  "Cache end of unterminated match to fontify")
-(defvar font-latex-match-command-cache-limit nil
-  "Cache limit of unterminated match to fontify")
-(defvar font-latex-match-command-cache-keywords nil
-  "Cache keywords of unterminated match to fontify")
-(defvar font-latex-match-command-cache-match nil
-  "Cache last match of unterminated match")
-(defvar font-latex-match-command-cache-stop nil
-  "Flag to not move point, because same pattern was returned twice to fontify")
+;;;;------------------
+;;;; Cache Method:
+;;;
+;;; This works:
+;;; 
+;;; (defun font-latex-set-cache (cache-id)
+;;;   (let ((cache (intern cache-id)))
+;;;     (set cache (list (point) (point-max)))))
+;;; (defun font-latex-get-cache (cache-id item)
+;;;   (let ((cache (intern cache-id)))
+;;;     (nth item (symbol-value cache))))
+;;; (font-latex-set-cache "font-latex-match-command-cache")
+;;; (font-latex-get-cache "font-latex-match-command-cache" 1)
+;;;
+;;; but let's use symbols instead:
 
-(make-variable-buffer-local 'font-latex-match-command-cache-start)
-(make-variable-buffer-local 'font-latex-match-command-cache-end)
-(make-variable-buffer-local 'font-latex-match-command-cache-limit)
-(make-variable-buffer-local 'font-latex-match-command-cache-keywords)
-(make-variable-buffer-local 'font-latex-match-command-cache-match)
-(make-variable-buffer-local 'font-latex-match-command-cache-stop)
+;;; Hacker's note: I haven't tested extensively using lazy-lock, which
+;;; apparently fontifies the entire visble page instead of just the current
+;;; line.  This could actually be slower than not using lazy-lock using the
+;;; current code.  Perhaps there's an opportunity to take advantage of
+;;; lazy-lock with alternate coding.
+
+;;; Hacker's note: If this method leads to infinite loops again, I could
+;;; change the cache method to something like:
+;;;  - When the pattern is un-finished, simply store the limit in the cache.
+;;;    and the regexp to match the termination.
+;;;  - When checking the cache, check to see if we're at the limit, and if
+;;;    so fontify the text directly like at point limit-1 (instead of
+;;;    letting font-lock itself set the font!) until either the regexp match
+;;;    is found or set another cache at the new limit
+;;;  - the scheme must allow a newline to be correctly fontified, and well
+;;;    as new characters on the same line as the first cache.  (How?)
+
+(defun font-latex-set-cache (cache-id kbeg kend limit keywords match-list)
+  "cache in symbol CACHE-ID the following info:
+KBEG and KEND: beginning and end points of the LaTeX keyword (e.g. \"section\")
+LIMIT:         up to where fontification is done.
+KEYWORDS:      the font-lock regexp that initiated the cache.
+MATCH LIST:    the match list that was returned to font-lock
+
+The INITIAL POINT from which we last moved is stored in the same cache, but 
+it's done elsewhere.  We will never fontify the same MATCH LIST twice in a 
+row from same INITIAL POINT."
+;debug  (message "Setting cache!")
+  (let ((ini-point (nth 5 (symbol-value cache-id)))
+        (oldlimit (nth 6 (symbol-value cache-id))))
+    (set cache-id 
+         (list kbeg kend limit keywords match-list ini-point oldlimit))))
+
+(defun font-latex-get-cache (cache-id item)
+"Retrieve info from cache in symbol CACHE-ID
+ 0: kbegin
+ 1: kend
+ 2: limit
+ 3: keywords
+ 4: match-list from last succesful cache
+ 5: initial point from which we last moved
+ 6: limit when we last moved"
+  (let ((cache (symbol-value cache-id)))
+    (nth item cache)))
+
+(defun font-latex-check-cache (cache-id keywords limit)
+  "Check that current parameters are consistent with cache to move point.
+If we move point, alter the last entry in the cache to indicate from where 
+we moved and the current limit.
+Return t if we move, false if we don't."
+  (let ((the-point (point))
+        (kbeg (font-latex-get-cache cache-id 0))
+        (inip (or (font-latex-get-cache cache-id 5) 0))
+        (oldlimit (or (font-latex-get-cache cache-id 6) 0)))
+    (when 
+        (and 
+         font-latex-do-multi-line
+         kbeg                           ;; Check that cache is actually set
+         (equal keywords (font-latex-get-cache cache-id 3))
+;debug   (message "1- cache: %s" (symbol-name cache-id))
+;debug   (message "1- keywords are the same; next compare point %s to %s" 
+;debug            the-point (font-latex-get-cache cache-id 1))
+         (not (= the-point (font-latex-get-cache cache-id 1)))
+;debug   (message "2- Not on end of keyword %s != %s; next after kbeg %s" 
+;debug            the-point (font-latex-get-cache cache-id 1) kbeg)
+         (< kbeg the-point)
+;debug   (message "3- After beginning of keyword at %s; next within limit %s"
+;debug            kbeg (font-latex-get-cache cache-id 2))
+         (<= the-point (font-latex-get-cache cache-id 2))
+;debug   (message "4- Within limit at %s" (font-latex-get-cache cache-id 2))
+;debug   (message "5- Same limit as last time?: %s vs %s  Point greater? %s > %s" 
+;debug            limit oldlimit the-point inip)
+         (or (< the-point inip) (not (= limit oldlimit)))
+;debug   (message "6- Is %s on same line as %s?" the-point kbeg)
+         (font-latex-not-on-same-line-as kbeg))
+;debug   (message "7- moving from %s to %s!" the-point kbeg)
+      (goto-char kbeg)
+      (let* ((cache (symbol-value cache-id))
+             (e0 kbeg)
+             (e1 (nth 1 cache))
+             (e2 (nth 2 cache))
+             (e3 (nth 3 cache))
+             (e4 (nth 4 cache)))
+        (set cache-id (list e0 e1 e2 e3 e4 the-point limit)))
+      t)))
+
+;;;;-----
+
+(defvar font-latex-match-command-cache nil
+  "Cache for font-latex-match-command")
+(make-variable-buffer-local 'font-latex-match-command-cache)
 
 ;; FIXME - Note to myself 
 ;; In call to font-latex-match-command-outside-arguments, I could arrange
 ;; such that keywords which cannot use [options] have this set to nil.
-;; LaTeX code woulldn't fontify if options are used illegally in commands,
+;; LaTeX code wouldn't fontify if options are used illegally in commands,
 ;; cuing users in that they are doing something wrong.  (See RCS V1.11 for
 ;; useopt option)
 ;;
  subexpression 1 is the contents of any following [...] forms 
  subexpression 2 is the contents of any following {...} forms.  
 Returns nil if none of KEYWORDS is found."
-  (when (and font-latex-do-multi-line
-             font-latex-match-command-cache-keywords
-             font-latex-match-command-cache-limit
-             font-latex-match-command-cache-start
-             font-latex-match-command-cache-end
-             (equal font-latex-match-command-cache-keywords keywords)
-             (not (= font-latex-match-command-cache-end (point)))
-             (< font-latex-match-command-cache-start (point))
-             (>= font-latex-match-command-cache-limit (point))
-             (not font-latex-match-command-cache-stop)
-             (font-latex-not-on-same-line-as 
-              font-latex-match-command-cache-start))
-    (goto-char font-latex-match-command-cache-start))
-  (setq font-latex-match-command-cache-stop nil)
-  (when (re-search-forward keywords limit t)
-    (cond
-     ((font-latex-commented-outp)
-      ;; Return a nul match such that we skip over this pattern.
-      ;; (Would be better to skip over internally to this function)
-      (store-match-data (list nil nil))
-      t)
-     (t
-      (let ((kbeg (match-beginning 0)) 
-            kend sbeg send cbeg cend
-            cache-reset
-            (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
-        (goto-char (match-end 0))
-        (if (and asterix (eq (following-char) ?\*))
-            (forward-char 1)) 
-        (skip-chars-forward " \n\t" limit)
-        (setq kend (point))
-        (while (eq (following-char) ?\[)
-          (setq sbeg kend)
-          (save-restriction
-            ;; Restrict to LIMIT.
-            (narrow-to-region (point-min) limit)
-            (if (condition-case nil
-                    (goto-char (or (scan-sexps (point) 1)
-                                ;;;(font-latex-find-matching-close ?\])
-                                   (point-max)))
-                  (error))
-                (setq send (point))
-              (setq cache-reset t)
-              (setq send (point-max))
-              (goto-char send))))
-        (skip-chars-forward " \n\t" limit)
-        (when (eq (following-char) ?\{)
-          (setq cbeg (point))
-          (save-restriction
-            ;; Restrict to LIMIT.
-            (narrow-to-region (point-min) limit)
-            (if (condition-case nil
-                    (goto-char (or (scan-sexps (point) 1) (point-max)))
-                  (error))
-                (setq cend (point))
-              (setq cache-reset t)
-              (setq cend (point-max))
-              (goto-char cend)))
+  (let ((we-moved (font-latex-check-cache 
+                   'font-latex-match-command-cache keywords limit)))
+    (when (re-search-forward keywords limit t)
+      (cond
+       ((font-latex-commented-outp)
+        ;; Return a nul match such that we skip over this pattern.
+        ;; (Would be better to skip over internally to this function)
+        (store-match-data (list nil nil))
+        t)
+       (t
+        (let ((kbeg (match-beginning 0)) 
+              kend sbeg send cbeg cend
+              cache-reset
+              (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
+          (goto-char (match-end 0))
+          (if (and asterix (eq (following-char) ?\*))
+              (forward-char 1)) 
+          (skip-chars-forward " \n\t" limit)
+          (setq kend (point))
+          (while (eq (following-char) ?\[)
+            (setq sbeg kend)
+            (save-restriction
+              ;; Restrict to LIMIT.
+              (narrow-to-region (point-min) limit)
+              (if (font-latex-find-matching-close ?\[ ?\])
+                  (setq send (point))
+                (setq cache-reset t)
+                (setq send (point-max))
+                (goto-char send))))
+          (skip-chars-forward " \n\t" limit)
+          (when (eq (following-char) ?\{)
+            (setq cbeg (point))
+            (save-restriction
+              ;; Restrict to LIMIT.
+              (narrow-to-region (point-min) limit)
+              (if (font-latex-find-matching-close ?\{ ?\})
+                  (setq cend (point))
+                (setq cache-reset t)
+                (setq cend (point-max))
+                (goto-char cend))))
           (when twoargs
             (skip-chars-forward " \n\t" limit)
             (when (eq (following-char) ?\{)
               (save-restriction
                 ;; Restrict to LIMIT.
                 (narrow-to-region (point-min) limit)
-                (if (condition-case nil
-                        (goto-char (or (scan-sexps (point) 1) (point-max)))
-                      (error))
+                (if (font-latex-find-matching-close ?\{ ?\})
                     (setq cend (point))
                   (setq cache-reset t)
                   (setq cend (point-max))
-                  (goto-char cend))))))
-        (store-match-data (list kbeg kend sbeg send cbeg cend))
+                  (goto-char cend)))))
+          (store-match-data (list kbeg kend sbeg send cbeg cend))
+          
+          ;; Handle cache
+;          (if (and we-moved
+;                   (equal (list kbeg kend sbeg send cbeg cend)
+;                          (font-latex-get-cache 
+;                           'font-latex-match-command-cache 4)))
+;              (progn
+;                (message "pattern cancelled... twice in a row")
+;                nil) ;; Return a nul search (cancel this fontification)
 
-        (when (and font-latex-do-multi-line
-                   font-latex-match-command-cache-keywords ;Sanity check!
-                   (equal font-latex-match-command-cache-keywords keywords)
-                   font-latex-match-command-cache-match
-                   (equal font-latex-match-command-cache-match
-                          (list kbeg kend sbeg send cbeg cend)))
-          (setq font-latex-match-command-cache-stop t))
-        (setq font-latex-match-command-cache-match
-              (list kbeg kend sbeg send cbeg cend))
+          (when (and font-latex-do-multi-line cache-reset)
+            (font-latex-set-cache 
+             'font-latex-match-command-cache 
+             kbeg kend limit keywords (list kbeg kend sbeg send cbeg cend)))
+          t))))))
 
-        (when (and font-latex-do-multi-line cache-reset)
-          (setq font-latex-match-command-cache-start kbeg
-                font-latex-match-command-cache-end   kend
-                font-latex-match-command-cache-limit (point)
-                font-latex-match-command-cache-keywords keywords))
-          t)))))
-
-(defvar font-latex-match-font-cache-start nil
-  "Cache start of unterminated match to fontify")
-(defvar font-latex-match-font-cache-end nil
-  "Cache end of unterminated match to fontify")
-(defvar font-latex-match-font-cache-limit nil
-  "Cache limit of unterminated match to fontify")
-(defvar font-latex-match-font-cache-match nil
-  "Cache last match of unterminated match")
-(defvar font-latex-match-font-cache-stop nil
-  "Flag to not move point, because same pattern was returned twice to fontify")
-(make-variable-buffer-local 'font-latex-match-font-cache-start)
-(make-variable-buffer-local 'font-latex-match-font-cache-end)
-(make-variable-buffer-local 'font-latex-match-font-cache-limit)
-(make-variable-buffer-local 'font-latex-match-font-cache-match)
-(make-variable-buffer-local 'font-latex-match-font-cache-stop)
+(defvar font-latex-match-font-cache nil
+  "Cache start of unterminated LaTeX font-changing commands to fontify")
+(make-variable-buffer-local 'font-latex-match-font-cache)
 
 (defun font-latex-match-font-outside-braces (limit)
   "Search for font-changing command like \textbf{fubar} before LIMIT.  
  subexpression 2 is the content to fontify in bold.
  subexpression 3 is the content to fontify in type-face.
 Returns nil if no font-changing command is found."
-  (when (and font-latex-do-multi-line
-             font-latex-match-font-cache-limit
-             font-latex-match-font-cache-start
-             font-latex-match-font-cache-end
-             (not (= font-latex-match-font-cache-end (point)))
-             (>= font-latex-match-font-cache-limit (point))
-             (< font-latex-match-font-cache-start (point))
-	     (not font-latex-match-font-cache-stop)
-             (font-latex-not-on-same-line-as 
-              font-latex-match-font-cache-start))
-    (goto-char font-latex-match-font-cache-start))
-  (setq font-latex-match-font-cache-stop nil)
+  (font-latex-check-cache 'font-latex-match-font-cache 'font limit)
   (when (re-search-forward
          (eval-when-compile
            (concat "\\\\" "\\("
                    "\\(emph\\)\\|"			      ;;; 2 - italic
                    "\\(text\\("
                                "\\(it\\|sl\\)\\|"	      ;;; 5 - italic
-                               "\\(md\\|rm\\|sf\\|tt\\)\\|"   ;;; 6 - type
+                               "\\(md\\|rm\\|sf\\|tt\\)\\|" ;;; 6 - type
                                "\\(bf\\|sc\\|up\\)"	      ;;; 7 - bold
                           "\\)\\)\\|"
                    "\\(boldsymbol\\|pmb\\)"		      ;;; 8 - bold
       t)
      (t
       (let ((kbeg (match-beginning 0)) (kend (match-end 1)) 
-            (beg  (match-end 0)) 
+            (beg  (1- (match-end 0)))   ;Include openning bracket
             end itbeg itend bfbeg bfend ttbeg ttend
-            (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
+            (parse-sexp-ignore-comments t) ; scan-sexps ignores comments
+            cache-reset)
         (goto-char kend)
         (save-restriction
           ;; Restrict to LIMIT.
           (narrow-to-region (point-min) limit)
-          (cond 
-           ((condition-case nil
-                (goto-char (or (scan-sexps (point) 1)
-                              ;;;(font-latex-find-matching-close ?\})
-                               (point-max)))
-              (error))
-            (setq end (1- (point))))
-           (t
+          (if (font-latex-find-matching-close ?\{ ?\})
+              (setq end (point))
+            (setq cache-reset t)
             (setq end (point-max))
-            (goto-char end)
-            (setq font-latex-match-font-cache-start kbeg
-                  font-latex-match-font-cache-end   kend
-                  font-latex-match-font-cache-limit (point)))))
+            (goto-char end)))
         (cond ((or (match-beginning 2) (match-beginning 5))
                (setq itbeg beg  itend end))
               ((match-beginning 6)
                (setq ttbeg beg  ttend end))
               (t
-
                (setq bfbeg beg  bfend end)))
         (store-match-data 
          (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
         ;; Start the subsequent search immediately after this keyword.
-        (goto-char kend)
-
-	(when ;Sanity check!
-	    (equal font-latex-match-font-cache-match
-		   (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
-	  (setq font-latex-match-font-cache-stop t))
-        (setq font-latex-match-font-cache-match
-              (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
+          (goto-char kend)
+          
+        (when (and font-latex-do-multi-line cache-reset)
+          (goto-char limit)             ;Avoid infinite loops?
+          (font-latex-set-cache 
+           'font-latex-match-font-cache 
+           kbeg kend limit 'font 
+           (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend)))
+        
         t)))))
-
-(defvar font-latex-match-infont-cache-start nil
-  "Cache start of unterminated match to fontify")
-(defvar font-latex-match-infont-cache-end nil
-  "Cache end of unterminated match to fontify")
-(defvar font-latex-match-infont-cache-limit nil
-  "Cache limit of unterminated match to fontify")
-(defvar font-latex-match-infont-cache-match nil
-  "Cache last match of unterminated match")
-(defvar font-latex-match-infont-cache-stop nil
-  "Flag to not move point, because same pattern was returned twice to fontify")
-(make-variable-buffer-local 'font-latex-match-infont-cache-start)
-(make-variable-buffer-local 'font-latex-match-infont-cache-end)
-(make-variable-buffer-local 'font-latex-match-infont-cache-limit)
-(make-variable-buffer-local 'font-latex-match-infont-cache-match)
-(make-variable-buffer-local 'font-latex-match-infont-cache-stop)
+  
+(defvar font-latex-match-infont-cache nil
+  "Cache start of unterminated LaTeX font-changing commands to fontify")
+(make-variable-buffer-local 'font-latex-match-infont-cache)
 
 (defun font-latex-match-font-inside-braces (limit)
   "Search for font-changing command like {\bf fubar} before LIMIT.  
  subexpression 2 is the content to fontify in bold.
  subexpression 3 is the content to fontify in type-face.
 Returns nil if no font-changing command is found."
-  ;; Infinite loop without this configuration.
-  (if font-latex-match-infont-cache-stop
-      (setq font-latex-match-infont-cache-stop nil) ;Stop now!
-    (when (and font-latex-do-multi-line
-               font-latex-match-infont-cache-limit
-               (>= font-latex-match-infont-cache-limit (point))
-               (<  font-latex-match-infont-cache-start (point))
-               (font-latex-not-on-same-line-as 
-                font-latex-match-infont-cache-start))
-      (goto-char font-latex-match-infont-cache-start))
-    (setq font-latex-match-infont-cache-stop nil)
-    (when (re-search-forward
-           (eval-when-compile
-             (concat "\\\\" "\\("
+  (font-latex-check-cache 'font-latex-match-infont-cache 'infont limit)
+  (when (re-search-forward
+         (eval-when-compile
+           (concat "\\\\" "\\("
                                                               ;;; 2 - italic
-                     "\\(em\\|it\\(shape\\)?\\|sl\\(shape\\)?\\)\\|"
+                   "\\(em\\|it\\(shape\\)?\\|sl\\(shape\\)?\\)\\|"
 	                                                      ;;; 5 - bold
-                     "\\(bf\\(series\\)?\\|upshape\\|sc\\(shape\\)?\\)\\|"
-                     "mdseries\\|tt\\(family\\)?\\|"
-                     "sf\\(family\\)?\\|rm\\(family\\)?\\|"
-                     "tiny\\|scriptsize\\|footnotesize\\|"
-                     "small\\|normalsize\\|large\\|Large\\|LARGE\\|huge\\|Huge"
-                     "\\)\\>[ \t]*"))
-           limit t)
-      (cond
-       ((font-latex-commented-outp)
-        ;; Return a nul match such that we skip over this pattern.
-        ;; (Would be better to skip over internally to this function)
-        ;; Using `prepend' won't help here, because the problem is that
-        ;; scan-sexp *fails* to find a commented-out matching bracket!
-        (store-match-data (list nil nil))
-        t)
-       (t
-        (let ((kbeg (match-beginning 0)) (kend (match-end 1)) 
-              (beg  (match-end 0))
-              end itbeg itend bfbeg bfend ttbeg ttend
-              (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
-          (goto-char kbeg)
-          (cond
-           ((not (eq (preceding-char) ?\{))
-            ;; Fontify only the keyword as bf/it/type (no argument found).
-            (cond ((match-beginning 2) (setq itbeg kbeg itend kend))
-                  ((match-beginning 5) (setq bfbeg kbeg bfend kend))
-                  (t                   (setq ttbeg kbeg ttend kend)))
-            (goto-char (match-end 0))
+                   "\\(bf\\(series\\)?\\|upshape\\|sc\\(shape\\)?\\)\\|"
+                   "mdseries\\|tt\\(family\\)?\\|"
+                   "sf\\(family\\)?\\|rm\\(family\\)?\\|"
+                   "tiny\\|scriptsize\\|footnotesize\\|"
+                   "small\\|normalsize\\|large\\|Large\\|LARGE\\|huge\\|Huge"
+                   "\\)\\>[ \t]*"))
+         limit t)
+    (cond
+     ((font-latex-commented-outp)
+      ;; Return a nul match such that we skip over this pattern.
+      ;; (Would be better to skip over internally to this function)
+      ;; Using `prepend' won't help here, because the problem is that
+      ;; scan-sexp *fails* to find a commented-out matching bracket!
+      (store-match-data (list nil nil))
+      t)
+     (t
+      (let ((kbeg (match-beginning 0)) (kend (match-end 1)) 
+            (beg  (match-end 0))
+            end itbeg itend bfbeg bfend ttbeg ttend
+            cache-reset
+            (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
+        (goto-char kbeg)
+        (cond
+         ((not (eq (preceding-char) ?\{))
+          ;; Fontify only the keyword as bf/it/type (no argument found).
+          (cond ((match-beginning 2) (setq itbeg kbeg itend kend))
+                ((match-beginning 5) (setq bfbeg kbeg bfend kend))
+                (t                   (setq ttbeg kbeg ttend kend)))
+          (goto-char (match-end 0))
+          (store-match-data 
+           (list nil nil itbeg itend bfbeg bfend ttbeg ttend))
+          t)
+         (t
+          ;; There's an opening bracket
+          (save-restriction
+            ;; Restrict to LIMIT.
+            (narrow-to-region (point-min) limit)
+            (forward-char -1)           ;Move on the opening bracket
+            (if (font-latex-find-matching-close ?\{ ?\})
+                (setq end (point))
+              (setq cache-reset t)
+              (setq end (point-max))
+              (goto-char end))
+            (cond ((match-beginning 2) (setq itbeg beg  itend end))
+                  ((match-beginning 5) (setq bfbeg beg  bfend end))
+                  (t                   (setq ttbeg beg  ttend end)))
             (store-match-data 
-             (list nil nil itbeg itend bfbeg bfend ttbeg ttend))
-            t)
-           (t
-            ;; There's an opening bracket
-            (save-restriction
-              ;; Restrict to LIMIT.
-              (narrow-to-region (point-min) limit)
-              (forward-char -1)           ;Move on the opening bracket
-              (cond 
-               ((condition-case nil
-                    (goto-char (or (scan-sexps (point) 1) (point-max)))
-                  (error))
-                (setq end (1- (point))))
-               (t                       ;error!
-                (setq end (point-max))
-                (goto-char end)
-                (setq font-latex-match-infont-cache-start kbeg
-                      font-latex-match-infont-cache-end   kend
-                      font-latex-match-infont-cache-limit (point))))
-              (cond ((match-beginning 2) (setq itbeg beg  itend end))
-                    ((match-beginning 5) (setq bfbeg beg  bfend end))
-                    (t                   (setq ttbeg beg  ttend end)))
-              (store-match-data 
-               (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
+             (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
+            
+            ;; Start the subsequent search immediately after this keyword.
+            (goto-char kend)
 
-              ;; XEmacs appears to move point after the fartest match.
-              ;; Emacs lets me move point within the match, usually after the
-              ;; first keyword.
-              (when ;Sanity check!
-                  (equal font-latex-match-infont-cache-match
-                         (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
-                (setq font-latex-match-infont-cache-stop t))
-              (setq font-latex-match-infont-cache-match
-                    (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
-              
-              ;; Start the subsequent search immediately after this keyword.
-              (goto-char kend)
-              t)))))))))
+            (when (and font-latex-do-multi-line cache-reset)
+              (goto-char limit)             ;Avoid infinite loops?
+              (font-latex-set-cache 
+               'font-latex-match-infont-cache 
+               kbeg kend limit 'infont
+               (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend)))
+
+            t))))))))
 
 (defun font-latex-not-on-same-line-as (cache-start)
   "Return t if point is not on same line as CACHE-START."
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.