Kuruluş modu tablosundaki hücreleri formüle bağlı olarak farklı şekilde biçimlendirebilir miyim?


17

Her hücrede sayıları olan bir kuruluş modu tablosunda bir sütun var. Sayı 1'in altında veya 2'nin üzerindeyse hücrenin arka plan rengini kırmızı olarak değiştirmek istiyorum.

Bunu nasıl yapabilirim?


3
Harika bir soru! Hem org-table-edit-formulasaka C-c 'hem de org-table-toggle-coordinate-overlaysaka C-c }, bu tür vurgulama özelliğinin nasıl uygulanacağı hakkında ipuçları sağlar . Belki de elisp gurusu bazı ek ipuçları veya örnekler sunacaktır.
Melioratus

Yanıtlar:


5

Bazı Elisp ile çalışmak için tüm tablo biçimlendirme var:

Formül, hücrelerin içeriği için değerlendirilir ve degrade kullanılarak bir renge dönüştürülür.

Kod içeren kuruluş dosyası:

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

Bu harika! Her şeyin nasıl bağlandığına dair biraz daha ayrıntılı bir açıklama okumak isterim, sadece "bu kod X yaptığınızda çalışır, Y ve Z'yi girdi olarak alır ve bu tabloya yaptığı şeydir" :)
Trevoke

Teşekkürler. Bu hemen hemen iki cevabınızın birleşimidir. Hem org-babel'den tablo verilerini aldığından hem de tablo adı bildirimini (bindirmeler ekleyebilmesi için) aradığı için biraz fazlalık vardır. Oradan, alınan tablo verilerinden satır ve sütun numaralarını org tablosu hücre koordinatlarına eşler. cs/itplbasit doğrusal enterpolasyon yapar ve cs/gradientbunu veri noktalarının ve renk duraklarının listesini kullanarak bir rengin enterpolasyonunu yapmak için kullanır. Oradan yanıtınıza olduğu gibi bir yer paylaşımı ekler. Örnek, tablonun başka bir yerindeki verilere başvurduğundan biraz önemsizdir.
Vladimir Panteleev

Kodu, ad / veri yedekliliğini düzelten, eski kaplamaları temizleyen ve kendisini bir org-ctrl-c-ctrl-c-hook olarak kaydeden daha yeni bir sürümle güncelledi, böylece çalıştırmak için kod bloğuna nokta koymanıza gerek yok o. Ayrıca belgedeki tüm tabloları izniyleorg-table-map-tables .
Vladimir Panteleev

Bu harika. Buraya gelip elisp'e aşina olmayan insanlar için biraz daha yorum yapmak isterdim, ama şaşırtıcı, teşekkürler!
Trevoke

@VladimirPanteleev bunu benim yapılandırmaya ekleyebilir ve herhangi bir tabloya kolayca uygulayabileceğim bir "dahili" işlev olup olmadığını biliyor musunuz?
tecosaur

4

Bir bindirme kullanmak nasıl yapacağım. Org-ctrl-c-ctrl-c-çengele takılabilirim. Bu, kontrolü çalıştırmak için Cc Cc tuşuna basabileceğim anlamına gelir.

Düzgün bir tablonun içinde olduğumu kontrol etmek ve tüm hücreler için bu çalıştırmak gerekir.

Sonra muhtemelen bindirmeleri yeniden yapmak veya en azından temizlemek için hizalama işlevine bağlanmam gerekiyor.

Bu kod, Cc Cc'ye bastığımda değer 1'den az veya 2'den büyükse, içinde bulunduğum hücre için hücre arka planını kırmızı yapar ... Ama yine de buggy ve bunlardan biri yoksa bindirmeleri temizler ' t kurallara uy.

(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

Bu henüz bir cevap değil ama burada keşfettiğim şeyleri takip etmek istiyorum, çünkü başka birine bir fikir verebilirler.

Hücrenin kendisinin değerini koşullu olarak değiştirmek mümkündür :

Elisp'de bir biçimlendirme işlevi oluşturabilir ve bunu formül satırından çağırabiliriz:

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

Ve şu şekilde kullanılabilir:

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

Sanırım istediğim bir yer paylaşımı oluşturulmasını gerektirebilir.


2

Emacs, hi-lock-face-buffer M-s h rsiz yazarken arabellekteki normal ifadeyi vurgulayan işlevi sağlar .

Tek ihtiyacımız olan, 1 veya 2 olmayan ve tablonun hücresi içindeki herhangi bir sayı ile eşleşen normal bir ifadedir. Bunu dene:

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

(Önceki ifadeleri M-nve ile hatırlayabilirsiniz M-p.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.