Function: texinfo-multitable-item

texinfo-multitable-item is a byte-compiled function defined in texinfmt.el.gz.

Signature

(texinfo-multitable-item)

Documentation

Format a row within a multicolumn table.

Cells in row are separated by @tab. Widths of cells are specified by the arguments in the @multitable line. All cells are made to be the same height. This command is executed when texinfmt sees @item inside @multitable.

Source Code

;; Defined in /usr/src/emacs/lisp/textmodes/texinfmt.el.gz
(defun texinfo-multitable-item ()
  "Format a row within a multicolumn table.
Cells in row are separated by @tab.
Widths of cells are specified by the arguments in the @multitable line.
All cells are made to be the same height.
This command is executed when texinfmt sees @item inside @multitable."
  (let ((original-buffer (current-buffer))
        (table-widths (reverse (car (cdr (car texinfo-stack)))))
        (existing-fill-column fill-column)
        start
        end
        (table-column       0)
        (table-entry-height 0)
        ;; unformatted row looks like:  A1  @tab  A2  @tab  A3
        ;; extract-row command deletes the source line in the table.
        (unformatted-row (texinfo-multitable-extract-row)))
    ;; Use a temporary buffer
    (set-buffer (get-buffer-create texinfo-multitable-buffer-name))
    (delete-region (point-min) (point-max))
    (insert unformatted-row)
    (goto-char (point-min))
;; 1. Check for correct number of @tab in line.
    (let ((tab-number 1))               ; one @tab between two columns
      (while (search-forward "@tab" nil t)
        (setq tab-number (1+ tab-number)))
      (let ((needed-tabs (- (length table-widths) tab-number)))
        (when (> needed-tabs 0)
              (goto-char (point-min))
              (end-of-line)
              (while (> needed-tabs 0)
                (insert "@w{ }\n@tab")
                (setq needed-tabs (1- needed-tabs))
                (message
                 "Added @tabs and empty spaces to a @multitable row")))))
    (goto-char (point-min))
;; 2. Format each cell, and copy to a rectangle
    ;; buffer looks like this:    A1  @tab  A2  @tab  A3
    ;; Cell #1: format up to @tab
    ;; Cell #2: format up to @tab
    ;; Cell #3: format up to eob
    (while (not (eobp))
      (setq start (point))
      (setq end (save-excursion
                  (if (search-forward "@tab" nil 'move)
                      ;; Delete the @tab command, including the @-sign
                      (delete-region
                       (point)
                       (progn (forward-word-strictly -1) (1- (point)))))
                  (point)))
      ;; Set fill-column *wider* than needed to produce inter-column space
      (setq fill-column (+ 1
                           texinfo-extra-inter-column-width
                           (nth table-column table-widths)))
      (narrow-to-region start end)
      ;; Remove whitespace before and after entry.
      (skip-chars-forward " ")
      (delete-region (point) (line-beginning-position))
      (goto-char (point-max))
      (skip-chars-backward " ")
      (delete-region (point) (line-end-position))
      ;; Temporarily set texinfo-stack to nil so texinfo-format-scan
      ;; does not see an unterminated @multitable.
      (let (texinfo-stack)                      ; nil
        (texinfo-format-scan))
      (let (fill-prefix)                        ; no fill prefix
        (fill-region (point-min) (point-max)))
      (setq table-entry-height
            (max table-entry-height (count-lines (point-min) (point-max))))
;; 3. Move point to end of bottom line, and pad that line to fill column.
      (goto-char (point-min))
      (forward-line (1- table-entry-height))
      (let* ((beg (point))                      ; beginning of line
             ;; add one more space for inter-column spacing
             (needed-whitespace
              (1+
               (- fill-column
                  (-
                   (progn (end-of-line) (point)) ; end of existing line
                   beg)))))
        (insert (make-string
                 (if (> needed-whitespace 0) needed-whitespace 1)
                 ? )))
      ;; now, put formatted cell into a rectangle
      (set (intern (concat texinfo-multitable-rectangle-name
                           (int-to-string table-column)))
           (extract-rectangle (point-min) (point)))
      (delete-region (point-min) (point))
      (goto-char (point-max))
      (setq table-column (1+ table-column))
      (widen))
;; 4. Add extra lines to rectangles so all are of same height
    (let ((total-number-of-columns table-column)
          (column-number 0)
          here)
      (while (> table-column 0)
        (let ((this-rectangle (int-to-string table-column)))
          (while (< (length this-rectangle) table-entry-height)
            (setq this-rectangle (append this-rectangle '("")))))
        (setq table-column (1- table-column)))
;; 5. Insert formatted rectangles in original buffer
      (switch-to-buffer original-buffer)
      (open-line table-entry-height)
      (while (< column-number total-number-of-columns)
        (setq here (point))
        (insert-rectangle
         (symbol-value (intern
                        (concat texinfo-multitable-rectangle-name
                                (int-to-string column-number)))))
        (goto-char here)
        (end-of-line)
        (setq column-number (1+ column-number))))
    (kill-buffer texinfo-multitable-buffer-name)
    (setq fill-column existing-fill-column)))