the following functions are used to close whatever tag
we're in. i'm just going to post the code in the
description, because i keep it in my .emacs file and
i'm not sure where it would go in the actual xslide
code (i wrote it long before xslide moved to
sourceforge and figured i'd share it now).
(defun my:xsl-insert-end-tag ()
"Close the last open tag."
(interactive)
(let ((last-tag (save-excursion
(my:xsl-find-last-open-tag (point)))))
(cond (last-tag
(insert-string (concat "</" last-tag ">"))
(xsl-electric-tab))
(t (error "There is no open tag in the buffer")))))
(defun my:xsl-find-last-open-tag (starting-point)
"Find the last opened tag and print the proper close
tag."
;; find the last unclosed tag
;;
;; \1 is the whole element name with namespace
;; \2 is the entire namespace prefix (including the
colon)
;; \3 is the prefix (minus the colon)
;; \4 is the element name (minus the namespace prefix)
(let ((sl (string-to-char "/"))
(re-for-element
"\\(\\(\\(\\sw\\|\\s_\\)+:\\)?\\(\\sw\\|\\s_\\)+\\)")
(re-shell "<%s%s\\s_*[^>]*>"))
(when (re-search-backward (format re-shell ""
re-for-element) nil t)
;; if this tag is ended (either self-ending or by
having an end
;; tag, try again
(let ((beg (point))
(el (match-string 1)))
(cond ((= (char-before (1- (match-end 0))) sl)
(my:xsl-find-last-open-tag starting-point))
((let (stack)
(while (re-search-forward
(format re-shell "\\(/?\\)" re-for-element)
starting-point t)
;; skip self closing tags
(when (not (= (char-before (1- (match-end 0))) sl))
(if (= 0 (length (match-string 1)))
;; a start tag, add it to the stack
(push (match-string 2) stack)
;; an end tag, pop the stack. i don't think
;; one needs check to see if this is the same
;; tag as we're popping 'cause if it's not,
;; we'll insert a wrong tag, which will be a
;; clue to the caller that they have bad data.
;; also no need to check if there's anything on
;; the stack, because we always add the tag
;; we're on first.
(pop stack))))
;; if the stack has stuff, return the pop
(if stack
(pop stack)
;; or find more open tags
(goto-char beg)
(my:xsl-find-last-open-tag starting-point))))
(t
el))))))