Function: org-table--increment-field

org-table--increment-field is a byte-compiled function defined in org-table.el.gz.

Signature

(org-table--increment-field FIELD PREVIOUS)

Documentation

Increment string FIELD according to PREVIOUS field.

Increment FIELD only if it is a string representing a number, per Emacs Lisp syntax, a timestamp, or is either prefixed or suffixed with a number. In any other case, return FIELD as-is.

If PREVIOUS has the same structure as FIELD, e.g., a number-prefixed string with the same pattern, the increment step is the difference between numbers (or timestamps, measured in days) in PREVIOUS and FIELD. Otherwise, it uses org-table-copy-increment, if the variable contains a number, or default to 1.

The function assumes org-table-copy-increment is non-nil.

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-table.el.gz
(defun org-table--increment-field (field previous)
  "Increment string FIELD according to PREVIOUS field.

Increment FIELD only if it is a string representing a number, per
Emacs Lisp syntax, a timestamp, or is either prefixed or suffixed
with a number.  In any other case, return FIELD as-is.

If PREVIOUS has the same structure as FIELD, e.g.,
a number-prefixed string with the same pattern, the increment
step is the difference between numbers (or timestamps, measured
in days) in PREVIOUS and FIELD.  Otherwise, it uses
`org-table-copy-increment', if the variable contains a number, or
default to 1.

The function assumes `org-table-copy-increment' is non-nil."
  (let* ((default-step (if (numberp org-table-copy-increment)
			   org-table-copy-increment
			 1))
	 (number-regexp			;Lisp read syntax for numbers
	  (rx (and string-start
		   (opt (any "+-"))
		   (or (and (one-or-more digit) (opt "."))
		       (and (zero-or-more digit) "." (one-or-more digit)))
		   (opt (any "eE") (opt (opt (any "+-")) (one-or-more digit)))
		   string-end)))
	 (number-prefix-regexp (rx (and string-start (one-or-more digit))))
	 (number-suffix-regexp (rx (and (one-or-more digit) string-end)))
	 (analyze
	  (lambda (field)
	    ;; Analyze string FIELD and return information related to
	    ;; increment or nil.  When non-nil, return value has the
	    ;; following scheme: (TYPE VALUE PATTERN) where
	    ;; - TYPE is a symbol among `number', `prefix', `suffix'
	    ;;   and `timestamp',
	    ;; - VALUE is a timestamp if TYPE is `timestamp', or
	    ;;   a number otherwise,
	    ;; - PATTERN is the field without its prefix, or suffix if
	    ;;   TYPE is either `prefix' or `suffix' , or nil
	    ;;   otherwise.
	    (cond ((not (org-string-nw-p field)) nil)
		  ((string-match-p number-regexp field)
		   (list 'number
			 (string-to-number field)
			 nil))
		  ((string-match number-prefix-regexp field)
		   (list 'prefix
			 (string-to-number (match-string 0 field))
			 (substring field (match-end 0))))
		  ((string-match number-suffix-regexp field)
		   (list 'suffix
			 (string-to-number (match-string 0 field))
			 (substring field 0 (match-beginning 0))))
		  ((string-match-p org-ts-regexp3 field)
		   (list 'timestamp field nil))
		  (t nil))))
	 (next-number-string
	  (lambda (n1 &optional n2)
	    ;; Increment number N1 and return it as a string.  If N2
	    ;; is also a number, deduce increment step from the
	    ;; difference between N1 and N2.  Otherwise, increment
	    ;; step is `default-step'.
	    (number-to-string (if n2 (+ n1 (- n1 n2)) (+ n1 default-step)))))
	 (shift-timestamp
	  (lambda (t1 &optional t2)
	    ;; Increment timestamp T1 and return it.  If T2 is also
	    ;; a timestamp, deduce increment step from the difference,
	    ;; in days, between T1 and T2.  Otherwise, increment by
	    ;; `default-step' days.
	    (with-temp-buffer
	      (insert t1)
	      (org-timestamp-up-day (if (not t2) default-step
				      (- (org-time-string-to-absolute t1)
					 (org-time-string-to-absolute t2))))
	      (buffer-string)))))
    ;; Check if both PREVIOUS and FIELD have the same type.  Also, if
    ;; the case of prefixed or suffixed numbers, make sure their
    ;; pattern, i.e., the part of the string without the prefix or the
    ;; suffix, is the same.
    (pcase (cons (funcall analyze field) (funcall analyze previous))
      (`((number ,n1 ,_) . (number ,n2 ,_))
       (funcall next-number-string n1 n2))
      (`((number ,n ,_) . ,_)
       (funcall next-number-string n))
      (`((prefix ,n1 ,p1) . (prefix ,n2 ,p2))
       (concat (funcall next-number-string n1 (and (equal p1 p2) n2)) p1))
      (`((prefix ,n ,p) . ,_)
       (concat (funcall next-number-string n) p))
      (`((suffix ,n1 ,p1) . (suffix ,n2 ,p2))
       (concat p1 (funcall next-number-string n1 (and (equal p1 p2) n2))))
      (`((suffix ,n ,p) . ,_)
       (concat p (funcall next-number-string n)))
      (`((timestamp ,t1 ,_) . (timestamp ,t2 ,_))
       (funcall shift-timestamp t1 t2))
      (`((timestamp ,t1 ,_) . ,_)
       (funcall shift-timestamp t1))
      (_ field))))