I am new to the Org API and I would be glad if you could give a look to the code and share some comments.
As for the proposed solution, consider the following table:
|---+--------------------------------+---|
| 1 | one | a |
| 2 | two | b |
| 3 | This is a long chunk of text | c |
| 4 | four | d |
| 5 | Yet another long chunk of text | e |
|---+--------------------------------+---|
Put the cursor anywhere in the second column and type:
M-x org-table-wrap-to-width
Enter a column width as requested. E.g., entering 15
, you get:
|---+----------------+---|
| 1 | one | a |
| 2 | two | b |
| 3 | This is a long | c |
| | chunk of text | |
| 4 | four | d |
| 5 | Yet another | e |
| | long chunk of | |
| | text | |
|---+----------------+---|
If you are dissatisfied with this width and want to try a different value, use the Emacs standard undo, which will restore the previous layout, so you can rerun the wrap function.
Here's the code. If you know Org, please, give feedback.
(defun org-table-wrap-to-width (width)
"Wrap current column to WIDTH."
(interactive (list (read-number "Enter column width: ")))
(org-table-check-inside-data-field)
(org-table-align)
(let (cline (ccol (org-table-current-column)) new-row-count (more t))
(org-table-goto-line 1)
(org-table-goto-column ccol)
(while more
(setq cline (org-table-current-line))
;; Cut current field
(org-table-copy-region (point) (point) 'cut)
;; Justify for width
(setq org-table-clip
(mapcar 'list (org-wrap (caar org-table-clip) width nil)))
;; Add new lines and fill
(setq new-row-count (1- (length org-table-clip)))
(if (> new-row-count 0)
(org-table-insert-n-row-below new-row-count))
(org-table-goto-line cline)
(org-table-goto-column ccol)
(org-table-paste-rectangle)
(org-table-goto-line (+ cline new-row-count))
;; Move to next line
(setq more (org-table-goto-line (+ cline new-row-count 1)))
(org-table-goto-column ccol))
(org-table-goto-line 1)
(org-table-goto-column ccol)))
(defun org-table-insert-n-row-below (n)
"Insert N new lines below the current."
(let* ((line (buffer-substring (point-at-bol) (point-at-eol)))
(new (org-table-clean-line line)))
;; Fix the first field if necessary
(if (string-match "^[ \t]*| *[#$] *|" line)
(setq new (replace-match (match-string 0 line) t t new)))
(beginning-of-line 2)
(setq new
(apply 'concat (make-list n (concat new "\n"))))
(let (org-table-may-need-update) (insert-before-markers new)) ;;; remove?
(beginning-of-line 0)
(re-search-forward "| ?" (point-at-eol) t)
(and (or org-table-may-need-update org-table-overlay-coordinates) ;;; remove?
(org-table-align))
(org-table-fix-formulas "@" nil (1- (org-table-current-dline)) n)))
org-table
would easily be amended, though.