I have a column in an org-mode table with numbers in each cell. I'd like to change the background color of the cell to red if the number is below 1 or above 2.
How can I do that?
Using an overlay is how I'm going to want to do it. I can hook into org-ctrl-c-ctrl-c-hook. It means I can press C-c C-c to run the check.
I need to properly check that I'm inside a table and run this for all cells.
Then I probably need to hook into the alignment function to either redo the overlays or at least clear them.
This code will make the cell background red for the cell I'm in if the value is less than 1 or greater than 2 when I press C-c C-c ... But it is still buggy and will clear the overlays if one of them doesn't match the rules.
(defun staggering () (save-excursion (let* ((ot-field-beginning (progn (org-table-beginning-of-field 1) (point))) (ot-field-end (progn (org-table-end-of-field 1) (point))) (cell-text (buffer-substring ot-field-beginning ot-field-end))) (if (or (< (string-to-number cell-text) 1) (> (string-to-number cell-text) 2)) (overlay-put (make-overlay (progn (org-table-beginning-of-field 1) (point)) (progn (org-table-end-of-field 1) (point))) 'face '(:background "#FF0000")))))) (add-hook 'org-ctrl-c-ctrl-c-hook 'staggering)
This is not yet an answer but I want to keep track of the things I discover here, as they may give someone else an idea.
It is possible to conditionally modify the value of the cell itself:
We can create a formatting function in elisp and then call it from the formula line:
#+BEGIN_SRC emacs-lisp :results silent (defun danger (cell) (if (or (< (string-to-number cell) 1) (> (string-to-number cell) 2)) (concat (int-to-string (string-to-number cell)) "!") cell)) #+END_SRC
And it can be used like so:
| String | Num | |--------+-----| | Foo | 2 | | Bar | 1 | | Baz | 3! | |--------+-----| #+TBLFM: $2='(danger @0$0)
I think what I want may require the creation of an overlay.
Emacs provides the function
hi-lock-face-buffer M-s h rwhich highlights a regular expression in the buffer as you type.
All we need is a regular expression which matches any number which is not 1 or 2 and is within the cell of a table. Try this:
| *\(-[0-9]+\|[03-9]\|[0-9][0-9]+\) *|
(You can recall previous expressions with M-n and M-p.)