Mercurial > emacs
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 |