I want to replace words like 1st with 1^{st} and 102nd with 102^{nd} while typing in emacs. Basically I want to replace things that match this:


with this \1^{\2} as I type.

It seems like an abbrev might work for this, but it does not appear you can put a regexp as the name.

The best I have come up with is

(defun org-ordinal-expansion ()
  (and (= ?w (char-syntax (char-before)))
         (and (skip-syntax-backward "w")
          (let (case-fold-search)
        (looking-at "\\([0-9]+\\)\\(st\\|nd\\|rd\\|th\\)"))
          (replace-match "\\1^{\\2}")))))

(define-minor-mode ordinal-mode
  "Toggle `ordinal-mode'.  Converst 1st to 1^{st} as you type."
  :init-value nil
  :lighter (" om")
  (if ordinal-mode
      (add-hook 'post-self-insert-hook #'org-ordinal-expansion nil 'local)
    (remove-hook 'post-self-insert-hook #'org-ordinal-expansion 'local)))

Is there some more elegant way to achieve this that doesn't rely on the post-self-insert-hook?

  • Not more elegant but another way to do what you want might be to add a function that does the conversion to write-file-functions so that it happens every time you save the file. At least then you'd be to use a single regexp search and replace. – stevoooo Apr 10 '17 at 19:03
  • That could also be done in a before-save-hook. I really want it to work as I type though. I guess even an abbrev basically has to do the check I do above, so it probably isn't too far off. – John Kitchin Apr 10 '17 at 22:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.