aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2001-10-25 22:25:30 +0000
committerStefan Monnier2001-10-25 22:25:30 +0000
commit6436765542a0f14d8c0d65bf7616d78bc6767289 (patch)
tree759977bf2ae62e8bf195031426ab0042d223a7f7
parent5cd62b8c044951d524a703cbacb8abf249ea0dd0 (diff)
downloademacs-6436765542a0f14d8c0d65bf7616d78bc6767289.tar.gz
emacs-6436765542a0f14d8c0d65bf7616d78bc6767289.zip
(sgml-font-lock-keywords-1): Ignore comments.
(sgml-font-lock-keywords-2): Use `eval'. Moved from sgml-mode-common. (sgml-font-lock-syntactic-keywords): New var. (sgml-mode-common): Drop the two args. Don't make buffer-local variables that aren't used. Don't set sgml-font-lock-keywords-2 now that it uses `eval instead. Don't set `before-string' props from sgml-display-text. (sgml-mode): Use define-derived-mode. (sgml-tags-invisible): Use sgml-display-text. (sgml-quote): New command. (html-tag-alist): Add args for `span'. (html-mode): Use define-derived-mode. Set sgml-display-text and sgml-tag-face-alist.
-rw-r--r--lisp/textmodes/sgml-mode.el127
1 files changed, 69 insertions, 58 deletions
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index a97f0888b11..3642aa5c5b3 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -234,16 +234,31 @@ Any terminating `>' or `/' is not matched.")
234(defconst sgml-font-lock-keywords-1 234(defconst sgml-font-lock-keywords-1
235 '(("<\\([!?][a-z][-.a-z0-9]*\\)" 1 font-lock-keyword-face) 235 '(("<\\([!?][a-z][-.a-z0-9]*\\)" 1 font-lock-keyword-face)
236 ("<\\(/?[a-z][-.a-z0-9]*\\)" 1 font-lock-function-name-face) 236 ("<\\(/?[a-z][-.a-z0-9]*\\)" 1 font-lock-function-name-face)
237 ("[&%][a-z][-.a-z0-9]*;?" . font-lock-variable-name-face) 237 ("[&%][a-z][-.a-z0-9]*;?" . font-lock-variable-name-face)))
238 ("<! *--.*-- *>" . font-lock-comment-face))) 238
239 239(defconst sgml-font-lock-keywords-2
240(defconst sgml-font-lock-keywords-2 ()) 240 (append
241 sgml-font-lock-keywords-1
242 '((eval
243 . (cons (concat "<"
244 (regexp-opt (mapcar 'car sgml-tag-face-alist) t)
245 "\\([ \t][^>]*\\)?>\\([^<]+\\)</\\1>")
246 '(3 (cdr (assoc (downcase (match-string 1))
247 sgml-tag-face-alist))))))))
241 248
242;; for font-lock, but must be defvar'ed after 249;; for font-lock, but must be defvar'ed after
243;; sgml-font-lock-keywords-1 and sgml-font-lock-keywords-2 above 250;; sgml-font-lock-keywords-1 and sgml-font-lock-keywords-2 above
244(defvar sgml-font-lock-keywords sgml-font-lock-keywords-1 251(defvar sgml-font-lock-keywords sgml-font-lock-keywords-1
245 "*Rules for highlighting SGML code. See also `sgml-tag-face-alist'.") 252 "*Rules for highlighting SGML code. See also `sgml-tag-face-alist'.")
246 253
254(defvar sgml-font-lock-syntactic-keywords
255 ;; Use the `b' style of comments to avoid interference with the -- ... --
256 ;; comments recognized when `sgml-specials' includes ?-.
257 ;; FIXME: beware of <!--> blabla <!--> !!
258 '(("\\(<\\)!--" (1 "< b"))
259 ("--[ \t\n]*\\(>\\)" (1 "> b")))
260 "Syntactic keywords for `sgml-mode'.")
261
247;; internal 262;; internal
248(defvar sgml-face-tag-alist () 263(defvar sgml-face-tag-alist ()
249 "Alist of face and tag name for facemenu.") 264 "Alist of face and tag name for facemenu.")
@@ -303,13 +318,8 @@ an optional alist of possible values."
303 318
304(defvar v2) ; free for skeleton 319(defvar v2) ; free for skeleton
305 320
306(defun sgml-mode-common (sgml-tag-face-alist sgml-display-text) 321(defun sgml-mode-common ()
307 "Common code for setting up `sgml-mode' and derived modes. 322 "Common code for setting up `sgml-mode' and derived modes."
308SGML-TAG-FACE-ALIST is used for calculating `sgml-font-lock-keywords-2'.
309SGML-DISPLAY-TEXT sets up alternate text for when tags are invisible (see
310varables of same name)."
311 (setq local-abbrev-table text-mode-abbrev-table)
312 (set-syntax-table sgml-mode-syntax-table)
313 (make-local-variable 'indent-line-function) 323 (make-local-variable 'indent-line-function)
314 (make-local-variable 'paragraph-start) 324 (make-local-variable 'paragraph-start)
315 (make-local-variable 'paragraph-separate) 325 (make-local-variable 'paragraph-separate)
@@ -318,25 +328,13 @@ varables of same name)."
318 (make-local-variable 'comment-start) 328 (make-local-variable 'comment-start)
319 (make-local-variable 'comment-end) 329 (make-local-variable 'comment-end)
320 (make-local-variable 'comment-indent-function) 330 (make-local-variable 'comment-indent-function)
321 (make-local-variable 'comment-indent-function)
322 (make-local-variable 'sgml-tags-invisible)
323 (make-local-variable 'skeleton-transformation) 331 (make-local-variable 'skeleton-transformation)
324 (make-local-variable 'skeleton-further-elements) 332 (make-local-variable 'skeleton-further-elements)
325 (make-local-variable 'skeleton-end-hook) 333 (make-local-variable 'skeleton-end-hook)
326 (make-local-variable 'font-lock-defaults) 334 (make-local-variable 'font-lock-defaults)
327 (make-local-variable 'sgml-font-lock-keywords-1)
328 (make-local-variable 'sgml-font-lock-keywords-2)
329 (make-local-variable 'facemenu-add-face-function) 335 (make-local-variable 'facemenu-add-face-function)
330 (make-local-variable 'facemenu-end-add-face) 336 (make-local-variable 'facemenu-end-add-face)
331 ;;(make-local-variable 'facemenu-remove-face-function) 337 ;;(make-local-variable 'facemenu-remove-face-function)
332 (and sgml-tag-face-alist
333 (not (assq 1 sgml-tag-face-alist))
334 (nconc sgml-tag-face-alist
335 `((1 (,(concat "<\\("
336 (mapconcat 'car sgml-tag-face-alist "\\|")
337 "\\)\\([ \t].+\\)?>\\(.+\\)</\\1>")
338 3 (cdr (assoc (downcase (match-string 1))
339 ',sgml-tag-face-alist)))))))
340 (setq indent-line-function 'indent-relative-maybe 338 (setq indent-line-function 'indent-relative-maybe
341 ;; A start or end tag by itself on a line separates a paragraph. 339 ;; A start or end tag by itself on a line separates a paragraph.
342 ;; This is desirable because SGML discards a newline that appears 340 ;; This is desirable because SGML discards a newline that appears
@@ -356,21 +354,17 @@ varables of same name)."
356 (not (or (eq v2 '\n) 354 (not (or (eq v2 '\n)
357 (eq (car-safe v2) '\n))) 355 (eq (car-safe v2) '\n)))
358 (newline-and-indent))) 356 (newline-and-indent)))
359 sgml-font-lock-keywords-2 (append
360 sgml-font-lock-keywords-1
361 (cdr (assq 1 sgml-tag-face-alist)))
362 font-lock-defaults '((sgml-font-lock-keywords 357 font-lock-defaults '((sgml-font-lock-keywords
363 sgml-font-lock-keywords-1 358 sgml-font-lock-keywords-1
364 sgml-font-lock-keywords-2) 359 sgml-font-lock-keywords-2)
365 nil 360 nil t nil nil
366 t) 361 (font-lock-syntactic-keywords
362 . sgml-font-lock-syntactic-keywords))
367 facemenu-add-face-function 'sgml-mode-facemenu-add-face-function) 363 facemenu-add-face-function 'sgml-mode-facemenu-add-face-function)
368 ;; This will allow existing comments within declarations to be 364 ;; This will allow existing comments within declarations to be
369 ;; recognized. 365 ;; recognized.
370 (set (make-local-variable 'comment-start-skip) "\\(?:<!\\)?--[ \t]*") 366 (set (make-local-variable 'comment-start-skip) "\\(?:<!\\)?--[ \t]*")
371 (set (make-local-variable 'comment-end-skip) "[ \t]*--\\([ \t\n]*>\\)?") 367 (set (make-local-variable 'comment-end-skip) "[ \t]*--\\([ \t\n]*>\\)?"))
372 (dolist (pair sgml-display-text)
373 (put (car pair) 'before-string (cdr pair))))
374 368
375 369
376(defun sgml-mode-facemenu-add-face-function (face end) 370(defun sgml-mode-facemenu-add-face-function (face end)
@@ -383,7 +377,7 @@ varables of same name)."
383 377
384 378
385;;;###autoload 379;;;###autoload
386(defun sgml-mode () 380(define-derived-mode sgml-mode text-mode "SGML"
387 "Major mode for editing SGML documents. 381 "Major mode for editing SGML documents.
388Makes > match <. Makes / blink matching /. 382Makes > match <. Makes / blink matching /.
389Keys <, &, SPC within <>, \" and ' can be electric depending on 383Keys <, &, SPC within <>, \" and ' can be electric depending on
@@ -401,18 +395,12 @@ Use \\[sgml-validate] to validate your document with an SGML parser.
401Do \\[describe-variable] sgml- SPC to see available variables. 395Do \\[describe-variable] sgml- SPC to see available variables.
402Do \\[describe-key] on the following bindings to discover what they do. 396Do \\[describe-key] on the following bindings to discover what they do.
403\\{sgml-mode-map}" 397\\{sgml-mode-map}"
404 (interactive) 398 (sgml-mode-common)
405 (kill-all-local-variables)
406 (setq mode-name "SGML"
407 major-mode 'sgml-mode)
408 (sgml-mode-common sgml-tag-face-alist sgml-display-text)
409 ;; Set imenu-generic-expression here, rather than in sgml-mode-common, 399 ;; Set imenu-generic-expression here, rather than in sgml-mode-common,
410 ;; because this definition probably is not useful in HTML mode. 400 ;; because this definition probably is not useful in HTML mode.
411 (make-local-variable 'imenu-generic-expression) 401 (make-local-variable 'imenu-generic-expression)
412 (setq imenu-generic-expression 402 (setq imenu-generic-expression
413 "<!\\(element\\|entity\\)[ \t\n]+%?[ \t\n]*\\([A-Za-z][-A-Za-z.0-9]*\\)") 403 "<!\\(element\\|entity\\)[ \t\n]+%?[ \t\n]*\\([A-Za-z][-A-Za-z.0-9]*\\)"))
414 (use-local-map sgml-mode-map)
415 (run-hooks 'text-mode-hook 'sgml-mode-hook))
416 404
417 405
418(defun sgml-comment-indent () 406(defun sgml-comment-indent ()
@@ -747,8 +735,9 @@ With prefix argument ARG, repeat this ARG times."
747 (buffer-file-name nil) 735 (buffer-file-name nil)
748 ;; This is needed in case font lock gets called, 736 ;; This is needed in case font lock gets called,
749 ;; since it moves point and might call sgml-point-entered. 737 ;; since it moves point and might call sgml-point-entered.
738 ;; How could it get called? -stef
750 (inhibit-point-motion-hooks t) 739 (inhibit-point-motion-hooks t)
751 symbol) 740 string)
752 (unwind-protect 741 (unwind-protect
753 (save-excursion 742 (save-excursion
754 (goto-char (point-min)) 743 (goto-char (point-min))
@@ -758,21 +747,22 @@ With prefix argument ARG, repeat this ARG times."
758 (not sgml-tags-invisible))) 747 (not sgml-tags-invisible)))
759 (while (re-search-forward "<\\([!/?A-Za-z][-A-Za-z0-9]*\\)" 748 (while (re-search-forward "<\\([!/?A-Za-z][-A-Za-z0-9]*\\)"
760 nil t) 749 nil t)
761 (setq symbol (intern-soft (downcase (match-string 1)))) 750 (setq string
751 (cdr (assq (intern-soft (downcase (match-string 1)))
752 sgml-display-text)))
762 (goto-char (match-beginning 0)) 753 (goto-char (match-beginning 0))
763 (and (get symbol 'before-string) 754 (and (stringp string)
764 (not (overlays-at (point))) 755 (not (overlays-at (point)))
765 (overlay-put (make-overlay (point) 756 (overlay-put (make-overlay (point)
766 (match-beginning 1)) 757 (match-beginning 1))
767 'category symbol)) 758 'before-string string))
768 (put-text-property (point) 759 (put-text-property (point)
769 (progn (forward-list) (point)) 760 (progn (forward-list) (point))
770 'category 'sgml-tag)) 761 'category 'sgml-tag))
771 (let ((pos (point))) 762 (let ((pos (point-min)))
772 (while (< (setq pos (next-overlay-change pos)) (point-max)) 763 (while (< (setq pos (next-overlay-change pos)) (point-max))
773 (delete-overlay (car (overlays-at pos))))) 764 (delete-overlay (car (overlays-at pos)))))
774 (remove-text-properties (point-min) (point-max) 765 (remove-text-properties (point-min) (point-max) '(category nil))))
775 '(category sgml-tag intangible t))))
776 (restore-buffer-modified-p modified)) 766 (restore-buffer-modified-p modified))
777 (run-hooks 'sgml-tags-invisible-hook) 767 (run-hooks 'sgml-tags-invisible-hook)
778 (message ""))) 768 (message "")))
@@ -854,6 +844,22 @@ See `sgml-tag-alist' for info about attributerules.."
854 (if alist 844 (if alist
855 (insert (skeleton-read '(completing-read "Value: " alist)))) 845 (insert (skeleton-read '(completing-read "Value: " alist))))
856 (insert ?\")))) 846 (insert ?\"))))
847
848(defun sgml-quote (start end &optional unquotep)
849 "Quote SGML text in region.
850With prefix argument, unquote the region."
851 (interactive "r\np")
852 (if (< start end)
853 (goto-char start)
854 (goto-char end)
855 (setq end start))
856 (if unquotep
857 (while (re-search-forward "&\\(amp\\|\\(l\\|\\(g\\)\\)t\\);" end t)
858 (replace-match (if (match-end 3) ">" (if (match-end 2) "<" "&"))))
859 (while (re-search-forward "[&<>]" end t)
860 (replace-match (cdr (assq (char-before) '((?& . "&amp;")
861 (?< . "&lt;")
862 (?> . "&gt;"))))))))
857 863
858 864
859;;; HTML mode 865;;; HTML mode
@@ -1098,7 +1104,17 @@ This takes effect when first loading the library.")
1098 ("s") 1104 ("s")
1099 ("samp") 1105 ("samp")
1100 ("small") 1106 ("small")
1101 ("span") 1107 ("span" nil
1108 ("class"
1109 ("builtin")
1110 ("comment")
1111 ("constant")
1112 ("function-name")
1113 ("keyword")
1114 ("string")
1115 ("type")
1116 ("variable-name")
1117 ("warning")))
1102 ("strong") 1118 ("strong")
1103 ("sub") 1119 ("sub")
1104 ("sup") 1120 ("sup")
@@ -1202,7 +1218,7 @@ This takes effect when first loading the library.")
1202"*Value of `sgml-tag-help' for HTML mode.") 1218"*Value of `sgml-tag-help' for HTML mode.")
1203 1219
1204;;;###autoload 1220;;;###autoload
1205(defun html-mode () 1221(define-derived-mode html-mode sgml-mode "HTML"
1206 "Major mode based on SGML mode for editing HTML documents. 1222 "Major mode based on SGML mode for editing HTML documents.
1207This allows inserting skeleton constructs used in hypertext documents with 1223This allows inserting skeleton constructs used in hypertext documents with
1208completion. See below for an introduction to HTML. Use 1224completion. See below for an introduction to HTML. Use
@@ -1238,12 +1254,8 @@ To work around that, do:
1238 (eval-after-load \"sgml-mode\" '(aset sgml-char-names ?' nil)) 1254 (eval-after-load \"sgml-mode\" '(aset sgml-char-names ?' nil))
1239 1255
1240\\{html-mode-map}" 1256\\{html-mode-map}"
1241 (interactive) 1257 (set (make-local-variable 'sgml-display-text) html-display-text)
1242 (kill-all-local-variables) 1258 (set (make-local-variable 'sgml-tag-face-alist) html-tag-face-alist)
1243 (setq mode-name "HTML"
1244 major-mode 'html-mode)
1245 (sgml-mode-common html-tag-face-alist html-display-text)
1246 (use-local-map html-mode-map)
1247 (make-local-variable 'sgml-tag-alist) 1259 (make-local-variable 'sgml-tag-alist)
1248 (make-local-variable 'sgml-face-tag-alist) 1260 (make-local-variable 'sgml-face-tag-alist)
1249 (make-local-variable 'sgml-tag-help) 1261 (make-local-variable 'sgml-tag-help)
@@ -1254,8 +1266,7 @@ To work around that, do:
1254 (setq sentence-end 1266 (setq sentence-end
1255 (if sentence-end-double-space 1267 (if sentence-end-double-space
1256 "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\| $\\|\t\\| \\)[ \t\n]*" 1268 "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\| $\\|\t\\| \\)[ \t\n]*"
1257 1269 "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\|[ \t]\\)[ \t\n]*"))
1258 "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\| \\|\t\\)[ \t\n]*"))
1259 (setq sgml-tag-alist html-tag-alist 1270 (setq sgml-tag-alist html-tag-alist
1260 sgml-face-tag-alist html-face-tag-alist 1271 sgml-face-tag-alist html-face-tag-alist
1261 sgml-tag-help html-tag-help 1272 sgml-tag-help html-tag-help
@@ -1267,7 +1278,7 @@ To work around that, do:
1267 ;; It's for the user to decide if it defeats it or not -stef 1278 ;; It's for the user to decide if it defeats it or not -stef
1268 ;; (make-local-variable 'imenu-sort-function) 1279 ;; (make-local-variable 'imenu-sort-function)
1269 ;; (setq imenu-sort-function nil) ; sorting the menu defeats the purpose 1280 ;; (setq imenu-sort-function nil) ; sorting the menu defeats the purpose
1270 (run-hooks 'text-mode-hook 'sgml-mode-hook 'html-mode-hook)) 1281 )
1271 1282
1272(defvar html-imenu-regexp 1283(defvar html-imenu-regexp
1273 "\\s-*<h\\([1-9]\\)[^\n<>]*>\\(<[^\n<>]*>\\)*\\s-*\\([^\n<>]*\\)" 1284 "\\s-*<h\\([1-9]\\)[^\n<>]*>\\(<[^\n<>]*>\\)*\\s-*\\([^\n<>]*\\)"