수식에 따라 조직 모드 테이블의 셀 서식을 다르게 지정할 수 있습니까?


17

각 셀에 숫자가있는 org-mode 테이블에 열이 있습니다. 숫자가 1보다 작거나 2보다 높으면 셀의 배경색을 빨간색으로 변경하고 싶습니다.

어떻게해야합니까?


3
좋은 질문입니다! org-table-edit-formulas일명 C-c 'org-table-toggle-coordinate-overlays일명 모두 이러한 유형의 강조 표시 기능을 구현하는 방법에 C-c }대한 단서 를 제공 합니다. 아마도 elisp 전문가가 몇 가지 추가 힌트 나 예제를 제공 할 것입니다.
Melioratus

답변:


4

일부 Elisp와 작동하도록 전체 테이블 형식이 있습니다.

셀 내용에 대한 공식을 평가하고 그라디언트를 사용하여 색상으로 변환합니다.

코드를 포함한 조직 파일 :

#+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

환상적입니다! "이 코드는 X를 수행 할 때 실행되고 Y와 Z가 입력으로 사용되며 이것이 테이블에서 수행하는 작업"인 경우에도 어떻게 연결되어 있는지에 대해 좀 더 심층적 인 설명을 읽고 싶습니다. :)
취소

감사. 이것은 두 가지 답변의 조합입니다. org-babel에서 테이블 데이터를 수신하고 테이블 이름 선언을 검색하므로 오버레이 등을 추가 할 수 있으므로 중복성이 있습니다. 여기에서 수신 된 테이블 데이터의 행 및 열 번호를 조직 테이블 셀 좌표에 맵핑합니다. cs/itpl간단한 선형 보간을 수행하고이를 cs/gradient사용하여 데이터 포인트 및 색상 정지 점 목록을 사용하여 색상을 보간합니다. 거기에서 답변과 같이 오버레이가 추가됩니다. 이 예제는 테이블의 다른 곳에서 데이터를 참조하기 때문에 사소한 것이 아닙니다.
블라디미르 판 텔레 예프

이름 / 데이터 중복성을 수정하고, 오래된 오버레이를 지우고, org-ctrl-c-ctrl-c-hook로 자신을 등록하는 최신 버전으로 코드를 업데이트하여 코드 블록을 가리킬 필요가 없습니다. 그것. 의 문서에있는 모든 테이블을 업데이트 할 수도 있습니다 org-table-map-tables.
블라디미르 판 텔레 예프

훌륭합니다. 나는 여기 와서 elisp에 익숙하지 않은 사람들에 대한 의견을 더 많이 원하지만 놀랍습니다. 감사합니다!
취소

4

오버레이를 사용하는 것이 좋습니다. org-ctrl-c-ctrl-c-hook에 연결할 수 있습니다. Cc Cc를 눌러 검사를 실행할 수 있음을 의미합니다.

나는 테이블 안에 있는지 확인하고 모든 셀에 대해 이것을 실행해야합니다.

그런 다음 오버레이를 다시 실행하거나 적어도 지우려면 정렬 기능에 연결해야합니다.

이 코드는 Cc Cc를 누를 때 값이 1보다 작거나 2보다 크면 내가있는 셀의 셀 배경을 빨간색으로 만듭니다 ...하지만 여전히 버그가 있으며 그중 하나가 있으면 오버레이를 지 웁니다. 규칙과 일치하지 않습니다.

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

2

이것은 아직 답이 아니지만 다른 사람에게 아이디어를 줄 수 있기 때문에 내가 여기서 발견 한 것들을 추적하고 싶습니다.

셀 자체의 값조건부로 수정할 수 있습니다 .

elisp에서 서식 함수를 만든 다음 수식 줄에서 호출 할 수 있습니다.

#+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

그리고 그것은 다음과 같이 사용될 수 있습니다 :

| String | Num | 
|--------+-----| 
| Foo    |   2 | 
| Bar    |   1 | 
| Baz    |  3! | 
|--------+-----|
#+TBLFM: $2='(danger @0$0)

원하는 것은 오버레이를 만들어야 할 수도 있습니다.


2

Emacs는 hi-lock-face-buffer M-s h r입력 할 때 버퍼에서 정규 표현식을 강조 표시하는 기능 을 제공합니다 .

우리가 필요로하는 것은 1 또는 2가 아니며 테이블의 셀 내에있는 숫자와 일치하는 정규식입니다. 이 시도:

| *\(-[0-9]+\|[03-9]\|[0-9][0-9]+\) *|

(당신은에 이전 식을 불러올 수 M-nM-p.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.