ฉันสามารถจัดรูปแบบเซลล์ในตารางโหมดองค์กรแตกต่างกันขึ้นอยู่กับสูตรได้หรือไม่?


17

ฉันมีคอลัมน์ในตารางโหมดองค์กรที่มีตัวเลขในแต่ละเซลล์ ฉันต้องการเปลี่ยนสีพื้นหลังของเซลล์เป็นสีแดงหากจำนวนต่ำกว่า 1 หรือสูงกว่า 2

ฉันจะทำสิ่งนั้นได้อย่างไร


3
เป็นคำถามที่ดีมาก! ทั้งorg-table-edit-formulasaka C-c 'และorg-table-toggle-coordinate-overlaysaka C-c }ให้ข้อมูลเกี่ยวกับวิธีใช้คุณลักษณะการไฮไลต์ประเภทนี้ บางทีกูรู elisp จะให้คำแนะนำหรือตัวอย่างเพิ่มเติม
Melioratus

คำตอบ:


4

ฉันจัดรูปแบบทั้งตารางเพื่อทำงานกับ Elisp บางส่วน:

สูตรจะถูกประเมินสำหรับเนื้อหาของเซลล์และแปลงเป็นสีโดยใช้การไล่ระดับสี

ไฟล์ Org รวมถึงรหัส:

#+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 เป็นอินพุทและนี่คือสิ่งที่ทำกับตาราง" :)
Trevoke

ขอบคุณ นี่เป็นการรวมกันของสองคำตอบของคุณ มีความซ้ำซ้อนบางอย่างเนื่องจากทั้งสองได้รับข้อมูลตารางจาก org-babel และค้นหาการประกาศชื่อตาราง (เพื่อให้สามารถเพิ่มการวางซ้อนเป็นต้น) จากนั้นจะจับคู่หมายเลขแถวและคอลัมน์จากข้อมูลตารางที่ได้รับไปยังพิกัดเซลล์ของตาราง org cs/itplทำการแก้ไขเชิงเส้นอย่างง่ายและcs/gradientใช้เพื่อแก้ไขสีโดยใช้รายการจุดข้อมูลและสีหยุด จากตรงนั้นเพียงเพิ่มการซ้อนทับในคำตอบของคุณ ตัวอย่างนี้เป็นบิตที่ไม่น่าสนใจเนื่องจากให้คำปรึกษาข้อมูลจากที่อื่นในตาราง
Vladimir Panteleev

อัปเดตรหัสด้วยเวอร์ชันที่ใหม่กว่าซึ่งแก้ไขชื่อ / ข้อมูลซ้ำซ้อนล้างการซ้อนทับเก่าและลงทะเบียนตัวเองเป็น org-ctrl-c-ctrl-c-hook เพื่อให้คุณไม่ต้องใส่จุดในบล็อกรหัสเพื่อเรียกใช้ มัน. org-table-map-tablesนอกจากนี้ยังสามารถปรับปรุงตารางทั้งหมดในมารยาทของเอกสาร
Vladimir Panteleev

เยี่ยมมาก ฉันชอบความคิดเห็นเพิ่มเติมสำหรับคนที่อาจมาที่นี่และไม่คุ้นเคยกับ elisp แต่มันน่าทึ่งขอบคุณ!
Trevoke

4

การใช้ภาพซ้อนทับเป็นวิธีที่ฉันต้องการทำ ฉันขอเกี่ยวกับ org-ctrl-c-ctrl-c-hook หมายความว่าฉันสามารถกด Cc Cc เพื่อเรียกใช้เช็ค

ฉันต้องตรวจสอบอย่างถูกต้องว่าฉันอยู่ในตารางและเรียกใช้สิ่งนี้กับเซลล์ทั้งหมด

จากนั้นฉันอาจต้องขอฟังก์ชั่นการจัดตำแหน่งเพื่อทำซ้ำการซ้อนทับหรืออย่างน้อยก็เคลียร์พวกเขา

รหัสนี้จะทำให้พื้นหลังของเซลล์เป็นสีแดงสำหรับเซลล์ที่ฉันอยู่ถ้าค่าน้อยกว่า 1 หรือมากกว่า 2 เมื่อฉันกด Cc Cc ... แต่มันก็ยังบั๊กและจะล้างซ้อนทับหากหนึ่งในนั้นไม่ได้ ' ไม่ตรงกับกฎ

(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-nและM-p.)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.