5

I'm trying to build a function but having trouble with the regex. Specifically, I want to match capital letters only.

This function is supposed to capitalize words that are in lowercase (theThe) but not touch words that are already in uppercase (like #+STARTUP: or * TODO).

(defun capitalize-unless-org-heading ()
  (interactive)
(unless 
(or
(looking-at "\*")
(looking-at "[\n\t ]*\\*") ; don't capitalize an org heading
(looking-at "* TODO") ; don't capitalize an org todo heading
(looking-at "[\n\t\ ]*#+") ; don't capitalize org options like #+STARTUP:
(looking-at "[\n\t\ *[A-Z]") ; don't capitalize any word that might be all uppercase
)
(capitalize-word 1))
)

If it matters, case-fold-search is set to t so I can search for text in my buffers without worrying about case. How do I build a regex to search for uppercase letters only?

incandescentman
  • 4,111
  • 16
  • 53

2 Answers2

6

You can temporarily bind case-fold-search using let:

(let ((case-fold-search nil))
  (looking-at "[\n\t ]*[A-Z]"))

Also, I changed your regexp for matching whitespace and newlines -- a ] was missing and you don't need the backslash before the space.

Here is the corrected code, also incorporating Zorgoth's edits below.

(defun capitalize-unless-org-heading ()
  (interactive)
  (unless (or
            (looking-at "[\n\t ]*\\*")
            (let ((case-fold-search nil))
              (looking-at "[\n\t ]*[A-Z]")) 
            (looking-at "[\n\t ]*#\\+")) 
    (capitalize-word 1)))
Lindydancer
  • 6,095
  • 1
  • 13
  • 25
2

Be aware that there are some mistakes in that code. I don't know if \* means anything at all in this context (\\* does). You also need to escape + with two backslashes as that has a meaning in emacs regexps. And there is a * at the beginning of a string that I presume was intended to be after a space.

Apart from that, the answer above answers the main question you had.

If you wanted a more general way of getting to the next word for other purposes you could use [^A-Za-z]* to see past all non-letters.

Zorgoth
  • 810
  • 6
  • 14
  • Thank you! Is this correct now? `(defun capitalize-unless-org-heading () (interactive) (unless (or (looking-at "[\n\t ]\\*") (let ((case-fold-search nil)) (looking-at "[\n\t ]*[A-Z]")) (looking-at "[\n\t ]*#\\+") ) (capitalize-word 1)) )` – incandescentman Dec 09 '15 at 01:21
  • 1
    There is a `*` missing after the first `[\n\t ]` group, which mean that you will only match exactly one whitespace character. – Lindydancer Dec 09 '15 at 08:00