Respuestas:
Obtuve el formato de tabla completa para trabajar con algunos Elisp:
Se evalúa una fórmula para el contenido de las celdas y se convierte a un color usando un gradiente.
Archivo de la organización que incluye el código:
#+name: item-prices
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Item | Weight | Label Price | Ratio | CS-F | <-LR | <-WR | CS-N | Si-N | Si-2 | St-N | St-F |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Охотничье ружьё | 3.3 | 400 | 121 | 40 | 10 | 11.82 | | 40 | 40 | 50 | 60 |
| «Гадюка-5» | 2.88 | 3000 | 1042 | 300 | 10 | 103.82 | | 300 | 300 | 375 | 450 |
| Обрез | 1.90 | 200 | 105 | 20 | 10 | 10.00 | | 20 | 20 | 25 | 30 |
| ПМм | 0.73 | 300 | 411 | 30 | 10 | 39.73 | | 30 | 30 | 37 | 45 |
| АКМ-74/2 * | 3.07 | 4000 | 1303 | 637 | 16 | 207.49 | | 318 | 318 | 398 | 478 |
| АКМ-74/2У | 2.71 | 2100 | 775 | 420 | 20 | 154.61 | | 210 | 210 | 262 | 315 |
| ПБ-1с | 0.97 | 400 | 412 | 120 | 30 | 122.68 | 100 | 40 | 40 | 50 | 60 |
| «Чeйзер-13» | 3.00 | 1250 | 417 | | | | | 125 | | | |
| «Чeйзер-13» * | | 1250 | 417 | 200 | 16 | 66.33 | | 100 | 100 | 125 | 149 |
| ХПСС-1м | 0.94 | 600 | 682 | | | | | 60 | | | |
| ХПСС-1м * | 0.88 | 600 | 682 | 92 | 15 | 104.55 | | 46 | 46 | 57 | 69 |
| «Фора-12» | 0.83 | 600 | 723 | 120 | 20 | 143.37 | | 60 | 60 | 74 | 90 |
| «Кора-919» | 1.10 | 1500 | | | | | | 150 | 150 | | 225 |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Прицел ПСО-1 | 0.20 | 1000 | 5000 | 100 | 10 | 500.00 | | 150 | 150 | 150 | 200 |
| Детектор «Отклик» | 0.00 | 500 | inf | 50 | 10 | 50.00 | | 100 | 100 | 175 | 250 |
| Детектор «Медведь» | 0.00 | 1000 | inf | 100 | 10 | 100.00 | | | | | 500 |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Кожаная куртка | 3.00 | 500 | 167 | 250 | 50 | 83.33 | | - | - | 200 | |
| Бронежилет ЧН-1 | 4.00 | 5000 | 1250 | 2500 | 50 | 625.00 | | - | - | | |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Аптечка | 0.10 | 300 | 3000 | 30 | 10 | 300.00 | 16 | 45 | 45 | 105 | 150 |
| Бинт | 0.05 | 200 | 4000 | 20 | 10 | 400.00 | 11 | 30 | | 70 | 100 |
| Противорад. п. | 0.05 | 300 | 6000 | 30 | 10 | 600.00 | 16 | 45 | | 105 | 150 |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Водка «Казаки» | 0.60 | 100 | 167 | 100 | 100 | 166.67 | 100 | - | - | - | - |
| «Завтрак туриста» | 0.30 | 100 | 333 | 100 | 100 | 333.33 | | - | - | - | - |
| Колбаса «Диетическая» | 0.50 | 50 | 100 | 50 | 100 | 100.00 | | - | - | - | - |
| Хлеб | 0.30 | 20 | 67 | 20 | 100 | 66.67 | | - | - | - | - |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Патроны 9x18 мм | 0.20 | 50 | 250 | 5 | 10 | 25.00 | 3 | 7 | 7 | 5 | 5 |
| Патроны 9x19 мм РВР | 0.24 | 100 | 417 | 20 | 20 | 83.33 | 15 | | | | |
| Патроны 9x19 мм ЦМО | 0.24 | 100 | 417 | | 0 | 0.00 | | 15 | 15 | 15 | 20 |
| Патроны 12x70 дробь | 0.45 | 10 | 22 | 1 | 10 | 2.22 | 0 | 1 | | 1 | 1 |
| Патроны 12x76 жекан | 0.50 | 20 | 40 | 4 | 20 | 8.00 | 3 | 1 | | 3 | 4 |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| Граната РГД-5 | 0.30 | 350 | | | | | | 52 | 52 | 70 | 70 |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
| «Медуза» | 0.5 | 4000 | 8000 | | 0 | 0.00 | | 2800 | 3600 | 2500 | 2800 |
|-----------------------+--------+-------------+-------+------+------+--------+------+------+------+------+------|
#+TBLFM: $4='(/ (string-to-number $3) (string-to-number $2));%1.f
#+TBLFM: $6='(/ (string-to-number $5) 0.01 (string-to-number $3));%1.f
#+TBLFM: $7=$5/$2;%1.2f
#+begin_src emacs-lisp :var table=item-prices
(defun cs/itpl (low high r rlow rhigh)
"Return the point between LOW and HIGH that corresponds to where R is between RLOW and RHIGH."
(+ low (/ (* (- high low) (- r rlow)) (- rhigh rlow))))
(defun cs/gradient (gradient p)
(if (< p (caar gradient))
(cdar gradient)
(while (and (cdr gradient) (> p (caadr gradient)))
(setq gradient (cdr gradient)))
(if (null (cdr gradient))
(cdar gradient)
(list
(cs/itpl (nth 1 (car gradient)) (nth 1 (cadr gradient)) p (caar gradient) (caadr gradient))
(cs/itpl (nth 2 (car gradient)) (nth 2 (cadr gradient)) p (caar gradient) (caadr gradient))
(cs/itpl (nth 3 (car gradient)) (nth 3 (cadr gradient)) p (caar gradient) (caadr gradient))))))
(defun cs/scs-table-color ()
(when (boundp 'cs/cell-color-overlays)
(mapc #'delete-overlay cs/cell-color-overlays))
(setq-local cs/cell-color-overlays nil)
(save-excursion
(org-table-map-tables
(lambda ()
(let* ((table (cl-remove-if-not #'listp (org-table-to-lisp))) ; remove 'hline
(heading (car table))
(element (org-element-at-point)))
(while (and element (not (eq (car element) 'table)))
(setq element (plist-get (cadr element) :parent)))
(cond
((equal (plist-get (cadr element) :name) "item-prices")
(org-table-analyze)
(cl-loop for row being the elements of (cdr table) using (index row-index)
do (cl-loop for col being the elements of row using (index col-index)
if (and
(string-match "^..-.$" (nth col-index heading))
(not (zerop (length col)))
(not (equal "0" col)))
do (progn
(org-table-goto-field (format "@%d$%d" (+ 2 row-index) (1+ col-index)))
(forward-char)
(let* ((base-price (string-to-number (nth 2 row)))
(vendor-price (string-to-number col))
(ratio (/ vendor-price 1.0 base-price))
(gradient '((0.10 #x40 #x00 #x00)
(0.20 #xC0 #x00 #x00)
(0.50 #x00 #x80 #x00)
(1.00 #x00 #xFF #x80)))
(color (cs/gradient gradient ratio))
(overlay (make-overlay
(progn (org-table-beginning-of-field 1) (backward-char) (point))
(progn (org-table-end-of-field 1) (forward-char) (point))))
(bg (apply #'message "#%02x%02x%02x" color))
(fg (if (< (apply #'+ color) 383) "#ffffff" "#000000"))
(face (list
:background bg
:foreground fg)))
(overlay-put overlay 'face face)
(push overlay cs/cell-color-overlays)))))))))
t)))
(add-hook 'org-ctrl-c-ctrl-c-hook 'cs/scs-table-color nil t)
nil
#+end_src
cs/itpl
realiza una interpolación lineal simple y la cs/gradient
utiliza para interpolar un color usando una lista de puntos de datos y paradas de color. A partir de ahí, solo agrega una superposición como en su respuesta. El ejemplo es un poco trivial, ya que consulta datos de otras partes de la tabla.
org-table-map-tables
.
Usar una superposición es cómo voy a querer hacerlo. Puedo conectarme a org-ctrl-c-ctrl-c-hook. Significa que puedo presionar Cc Cc para ejecutar la verificación.
Necesito verificar adecuadamente que estoy dentro de una tabla y ejecutar esto para todas las celdas.
Entonces probablemente necesito conectarme a la función de alineación para rehacer las superposiciones o al menos borrarlas.
Este código hará que el fondo de la celda sea rojo para la celda en la que estoy si el valor es menor que 1 o mayor que 2 cuando presiono Cc Cc ... Pero todavía tiene errores y borrará las superposiciones si una de ellas no lo hace. No coincide con las reglas.
(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)
Todavía no es una respuesta, pero quiero hacer un seguimiento de las cosas que descubro aquí, ya que pueden darle una idea a otra persona.
Es posible modificar condicionalmente el valor de la celda en sí :
Podemos crear una función de formato en elisp y luego llamarla desde la línea de fórmula:
#+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
Y se puede usar así:
| String | Num |
|--------+-----|
| Foo | 2 |
| Bar | 1 |
| Baz | 3! |
|--------+-----|
#+TBLFM: $2='(danger @0$0)
Creo que lo que quiero puede requerir la creación de una superposición.
Emacs proporciona la función hi-lock-face-buffer
M-s h rque resalta una expresión regular en el búfer a medida que escribe.
Todo lo que necesitamos es una expresión regular que coincida con cualquier número que no sea 1 o 2 y esté dentro de la celda de una tabla. Prueba esto:
| *\(-[0-9]+\|[03-9]\|[0-9][0-9]+\) *|
(Puede recordar expresiones anteriores con M-ny M-p.)
org-table-edit-formulas
akaC-c '
comoorg-table-toggle-coordinate-overlays
akaC-c }
proporcionan pistas sobre cómo implementar este tipo de función de resaltado. Quizás un gurú de elisp proporcionará algunos consejos o ejemplos adicionales.