I wrote this for you; he did not have rigorous testing, but he seems to be doing what you are looking for.
The logic behind it is to sort out all the characters in the text. If the character is equal to a lowercase character, add it to the return string in upper case. If not, add it to lowercase. At the end, delete the region and insert the returned row.
It works right on the text page, although I would use it with caution on huge texts (it must be all the same).
(defun toggle-case () (interactive) (when (region-active-p) (let ((i 0) (return-string "") (input (buffer-substring-no-properties (region-beginning) (region-end)))) (while (< i (- (region-end) (region-beginning))) (let ((current-char (substring input i (+ i 1)))) (if (string= (substring input i (+ i 1)) (downcase (substring input i (+ i 1)))) (setq return-string (concat return-string (upcase (substring input i (+ i 1))))) (setq return-string (concat return-string (downcase (substring input i (+ i 1))))))) (setq i (+ i 1))) (delete-region (region-beginning) (region-end)) (insert return-string))))
source share