Wrap text in an org-mode block

In my most recent post on org-mode, I talked about using blocks to mark text as being latex, or source code and so on. I mentioned using the shortcuts like <e then TAB on a new line to create an empty block. Sometimes it is handy to wrap existing text in a block, and the following function does that for the text you have selected.

This has been in my config file for ages and I can’t remember where it came from – I know I didn’t write it! A bit of googleing suggests this could be the origin, but if anyone knows different, let me know.

I bind the function to C-< because it reminds me of the < shortcuts to create the blocks, and I don’t use the org-cycle-agenda-files that is usually bound to that key combo.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; function to wrap blocks of text in org templates                       ;;
;; e.g. latex or src etc                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun org-begin-template ()
  "Make a template at point."
  (interactive)
  (if (org-at-table-p)
      (call-interactively 'org-table-rotate-recalc-marks)
    (let* ((choices '(("s" . "SRC")
                      ("e" . "EXAMPLE")
                      ("q" . "QUOTE")
                      ("v" . "VERSE")
                      ("c" . "CENTER")
                      ("l" . "LaTeX")
                      ("h" . "HTML")
                      ("a" . "ASCII")))
           (key
            (key-description
             (vector
              (read-key
               (concat (propertize "Template type: " 'face 'minibuffer-prompt)
                       (mapconcat (lambda (choice)
                                    (concat (propertize (car choice) 'face 'font-lock-type-face)
                                            ": "
                                            (cdr choice)))
                                  choices
                                  ", ")))))))
      (let ((result (assoc key choices)))
        (when result
          (let ((choice (cdr result)))
            (cond
             ((region-active-p)
              (let ((start (region-beginning))
                    (end (region-end)))
                (goto-char end)
                (insert "#+END_" choice "\n")
                (goto-char start)
                (insert "#+BEGIN_" choice "\n")))
             (t
              (insert "#+BEGIN_" choice "\n")
              (save-excursion (insert "#+END_" choice))))))))))

;;bind to key
(define-key org-mode-map (kbd "C-<") 'org-begin-template)
  • NoonianAtall

    Thank you! I have wanted a function to do this so many times, but my lisp-fu is weak. 🙂 This should really be in org itself.

  • disqus_NGUkO53xWm

    thx!

    can you perhaps add a option that if no region is marked it wraps the current line is at point?

    best

    Z

    • That is a good suggestion, but not something I’ll have time to do I’m afraid!

  • Phil

    Ideally this would use `org-structure-template-alist’ to determine the key bindings and associated text.