I became annoyed at how, when pressing M-Q (fill-paragraph) while in a block like this:
#+CAPTION: This is a really long caption that I need #+CAPTION: to describe my table in excruciating and unnecessary detail Org takes no account of the #+ directives and simply smooshes all the lines together like this: #+CAPTION: This is a really long caption that I need +CAPTION: to describe my #table in excruciating and unnecessary detail So I wrote the following function. I have it bound to M-q in org-mode. Its behaviour: 1. It wraps a series of #+CAPTION lines as if the caption directives are not there -- ie it turns the above example into: #+CAPTION: This is a really long caption that I need to describe my table in #+CAPTION: excruciating and unnecessary detail 2. It ignores other #+XXX: directives, ie no filling is performed. 3. In every other context it behaves as 'fill-paragraph'. -------- (defun org-smart-wrap (&optional width) (interactive) (let ((lines nil) (width (or width (- fill-column 11))) (start nil) (end nil)) (save-match-data (cond ((and (eql major-mode 'org-mode) (save-excursion (beginning-of-line) (looking-at "#\\+\\([A-Za-z0-9_]+\\):"))) (cond ((not (string-equal (match-string 1) "CAPTION")) (message "`#+%s' directive found, fill command ignored." (substring-no-properties (match-string 1)))) (t ;; Wrap caption. (save-excursion (while (line-starts-with-p "#\\+CAPTION:") (forward-line -1)) (unless (line-starts-with-p "#\\+CAPTION:") (forward-line)) (setf start (point)) (while (line-starts-with-p "#\\+CAPTION:") (beginning-of-line) (search-forward "#+CAPTION:" (end-of-line-pos) t) (push (org-trim (buffer-substring-no-properties (point) (end-of-line-pos))) lines) (forward-line)) (beginning-of-line) (setf end (point)) (setf lines (mapcar (lambda (line) (concat "#+CAPTION: " line)) (org-wrap (apply 'concat (mapcar (lambda (line) (concat line " ")) (reverse lines))) width))) (delete-region start end) (dolist (line lines) (insert line) (newline)))))) (t (fill-paragraph))))))