Function: align-areas

align-areas is a byte-compiled function defined in align.el.gz.

Signature

(align-areas AREAS PROPS RULE FUNC)

Documentation

Given a list of AREAS and formatting PROPS, align according to RULE.

AREAS should be a list of cons cells containing beginning and ending markers. This function sweeps through all of the beginning markers, finds out which one starts in the furthermost column, and then deletes and inserts text such that all of the ending markers occur in the same column.

If FUNC is non-nil, it will be called for each text region that would have been aligned. No changes will be made to the buffer.

Source Code

;; Defined in /usr/src/emacs/lisp/align.el.gz
(defun align-areas (areas props rule func)
  "Given a list of AREAS and formatting PROPS, align according to RULE.
AREAS should be a list of cons cells containing beginning and ending
markers.  This function sweeps through all of the beginning markers,
finds out which one starts in the furthermost column, and then deletes
and inserts text such that all of the ending markers occur in the same
column.

If FUNC is non-nil, it will be called for each text region that would
have been aligned.  No changes will be made to the buffer."
  (let* ((column (cdr (assq 'column rule)))
	 (fixed (if (symbolp column)
		    (symbol-value column)
		  column))
	 (justify (cdr (assq 'justify rule)))
	 (col (or fixed 0))
	 (width 0)
	 ecol change)

    ;; Determine the alignment column.
    (let ((a areas))
      (while a
	(unless fixed
	  (setq col (max col (align-column (caar a)))))
	(unless change
	  (goto-char (cdar a))
	  (if ecol
	      (if (/= ecol (current-column))
		  (setq change t))
	    (setq ecol (current-column))))
	(when justify
	  (goto-char (caar a))
	  (if (and (re-search-forward "\\s-*" (cdar a) t)
		   (/= (point) (cdar a)))
	      (let ((bcol (current-column)))
		(setcdr (car a) (cons (point-marker) (cdar a)))
		(goto-char (cdr (cdar a)))
		(setq width (max width (- (current-column) bcol))))))
	(setq a (cdr a))))

    (unless fixed
      (setq col (+ (align-adjust-col-for-rule
		    col rule (car props) (cdr props)) width)))

    ;; Make all ending positions to occur in the goal column.  Since
    ;; the whitespace to be modified was already deleted by
    ;; `align-region', all we have to do here is indent.

    (unless change
      (setq change (and ecol (/= col ecol))))

    (when (or func change)
      (while areas
	(let ((area (car areas))
	      (gocol col) cur)
	  (when area
	    (if func
		(funcall func
                         (marker-position (car area))
                         (marker-position (if (and justify
                                                   (consp (cdr area)))
                                              (cadr area)
                                            (cdr area)))
                         change)
	      (if (not (and justify
			    (consp (cdr area))))
		  (goto-char (cdr area))
		(goto-char (cddr area))
		(let ((ecol (current-column)))
		  (goto-char (cadr area))
		  (setq gocol (- col (- ecol (current-column))))))
	      (setq cur (current-column))
	      (cond ((< gocol 0) t)     ; don't do anything
		    ((= cur gocol) t)   ; don't need to
		    ((< cur gocol)      ; just add space
		     ;; FIXME: It is stated above that "...the
		     ;;	       whitespace to be modified was already
		     ;;	       deleted by `align-region', all we have
		     ;;	       to do here is indent."  However, this
		     ;;	       doesn't seem to be true, so we first
		     ;;	       delete the whitespace to avoid tabs
		     ;;	       after spaces.
		     (delete-horizontal-space t)
		     (indent-to gocol))
		    (t
		     ;; This code works around an oddity in the
		     ;; FORCE argument of `move-to-column', which
		     ;; tends to screw up markers if there is any
		     ;; tabbing.
		     (let ((endcol (align-column
				    (if (and justify
					     (consp (cdr area)))
					(cadr area)
				      (cdr area))))
			   (abuts (<= gocol
				      (align-column (car area)))))
		       (if abuts
			   (goto-char (car area))
			 (move-to-column gocol t))
		       (let ((here (point)))
			 (move-to-column endcol t)
			 (delete-region here (point))
			 (if abuts
			     (indent-to (align-adjust-col-for-rule
					 (current-column) rule
					 (car props) (cdr props)))))))))))
	(setq areas (cdr areas))))))