Emacs, scripting and anything text oriented.

Converting Org keywords to lower-case

Kaushal Modi

I never quite liked the trend to have upper-cased keywords in Org documents, like #+TITLE.

So it was a pleasure to see that trend start changing in this Org commit.. so that that same keyword would now be written as #+title.

But now I have quite a few Org documents with the ALL-CAPS keywords and block identifiers. So I came up with this little “lower-case all the Org keywords and block identifiers in the current document” Elisp command:

(defun modi/lower-case-org-keywords ()
  "Lower case Org keywords and block identifiers.

Example: \"#+TITLE\" -> \"#+title\"
         \"#+BEGIN_EXAMPLE\" -> \"#+begin_example\"

    (goto-char (point-min))
    (let ((case-fold-search nil)
          (count 0))
      ;; Match examples: "#+FOO bar", "#+FOO:", "=#+FOO=", "~#+FOO~",
      ;;                 "‘#+FOO’", "“#+FOO”", ",#+FOO bar",
      ;;                 "#+FOO_bar<eol>", "#+FOO<eol>".
      (while (re-search-forward "\\(?1:#\\+[A-Z_]+\\(?:_[[:alpha:]]+\\)*\\)\\(?:[ :=~’”]\\|$\\)" nil :noerror)
        (setq count (1+ count))
        (replace-match (downcase (match-string-no-properties 1)) :fixedcase nil nil 1))
      (message "Lower-cased %d matches" count))))

Here are few examples where M-x modi/lower-case-org-keywords did hundreds of replacements for me, saving me a lot of time 😎.