Emacs: Twitterfy 📜

By Xah Lee. Date: . Last updated: .

Here's a emacs lisp command that shortens text to fit twitter's 140 chars.

put this in your Emacs Init File:

(defun xah-twitterfy ()
  "Shorten words for Twitter 280 char limit on current line or selection.

If `universal-argument' is called first, ask for conversion direction (shorten/lenthen).

Note: calling this function twice in opposite direction does not necessarily return the origial, because the map is not one-to-one.

URL `http://xahlee.info/emacs/emacs/elisp_twitterfy.html'
Created: 2019-03-02
Version: 2025-03-25"
  (interactive)
  (let (xbeg xend xdirection
            (xabbrevMap
             [
              ["\\bare\\b" "r"]
              ["\\byou\\b" "u"]
              ["e.g. " "eg "]
              ["\bto\b" "2"]
              [" your" " ur "]
              ["\\band\\b" "&"]
              ["\\bbecause\\b" "∵"]
              ["\\bcuz\\b" "∵"]
              ["therefore " "∴"]
              [" at " " @ "]
              [" love " " ♥ "]
              [" one " " 1 "]
              [" two " " 2 "]
              [" three " " 3 "]
              [" four " " 4 "]
              [" zero " " 0 "]
              ["hexadecimal " "hex "]
              ["Emacs: " "#emacs "]
              ["JavaScript: " "#JavaScript "]
              ["Python: " "#python "]
              ["Ruby: " "#ruby "]
              ["Perl: " "#perl "]
              ["Emacs Lisp: " "#emacs #lisp "]
              ["Elisp: " "#emacs #lisp "]
              [", " ","]
              ["\\.\\.\\." "…"]
              ["\\. " "。"]
              ["\\? " "?"]
              [": " ":"]
              ["! " "!"]]
             )
            (xreverseMap
             [
              ["\\bu\\b" "you"]
              ["\\br\\b" "are"]
              ["eg " "e.g. "]
              [" 2 " " to "]
              ["\\bur\\b" "your"]
              ["\\b&\\b" "and"]
              ["\\bcuz\\b" "because"]
              ["\\b∴\\b" "therefore "]
              [" @ " " at "]
              [" ♥ " " love "]
              [" 1 " " one "]
              [" 2 " " two "]
              [" 3 " " three "]
              [" 4 " " four "]
              [" 0 " " zero "]
              ["hex " "hexadecimal "]
              ["," ", "]
              ["…" "..."]
              ["。" ". "]
              ["?" "? "]
              [":" ": "]
              ["!" "! "]
              ]
             ))
    (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
    (setq xdirection
          (if current-prefix-arg
              (completing-read "Direction: " '("shorten" "lengthen") nil t)
            "auto"
            ))
    (save-restriction
      (narrow-to-region xbeg xend)
      (when (string-equal xdirection "auto")
        (goto-char (point-min))
        (setq xdirection
              (if (re-search-forward "。\\|,\\|?\\|!" nil t)
                  "lengthen" "shorten"
                  )))
      (let ((case-fold-search nil))
        (mapc
         (lambda (xx)
           (goto-char (point-min))
           (while (re-search-forward (elt xx 0) nil t)
             (replace-match (elt xx 1) t t)))
         (if (string-equal xdirection "shorten")
             xabbrevMap
           xreverseMap))
        (goto-char (point-min))
        (while (re-search-forward "  +" nil t)
          (replace-match " " t t)))
      (goto-char (+ (point-min) 280)))))