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?

  • 2
    Great question! Both org-table-edit-formulas aka C-c ' and org-table-toggle-coordinate-overlays aka C-c } provide clues on how to implement this type of highlighting feature. Perhaps an elisp guru will provide some additional hints or examples. – Melioratus Jan 24 '15 at 17:30

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.)

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.