Function: hui-select-markup-pair

hui-select-markup-pair is a byte-compiled function defined in hui-select.el.

Signature

(hui-select-markup-pair POS)

Documentation

Return (start . end) of region of markup pair, one of which is at POS.

The region returned is between the opening and closing tag. Markups recognised are HTML, XML or SGML tag pairs. The major mode for each language that uses such tags must be included in the list, hui-select-markup-modes.

Source Code

;; Defined in ~/.emacs.d/elpa/hyperbole-20260414.325/hui-select.el
(defun hui-select-markup-pair (pos)
  "Return (start . end) of region of markup pair, one of which is at POS.
The region returned is between the opening and closing tag.
Markups recognised are HTML, XML or SGML tag pairs.  The major
mode for each language that uses such tags must be included in
the list, hui-select-markup-modes."
  (when (memq major-mode hui-select-markup-modes)
    (setq hui-select-previous 'markup-pair)
    (let ((pos-with-space)
	  ;; Assume case of tag names is irrelevant.
	  (case-fold-search t)
	  (result)
	  start-regexp
	  end-regexp
	  bolp
	  opoint)
      (save-excursion
        (setq result
	      (catch 'done
                (goto-char pos)
                (cond
                 ;; Beginning of a tag pair
                 ((looking-at "<[^/][^<> \t\n\r]*")
                  (setq start-regexp (regexp-quote (match-string 0))
                        end-regexp   (concat "</" (substring start-regexp 1)))
                  (setq pos (point))
                  (skip-chars-backward " \t")
                  (setq bolp (bolp)
                        pos-with-space (point))
                  ;; Skip over nested tags.
                  (let ((count 0)
                        (regexp (concat start-regexp "\\|" end-regexp)))
                    (while (and (>= count 0)
                                (re-search-forward regexp nil t))
		      (if (/= (char-after (1+ (match-beginning 0))) ?/)
                          ;; Start tag
                          (setq count (1+ count))
                        ;; Move past end tag terminator
                        (setq opoint (point))
                        (when (or (not (re-search-forward "[<>]" nil t))
                                  (= (preceding-char) ?<))
			  (throw 'done opoint))
                        (setq count (1- count))
                        (when (= count 0)
                          (cond ((smart-eobp)
                                 (if bolp
				     ;; Include leading space since the
				     ;; start and end tags begin and end
				     ;; lines.
				     (setq pos pos-with-space)
                                   (goto-char (1- (point)))))
                                ((looking-at "[ \t]*[\n\r]")
                                 ;; Don't include final newline unless the
                                 ;; start tag was the first thing on its line.
                                 (if bolp
				     (progn (goto-char (match-end 0))
                                            ;; Include leading space since the
                                            ;; start and end tags begin and end
                                            ;; lines.
                                            (setq pos pos-with-space))
                                   (goto-char (1- (match-end 0))))))
			  (throw 'done (hui-select-set-region pos (point))))))))
                 ;;
                 ;; End of a tag pair
                 ((or (looking-at "</[^\> \t\n\r]+")
		      (and (skip-chars-backward "\<")
                           (looking-at "</[^\> \t\n\r]+")))
                  (goto-char (match-end 0))
                  (setq end-regexp (regexp-quote (match-string 0))
                        start-regexp   (concat "\<" (substring end-regexp 2))
                        opoint (point))
                  (when (or (not (re-search-forward "[<>]" nil t))
                            (= (preceding-char) ?<))
		    (throw 'done opoint))
                  (setq pos (point))
                  (when (looking-at "[ \t]*[\n\r]")
		    (setq pos-with-space (match-end 0)))
                  ;; Skip over nested tags.
                  (let ((count 0)
                        (regexp (concat start-regexp "\\|" end-regexp)))
                    (while (and (>= count 0)
                                (re-search-backward regexp nil t))
		      (if (= (char-after (1+ (point))) ?/)
                          ;; End tag
                          (setq count (1+ count))
                        ;; Start tag
                        (setq count (1- count))
                        (when (= count 0)
			  (when pos-with-space
			    ;; Newline found after original end tag.
			    (skip-chars-backward " \t")
			    (if (bolp)
				;; Don't include final newline unless the
				;; start tag is the first thing on its line.
				(setq pos pos-with-space)
			      (setq pos (1- pos-with-space))
			      ;; Don't include non-leading space.
			      (skip-chars-forward " \t")))
			  (throw 'done (hui-select-set-region (point) pos)))))))))))
      (if (integerp result)
	  (progn (goto-char result)
		 (error "(hui-select-markup-pair): Add a terminator character for this end tag"))
	result))))