comparison lisp/textmodes/sgml-mode.el @ 58122:1e9ea828c37a

(sgml-tag-text-p): New fun. (sgml-parse-tag-backward): Use it to skip spurious < or >.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 10 Nov 2004 14:39:40 +0000
parents e60d53125cf2
children e51199adcfb0 cb7f41387eb3
comparison
equal deleted inserted replaced
58121:9d53304eb0af 58122:1e9ea828c37a
1 ;;; sgml-mode.el --- SGML- and HTML-editing modes 1 ;;; sgml-mode.el --- SGML- and HTML-editing modes
2 2
3 ;; Copyright (C) 1992,95,96,98,2001,2002, 2003 Free Software Foundation, Inc. 3 ;; Copyright (C) 1992, 1995, 1996, 1998, 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
4 5
5 ;; Author: James Clark <jjc@jclark.com> 6 ;; Author: James Clark <jjc@jclark.com>
6 ;; Maintainer: FSF 7 ;; Maintainer: FSF
7 ;; Adapted-By: ESR, Daniel Pfeiffer <occitan@esperanto.org>, 8 ;; Adapted-By: ESR, Daniel Pfeiffer <occitan@esperanto.org>,
8 ;; F.Potorti@cnuce.cnr.it 9 ;; F.Potorti@cnuce.cnr.it
1051 "Return t if the test before point matches STR." 1052 "Return t if the test before point matches STR."
1052 (let ((start (- (point) (length str)))) 1053 (let ((start (- (point) (length str))))
1053 (and (>= start (point-min)) 1054 (and (>= start (point-min))
1054 (equal str (buffer-substring-no-properties start (point)))))) 1055 (equal str (buffer-substring-no-properties start (point))))))
1055 1056
1057 (defun sgml-tag-text-p (start end)
1058 "Return non-nil if text between START and END is a tag.
1059 Checks among other things that the tag does not contain spurious
1060 unquoted < or > chars inside, which would indicate that it
1061 really isn't a tag after all."
1062 (save-excursion
1063 (with-syntax-table sgml-tag-syntax-table
1064 (let ((pps (parse-partial-sexp start end 2)))
1065 (and (= (nth 0 pps) 0))))))
1066
1056 (defun sgml-parse-tag-backward (&optional limit) 1067 (defun sgml-parse-tag-backward (&optional limit)
1057 "Parse an SGML tag backward, and return information about the tag. 1068 "Parse an SGML tag backward, and return information about the tag.
1058 Assume that parsing starts from within a textual context. 1069 Assume that parsing starts from within a textual context.
1059 Leave point at the beginning of the tag." 1070 Leave point at the beginning of the tag."
1060 (let (tag-type tag-start tag-end name) 1071 (catch 'found
1061 (or (re-search-backward "[<>]" limit 'move) 1072 (let (tag-type tag-start tag-end name)
1062 (error "No tag found")) 1073 (or (re-search-backward "[<>]" limit 'move)
1063 (when (eq (char-after) ?<) 1074 (error "No tag found"))
1064 ;; Oops!! Looks like we were not in a textual context after all!. 1075 (when (eq (char-after) ?<)
1065 ;; Let's try to recover. 1076 ;; Oops!! Looks like we were not in a textual context after all!.
1066 (with-syntax-table sgml-tag-syntax-table 1077 ;; Let's try to recover.
1067 (forward-sexp) 1078 (with-syntax-table sgml-tag-syntax-table
1068 (forward-char -1))) 1079 (let ((pos (point)))
1069 (setq tag-end (1+ (point))) 1080 (condition-case nil
1070 (cond 1081 (forward-sexp)
1071 ((sgml-looking-back-at "--") ; comment 1082 (scan-error
1072 (setq tag-type 'comment 1083 ;; This < seems to be just a spurious one, let's ignore it.
1073 tag-start (search-backward "<!--" nil t))) 1084 (goto-char pos)
1074 ((sgml-looking-back-at "]]") ; cdata 1085 (throw 'found (sgml-parse-tag-backward limit))))
1075 (setq tag-type 'cdata 1086 ;; Check it is really a tag, without any extra < or > inside.
1076 tag-start (re-search-backward "<!\\[[A-Z]+\\[" nil t))) 1087 (unless (sgml-tag-text-p pos (point))
1077 (t 1088 (goto-char pos)
1078 (setq tag-start 1089 (throw 'found (sgml-parse-tag-backward limit)))
1079 (with-syntax-table sgml-tag-syntax-table 1090 (forward-char -1))))
1080 (goto-char tag-end) 1091 (setq tag-end (1+ (point)))
1081 (backward-sexp) 1092 (cond
1082 (point))) 1093 ((sgml-looking-back-at "--") ; comment
1083 (goto-char (1+ tag-start)) 1094 (setq tag-type 'comment
1084 (case (char-after) 1095 tag-start (search-backward "<!--" nil t)))
1085 (?! ; declaration 1096 ((sgml-looking-back-at "]]") ; cdata
1086 (setq tag-type 'decl)) 1097 (setq tag-type 'cdata
1087 (?? ; processing-instruction 1098 tag-start (re-search-backward "<!\\[[A-Z]+\\[" nil t)))
1088 (setq tag-type 'pi)) 1099 (t
1089 (?/ ; close-tag 1100 (setq tag-start
1090 (forward-char 1) 1101 (with-syntax-table sgml-tag-syntax-table
1091 (setq tag-type 'close 1102 (goto-char tag-end)
1092 name (sgml-parse-tag-name))) 1103 (condition-case nil
1093 (?% ; JSP tags 1104 (backward-sexp)
1094 (setq tag-type 'jsp)) 1105 (scan-error
1095 (t ; open or empty tag 1106 ;; This > isn't really the end of a tag. Skip it.
1096 (setq tag-type 'open 1107 (goto-char (1- tag-end))
1097 name (sgml-parse-tag-name)) 1108 (throw 'found (sgml-parse-tag-backward limit))))
1098 (if (or (eq ?/ (char-before (- tag-end 1))) 1109 (point)))
1099 (sgml-empty-tag-p name)) 1110 (goto-char (1+ tag-start))
1100 (setq tag-type 'empty)))))) 1111 (case (char-after)
1101 (goto-char tag-start) 1112 (?! ; declaration
1102 (sgml-make-tag tag-type tag-start tag-end name))) 1113 (setq tag-type 'decl))
1114 (?? ; processing-instruction
1115 (setq tag-type 'pi))
1116 (?/ ; close-tag
1117 (forward-char 1)
1118 (setq tag-type 'close
1119 name (sgml-parse-tag-name)))
1120 (?% ; JSP tags
1121 (setq tag-type 'jsp))
1122 (t ; open or empty tag
1123 (setq tag-type 'open
1124 name (sgml-parse-tag-name))
1125 (if (or (eq ?/ (char-before (- tag-end 1)))
1126 (sgml-empty-tag-p name))
1127 (setq tag-type 'empty))))))
1128 (goto-char tag-start)
1129 (sgml-make-tag tag-type tag-start tag-end name))))
1103 1130
1104 (defun sgml-get-context (&optional until) 1131 (defun sgml-get-context (&optional until)
1105 "Determine the context of the current position. 1132 "Determine the context of the current position.
1106 By default, parse until we find a start-tag as the first thing on a line. 1133 By default, parse until we find a start-tag as the first thing on a line.
1107 If UNTIL is `empty', return even if the context is empty (i.e. 1134 If UNTIL is `empty', return even if the context is empty (i.e.
1964 ""))) 1991 "")))
1965 \n)) 1992 \n))
1966 1993
1967 (provide 'sgml-mode) 1994 (provide 'sgml-mode)
1968 1995
1969 ;;; arch-tag: 9675da94-b7f9-4bda-ad19-73ed7b4fb401 1996 ;; arch-tag: 9675da94-b7f9-4bda-ad19-73ed7b4fb401
1970 ;;; sgml-mode.el ends here 1997 ;;; sgml-mode.el ends here