# plan9palette.fnl -rw-r--r-- 2.7 KiB View raw
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
;; Something to output a color palette according to https://9p.io/magic/man2html/6/color
;;
;; I couldn't visualize the colors it was supposed to generate, and I
;; was curious, so I made a thing to generate said colors and display
;; them.
;;
;; I THINK the colors are correct.
;;
;; By icefox@dreamquest.io
;; License: MIT


(fn generate-palette []
  "Generates the palette, returning a list of [r g b] values"
  (var palette [])
  (for [r 0 3]
    (for [v 0 3]
      (for [g 0 3]
        (for [b 0 3]
          (var denom r)
          (if (> g denom) (set denom g))
          (if (> b denom) (set denom b))
          ; Check for divide by 0, pick grey
          (if (= denom 0)
            (let [c (* 17 v)]
              (table.insert palette [c c c]))
            (let [num (* 17 (+ (* 4 denom) v))]
              (table.insert
                palette
                [(// (* r num) denom)
                 (// (* g num) denom)
                 (// (* b num) denom)])))))))
    palette)


;; Ok now we want to output the result of this.  We have three options.
;; First, we could just print out the raw values, though that's not
;; very helpful:
;(local fennel (require :fennel))
;(print (fennel.view (generate-palette)))


;; Otherwise I WAS going to make a cool program that generated a png or
;; displayed something with love2d, but
(print "<html><head></head><body>")
(print "<table>")


;; This outputs one color per line, which is a good start
;(each [_i color (ipairs (generate-palette))]
;  (let [color-str (string.format "#%02X%02X%02X" (. color 1) (. color 2) (. color 3))]
;    (print (string.format "<tr><td style=\"padding: 1em; background-color:%s\">" color-str))
;    (print color-str)
;    (print "</td></tr>")))

;; But this outputs a 16x16 grid of grid cells, which looks a lot
;; better.
;;
;; It is also a good demonstration of why 1-based list indexing is bad
;; and wrong.  Lua/Fennel's `(for [i a b] ...)` statement goes from a to
;; b inclusive, so it took me like ten tries to figure out what I actually
;; needed was:
;;   x = [0, 15], y = [0, 15], idx = x*16 + y + 1
;; In a 0-based language you'd write it as:
;;   x = [0, 16), y = [0, 16), idx = x*16 + y
;; I only figured out it was wrong because the palette forms 4x4 color
;; groupings and I noticed there was a 4x3 grouping so I was missing a
;; row.
(local colors (generate-palette))
(for [x 0 15]
  (print "<tr>")
  (for [y 0 15]
    (local idx (+ (+ y 1) (* x 16)))
    ;(print x y idx)
    (let [color (. colors idx)
          color-str (string.format "#%02X%02X%02X" (. color 1) (. color 2) (. color 3))]
      (print (string.format "<td style=\"padding: 1em; background-color:%s\">" color-str))
      (print color-str)
      (print "</td>")))
  (print "</tr>"))

(print "</table>")
(print "</body></html>")