Looking at this page it seems title-capitals can get reasonably involved. Do packages exist that perform title-caps with support for some of these rules?
Asked
Active
Viewed 251 times
2 Answers
3
This is a short function that does basic title-capitals:
- Some words aren't capitalized (
the
,of
, ... etc). - The 1st word is always capitalized.
- Existing capitalized words are left unchanged (typically acronyms, e.g.
CPU
,API
,FIFO
.. etc). - Characters such as (
\
-
'
.
) prevent the next letter from being capitalized. - Without a selection it operates on the whole line.
- Colon character capitalizes the following word, even if it would normally be skipped: e.g.
Example: The Test Title
Question? The Answer
(defun my-upcase-initials-region ()
(interactive)
(let ((beg nil)
(end nil)
(prev-word-end nil)
;; Allow capitals for skip characters after this, so:
;; Warning: An Example
;; Capitalizes the `An'.
(chars-skip-reset '(?: ?! ??))
;; Don't capitalize characters directly after these. e.g.
;; "Foo-bar" or "Foo\bar" or "Foo's".
(chars-separator '(?\\ ?- ?' ?.))
(word-chars "[:alnum:]")
(word-skip
(list "a" "an" "and" "as" "at" "but" "by"
"for" "if" "in" "is" "it" "nor" "of"
"on" "or" "so" "the" "to" "up" "was" "yet"))
(is-first t))
(cond
((region-active-p)
(setq beg (region-beginning))
(setq end (region-end)))
(t
(setq beg (line-beginning-position))
(setq end (line-end-position))))
(save-excursion
(goto-char beg)
(while (< (point) end)
(setq prev-word-end (point))
(skip-chars-forward (concat "^" word-chars) end)
(let ((word-end
(save-excursion
(skip-chars-forward word-chars end)
(point))))
(unless (memq (char-before (point)) chars-separator)
(let* ((c-orig (char-to-string (char-after (point))))
(c-up (capitalize c-orig)))
(unless (string-equal c-orig c-up)
(let ((word (buffer-substring-no-properties (point) word-end)))
(when
(or
;; Always allow capitalization.
is-first
;; If it's not a skip word, allow.
(not (member word word-skip))
;; Check the beginning of the
;; previous word doesn't reset first.
(save-excursion
(and
(not (zerop (skip-chars-backward "[:blank:]" prev-word-end)))
(memq (char-before (point)) chars-skip-reset))))
(delete-region (point) (1+ (point)))
(insert c-up))))))
(goto-char word-end)
(setq is-first nil))))))

ideasman42
- 8,375
- 1
- 28
- 105