With the help of the lisp code at the end of this answer you can define a file-local list org-table-buffer-local-formulas
of replacements within org-table formulas which are active during the command org-table-recalculate
.
Each replacement is a cons (REGEXP . NEWTEXT)
of a regular expression string REGEXP
that should match the string you want to replace and the new text string NEWTEXT
that replaces the match.
The following example demonstrates how you can define org-table-buffer-local-formulas
and how you can use the replacements in org table formulas.
* Section with tables
You can use the replacements in ~org-table-buffer-local-formulas~
in org table formulas:
| first column | second column | third column |
|--------------+---------------+--------------|
| 1 | 2 | 4 |
| 2 | 4 | 8 |
#+TBLFM: {TBLFM:FIRST}
A second table with the same formula:
| | | |
| first column | second column | third column |
|--------------+---------------+--------------|
| 3 | 6 | 12 |
| 5 | 10 | 20 |
#+TBLFM: {TBLFM:FIRST}
The third table uses another formula from the list:
| | | |
| first column | second column | third column |
|--------------+---------------+--------------|
| 3 | 9 | 36 |
| 5 | 15 | 60 |
#+TBLFM: {TBLFM:SECOND}
* Local Variables :noexport:
Local Variables:
org-table-buffer-local-formulas: (("{TBLFM:FIRST}" . "$2=2*$1::$3=2*$2") ("{TBLFM:SECOND}" . "$2=3*$1::$3=4*$2"))
End:
There follows the lisp code you need to make the above example work.
You can install that lisp code in your init file.
(defun cmdbufmod-prepare (bufmod-list &optional start bound)
"Prepare buffer for `cmdbufmod' with modifications BUFMOD-LIST.
See `cmdbufmod' for the format of BUFMOD-LIST.
If START is a buffer position the search for the regular expressions in BUFMOD-LIST
starts there. Otherwise it starts at `point-min'.
Optional BOUND limits the search.
Return the list of original text sections.
Each text section is a cons of an insertion marker and the old text
that needs to be restored there."
(unless start (setq start (point-min)))
(let (original-list)
(save-excursion
(dolist (bufmod bufmod-list)
(let ((place (car bufmod))
(newtext (cdr bufmod)))
(goto-char start)
(while (if (functionp place)
(funcall place bound)
(re-search-forward place bound t))
(setq original-list
(cons (cons (set-marker (make-marker) (match-beginning 0))
(match-string 0))
original-list))
(replace-match (propertize (if (functionp newtext)
(funcall newtext)
newtext)
'cmdbufmod t))))))
original-list))
(defun cmdbufmod-cleanup (original-list)
"Restore original text sections from ORIGINAL-LIST.
See the return value of `cmdbufmod-prepare' for the structure of ORIGINAL-LIST."
(cl-loop for interval being the intervals property 'cmdbufmod
if (get-text-property (car interval) 'cmdbufmod)
do (delete-region (car interval) (cdr interval)))
(cl-loop for original in original-list do
(goto-char (car original))
(insert (cdr original))))
(defun cmdbufmod (bufmod-list fun &rest args)
"After applying BUFMOD-LIST to current buffer run FUN with ARGS like `apply'.
BUFMOD is a list of buffer modifications. Each buffer modification
is a cons \(PLACE . NEWTEXT).
PLACE can be a regular expression or a function.
If PLACE is a function it should search for the next place to be replaced
starting at point. It gets the search bound as an argument,
should set match-data like `re-search-forward',
and return non-nil if a match is found.
If PLACE is a regular expression it is treated like the function
\(lambda () (re-search-forward PLACE nil t))
NEWTEXT can be a replacement string or a function.
A function should return the string for `replace-match'."
(let (original-list)
(unwind-protect
(progn
(setq original-list (cmdbufmod-prepare bufmod-list))
(apply fun args))
(cmdbufmod-cleanup original-list))))
(defvar-local org-table-buffer-local-formulas nil
"List of buffer local table formulas.
Each element is a cons of a regexp and a formula (sequence).
The text matching the regexp is replaced by the formula sequence
when the table is iterated.")
(defun org-table-get-stored-formulas-buf-loc (oldfun &rest args)
"Replace buffer local table formulas when calling OLDFUN with ARGS."
(cmdbufmod org-table-buffer-local-formulas oldfun args))
(advice-add 'org-table-recalculate :around #'org-table-get-stored-formulas-buf-loc)