Function: org-table-align

org-table-align is an interactive and byte-compiled function defined in org-table.el.gz.

Signature

(org-table-align)

Documentation

Align the table at point by aligning all vertical bars.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-table.el.gz
(defun org-table-align ()
  "Align the table at point by aligning all vertical bars."
  (interactive)
  (let ((beg (org-table-begin))
	(end (copy-marker (org-table-end))))
    (org-table-save-field
     ;; Make sure invisible characters in the table are at the right
     ;; place since column widths take them into account.
     (font-lock-ensure beg end)
     (move-marker org-table-aligned-begin-marker beg)
     (move-marker org-table-aligned-end-marker end)
     (goto-char beg)
     (org-table-with-shrunk-columns
      (let* ((table (org-table-to-lisp))
             (rows (remq 'hline table))
	     (widths nil)
	     (alignments nil)
	     (columns-number 1)
             (invisibility-spec (org-string-width-invisibility-spec))
             (cell-width-cache (make-hash-table :test 'equal))
             (get-or-compute-cell-width
              (lambda (cell)
                (or (gethash cell cell-width-cache)
                    (puthash
                     cell
                     (org-string-width cell nil 'org-table invisibility-spec)
                     cell-width-cache)))))
	(if (null rows)
	    ;; Table contains only horizontal rules.  Compute the
	    ;; number of columns anyway, and choose an arbitrary width
	    ;; and alignment.
	    (let ((end (line-end-position)))
	      (save-excursion
		(while (search-forward "+" end t)
		  (cl-incf columns-number)))
	      (setq widths (make-list columns-number 1))
	      (setq alignments (make-list columns-number "l")))
	  ;; Compute alignment and width for each column.
	  (setq columns-number (apply #'max (mapcar #'length rows)))
	  (dotimes (i columns-number)
	    (let ((max-width 1)
		  (fixed-align? nil)
		  (numbers 0)
		  (non-empty 0))
	      (dolist (row rows)
		(let ((cell (or (nth i row) "")))
		  (setq max-width (max max-width (funcall get-or-compute-cell-width cell)))
		  (cond (fixed-align? nil)
			((equal cell "") nil)
			((string-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
			 (setq fixed-align? (match-string 1 cell)))
			(t
			 (cl-incf non-empty)
			 (when (string-match-p org-table-number-regexp cell)
			   (cl-incf numbers))))))
	      (push max-width widths)
	      (push (cond
		     (fixed-align?)
		     ((>= numbers (* org-table-number-fraction non-empty)) "r")
		     (t "l"))
		    alignments)))
	  (setq widths (nreverse widths))
	  (setq alignments (nreverse alignments)))
	;; Store alignment of this table, for later editing of single
	;; fields.
	(setq org-table-last-alignment alignments)
	(setq org-table-last-column-widths widths)
	;; Build new table rows.  Only replace rows that actually
	;; changed.
        (org-fold-core-ignore-modifications
          (org-combine-change-calls beg end
	    (let ((rule (and (memq 'hline table)
			     (mapconcat (lambda (w) (make-string (+ 2 w) ?-))
                                        widths
                                        "+")))
                  (indent (progn (looking-at "[ \t]*|") (match-string 0))))
	      (dolist (row table)
                (let ((previous (buffer-substring (point) (line-end-position)))
		      (new
                       (concat indent
                               (if (eq row 'hline) rule
                                 (let* ((offset (- columns-number (length row)))
                                        (fields (if (= 0 offset) row
                                                  ;; Add missing fields.
                                                  (append row
                                                          (make-list offset "")))))
                                   (mapconcat #'identity
                                              (cl-mapcar
                                               (lambda (field width alignment)
                                                 (org-table--align-field
                                                  field
                                                  width
                                                  alignment
                                                  (funcall get-or-compute-cell-width field)))
					       fields
					       widths
					       alignments)
                                              "|")))
                               "|")))
                  (if (equal new previous)
		      (forward-line)
		    (insert new "\n")
		    (delete-region (point) (line-beginning-position 2))))))))
	(set-marker end nil)
	(when org-table-overlay-coordinates (org-table-overlay-coordinates))
	(setq org-table-may-need-update nil))))))