Mercurial > emacs
changeset 46352:66fb3c24b4ba
(sgml-quote): Use narrowing. Improve the regexp used when unquoting.
(sgml-pretty-print): New function.
(sgml-get-context): Better handling of improperly nested tags.
(sgml-show-context): Don't use the FULL arg of sgml-get-context.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sat, 13 Jul 2002 19:23:05 +0000 |
parents | 44a2f4703942 |
children | c6a6286bc21a |
files | lisp/textmodes/sgml-mode.el |
diffstat | 1 files changed, 64 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/textmodes/sgml-mode.el Sat Jul 13 18:56:04 2002 +0000 +++ b/lisp/textmodes/sgml-mode.el Sat Jul 13 19:23:05 2002 +0000 @@ -942,20 +942,51 @@ (insert ?\")))) (defun sgml-quote (start end &optional unquotep) - "Quote SGML text in region. -With prefix argument, unquote the region." - (interactive "r\np") - (if (< start end) - (goto-char start) - (goto-char end) - (setq end start)) - (if unquotep - (while (re-search-forward "&\\(amp\\|\\(l\\|\\(g\\)\\)t\\)[;\n]" end t) - (replace-match (if (match-end 3) ">" (if (match-end 2) "<" "&")))) - (while (re-search-forward "[&<>]" end t) - (replace-match (cdr (assq (char-before) '((?& . "&") - (?< . "<") - (?> . ">")))))))) + "Quote SGML text in region START ... END. +Only &, < and > are quoted, the rest is left untouched. +With prefix argument UNQUOTEP, unquote the region." + (interactive "r\nP") + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (if unquotep + ;; FIXME: We should unquote other named character references as well. + (while (re-search-forward + "\\(&\\(amp\\|\\(l\\|\\(g\\)\\)t\\)\\)[][<>&;\n\t \"%!'(),/=?]" + nil t) + (replace-match (if (match-end 4) ">" (if (match-end 3) "<" "&")) t t + nil (if (eq (char-before (match-end 0)) ?\;) 0 1))) + (while (re-search-forward "[&<>]" nil t) + (replace-match (cdr (assq (char-before) '((?& . "&") + (?< . "<") + (?> . ">")))) + t t))))) + +(defun sgml-pretty-print (beg end) + "Simple-minded pretty printer for SGML. +Re-indents the code and inserts newlines between BEG and END. +You might want to turn on `auto-fill-mode' to get better results." + ;; TODO: + ;; - insert newline between some start-tag and text. + ;; - don't insert newline in front of some end-tags. + (interactive "r") + (save-excursion + (if (< beg end) + (goto-char beg) + (goto-char end) + (setq end beg) + (setq beg (point))) + ;; Don't use narrowing because it screws up auto-indent. + (setq end (copy-marker end t)) + (with-syntax-table sgml-tag-syntax-table + (while (re-search-forward "<" end t) + (goto-char (match-beginning 0)) + (unless (or ;;(looking-at "</") + (progn (skip-chars-backward " \t") (bolp))) + (reindent-then-newline-and-indent)) + (forward-sexp 1))) + ;; (indent-region beg end) + )) ;; Parsing @@ -1050,7 +1081,7 @@ (> (sgml-tag-end tag-info) (sgml-tag-end (car context)))) (setq context (cdr context))) - + (cond ;; start-tag @@ -1071,9 +1102,18 @@ (t ;; The open and close tags don't match. (if (not sgml-xml-mode) - ;; Assume the open tag is simply not closed. (unless (sgml-unclosed-tag-p (sgml-tag-name tag-info)) - (message "Unclosed tag <%s>" (sgml-tag-name tag-info))) + (message "Unclosed tag <%s>" (sgml-tag-name tag-info)) + (let ((tmp ignore)) + ;; We could just assume that the tag is simply not closed + ;; but it's a bad assumption when tags *are* closed but + ;; not properly nested. + (while (and (cdr tmp) + (not (eq t (compare-strings + (sgml-tag-name tag-info) nil nil + (cadr tmp) nil nil t)))) + (setq tmp (cdr tmp))) + (if (cdr tmp) (setcdr tmp (cddr tmp))))) (message "Unmatched tags <%s> and </%s>" (sgml-tag-name tag-info) (pop ignore)))))) @@ -1092,7 +1132,13 @@ If FULL is non-nil, parse back to the beginning of the buffer." (interactive "P") (with-output-to-temp-buffer "*XML Context*" - (pp (save-excursion (sgml-get-context full))))) + (save-excursion + (let ((context (sgml-get-context))) + (when full + (let ((more nil)) + (while (setq more (sgml-get-context)) + (setq context (nconc more context))))) + (pp context))))) ;; Editing shortcuts