here's a little interesting exercise.
I'm writing a toggle-letter-case function below. However, it has some
problems. (see the doc string). After thinking on this for a while,
the problem seems a bit complex. It'll take perhaps few hours to fix
these, in particular, if it is to cover chars like éÉ èÈ üÜ. Also, it
seems a good solution will require this function to have a state, but
i'm reluctant to introduce a global variable for it.
I'm wondering, if anyone have a better solution?
(defun toggle-letter-case ()
"Toggle the letter case of current word or text selection.
Toggles from 3 cases: upper case, lower case, title case,
in that order.
Title case means upcase first letter of each word.
Todo:
• this command only consider English alphabets. For example, it may
not work properly if you have éÉ èÈ üÜ.
• It may not work when the first or second letter is a number, e.g.
“1time”.
• It may not work when you only have a single letter. e.g. “A
teapot”."
(interactive)
(save-excursion
(let (pt pos1 pos2 cap1p cap2p (deactivate-mark nil) (case-fold-search
nil)
)
(setq pt (point))
(if (and transient-mark-mode mark-active)
(setq pos1 (region-beginning)
pos2 (region-end))
(setq pos1 (car (bounds-of-thing-at-point 'word))
pos2 (cdr (bounds-of-thing-at-point 'word))))
;; check 1th and 2th letters cases
(goto-char pos1)
(setq cap1p (looking-at "[A-Z]"))
(goto-char (1+ pos1))
(setq cap2p (looking-at "[A-Z]"))
(cond
((and (not cap1p) (not cap2p)) (upcase-initials-region pos1 pos2))
((and cap1p (not cap2p)) (upcase-region pos1 pos2) )
((and cap1p cap2p) (downcase-region pos1 pos2) )
(t (downcase-region pos1 pos2) )
)
)
)
)
PS the above assumes you have transient-mode on.
Xah
∑ http://xahlee.org/
☄