|
2 | 2 | (:require
|
3 | 3 | [clojure.string :as str]
|
4 | 4 | [remplater.components.builtin-components]
|
| 5 | + [remplater.components.positioning :as pos] |
5 | 6 | [remplater.components.render :as render]
|
6 | 7 | [remplater.datetime :as dt]
|
7 | 8 | [remplater.pdf :as pdf]
|
8 | 9 | [tick.core :as t])
|
9 | 10 | (:import
|
10 | 11 | [org.apache.pdfbox.pdmodel.common PDRectangle]))
|
11 | 12 |
|
12 |
| -(def color-light-gray (pdf/make-color 100 100 100)) |
13 |
| - |
14 |
| -(defn get-note-page-name [note-index] (str "note-" note-index)) |
15 |
| - |
16 |
| -(def index-cells-pattern |
17 |
| - {:width "10%" |
18 |
| - :height 80 |
19 |
| - :row-count 20 |
20 |
| - :outline [:line {:width 1}] |
21 |
| - :line [:line {:width 1}] |
22 |
| - :cell (fn [{:keys [index]} & children] |
23 |
| - [:page-link {:target-page (get-note-page-name index)} |
24 |
| - [:padding {:padding-left 20} |
25 |
| - [:split {:direction :x :splits [20]} |
26 |
| - [:circle {:radius 12}] |
27 |
| - [:padding {:padding 10} |
28 |
| - [:text {:text (-> index inc str) |
29 |
| - :font-size 20 |
30 |
| - :valign :center |
31 |
| - :halign :left}]]]]])}) |
32 |
| - |
33 |
| -(def note-pattern |
34 |
| - {:width "50%" |
| 13 | +(def paddings |
| 14 | + {:layout-left 200 |
| 15 | + :layout-top 105}) |
| 16 | + |
| 17 | +(def colors |
| 18 | + {:gray (pdf/make-color 50 50 50) |
| 19 | + :light-gray (pdf/make-color 100 100 100)}) |
| 20 | + |
| 21 | +(def styles |
| 22 | + {:layout-border {:width 1 |
| 23 | + :color (:light-gray colors)} |
| 24 | + :week-days-completion-mark {:padding 10}}) |
| 25 | + |
| 26 | +(def page-names |
| 27 | + {:day #(str "day-" %) |
| 28 | + :weeks #(str "weeks-" %)}) |
| 29 | + |
| 30 | +(def days-per-weeks-page 28) |
| 31 | +(def week-days-completion-mark-size 60) |
| 32 | +(def day-completion-mark-size 60) |
| 33 | + |
| 34 | +(defn get-page-name [page-name & params] |
| 35 | + (apply (get page-names page-name) params)) |
| 36 | + |
| 37 | +(def light-gray-line |
| 38 | + [:line {:width 1 |
| 39 | + :color (:light-gray colors)}]) |
| 40 | + |
| 41 | +(defn bottom-outline [{:as attrs :keys [side]} & children] |
| 42 | + (when (= :bottom side) |
| 43 | + children)) |
| 44 | + |
| 45 | +(def lines-layout-pattern |
| 46 | + {:width "100%" |
35 | 47 | :height 52
|
36 |
| - :row-count 35 |
37 | 48 | :outline (fn [{:as attrs :keys [side]} & children]
|
38 | 49 | (when (#{:bottom :top} side)
|
39 |
| - [:line {:width 1 |
40 |
| - :color color-light-gray}])) |
41 |
| - :line [:line {:width 1 |
42 |
| - :color color-light-gray}]}) |
43 |
| - |
44 |
| -(defn index-page [{:keys [notes-count]}] |
45 |
| - [:page {:name "index"} |
46 |
| - [:padding {:padding 120} |
47 |
| - [:pattern-grid {:pattern index-cells-pattern}]]]) |
48 |
| - |
49 |
| -(defn note-page [{:keys [note-index]}] |
50 |
| - [:page {:name (get-note-page-name note-index) |
51 |
| - :size (PDRectangle. 1404 4000)} |
52 |
| - [:split {:direction :y :splits [105]} |
53 |
| - [:padding {:padding-left 120} |
54 |
| - [:page-link {:target-page "index"} |
55 |
| - [:split {:direction :x :splits [100]} |
56 |
| - [:circle {:radius 15}] |
57 |
| - [:text {:text (-> note-index inc str) |
| 50 | + light-gray-line)) |
| 51 | + :line light-gray-line}) |
| 52 | + |
| 53 | +(defn completion-mark [{:as attrs :keys [x1 y1 x2 y2]}] |
| 54 | + (let [attrs (merge attrs light-gray-line) |
| 55 | + {:keys [x y]} (pos/rect->center attrs)] |
| 56 | + [:div |
| 57 | + [:line (assoc attrs :x1 x1 :y1 y :x2 x :y2 y2)] |
| 58 | + [:line (assoc attrs :x1 x :y1 y2 :x2 x2 :y2 y)] |
| 59 | + [:line (assoc attrs :x1 x2 :y1 y :x2 x :y2 y1)] |
| 60 | + [:line (assoc attrs :x1 x :y1 y1 :x2 x1 :y2 y)]])) |
| 61 | + |
| 62 | +(defn page-layout [{:keys [top-left top-right bottom-left bottom-right]}] |
| 63 | + [:split {:direction :y :splits [(:layout-top paddings)]} |
| 64 | + [:div |
| 65 | + [:border {:border-bottom (:layout-border styles)}] |
| 66 | + [:split {:direction :x :splits [(:layout-left paddings)]} |
| 67 | + [:div |
| 68 | + [:border {:border-right (:layout-border styles)}] |
| 69 | + top-left] |
| 70 | + top-right]] |
| 71 | + |
| 72 | + [:split {:direction :x :splits [(:layout-left paddings)]} |
| 73 | + [:div |
| 74 | + [:border {:border-right (:layout-border styles)}] |
| 75 | + bottom-left] |
| 76 | + bottom-right]]) |
| 77 | + |
| 78 | +(defn weeks-page [{:keys [from-date]}] |
| 79 | + [:page {:name (get-page-name :weeks from-date)} |
| 80 | + [page-layout |
| 81 | + {:bottom-right |
| 82 | + [:split {:direction :y :splits [700]} |
| 83 | + [:grid {:cols 7 :rows 4 |
| 84 | + :line light-gray-line |
| 85 | + :outline (fn [attrs & _] |
| 86 | + [bottom-outline attrs light-gray-line])} |
| 87 | + (fn [{:keys [index]}] |
| 88 | + (let [date (t/>> from-date (t/of-days index))] |
| 89 | + [:page-link {:target-page (get-page-name :day date)} |
| 90 | + [:padding {:padding 10} |
| 91 | + [:split {:direction :y :splits [30]} |
| 92 | + [:text {:text (t/format (t/formatter "dd") date) |
| 93 | + :color (:gray colors) |
| 94 | + :font-size 30 |
| 95 | + :valign :top |
| 96 | + :halign :right}] |
| 97 | + [:text {:text (-> (t/format (t/formatter "MMM") date) |
| 98 | + (str/upper-case)) |
| 99 | + :color (:light-gray colors) |
| 100 | + :font-size 20 |
| 101 | + :valign :top |
| 102 | + :halign :right}]]] |
| 103 | + |
| 104 | + [:split {:direction :x :splits [week-days-completion-mark-size]} |
| 105 | + [:split {:direction :y :splits [week-days-completion-mark-size]} |
| 106 | + [:padding (:week-days-completion-mark styles) |
| 107 | + [completion-mark]]]]]))]]}]]) |
| 108 | + |
| 109 | +(defn day-page [{:keys [date weeks-date]}] |
| 110 | + [:page {:name (get-page-name :day date) |
| 111 | + :size (PDRectangle. 1404 6000)} |
| 112 | + [page-layout |
| 113 | + {:top-left |
| 114 | + [:padding {:padding-top "25%" |
| 115 | + :padding-left 120} |
| 116 | + [:split {:direction :x :splits [day-completion-mark-size]} |
| 117 | + [:split {:direction :y :splits [day-completion-mark-size]} |
| 118 | + [completion-mark]]]] |
| 119 | + |
| 120 | + :top-right |
| 121 | + [:page-link {:target-page (get-page-name :weeks weeks-date)} |
| 122 | + [:padding {:padding-left 20} |
| 123 | + [:text {:text (t/format (t/formatter "dd MMM") date) |
58 | 124 | :font-size 40
|
59 | 125 | :valign :center
|
60 |
| - :halign :left}]]]] |
61 |
| - [:pattern-grid {:pattern note-pattern}]]]) |
| 126 | + :halign :left}]]] |
| 127 | + |
| 128 | + :bottom-left |
| 129 | + [:pattern-grid {:pattern lines-layout-pattern}] |
| 130 | + |
| 131 | + :bottom-right |
| 132 | + [:pattern-grid {:pattern lines-layout-pattern}]}]]) |
62 | 133 |
|
63 |
| -(defn document [{:as attrs :keys [notes-count]}] |
| 134 | +(defn document [{:as attrs :keys [from-date to-date]}] |
64 | 135 | (into [:document {:output "/tmp/autofocus.pdf"
|
65 | 136 | :page-size pdf/remarkable-2-page-size
|
66 | 137 | :fonts {:default "fonts/Iosevka-Regular.ttf"}}]
|
67 | 138 | (concat
|
68 |
| - [[index-page attrs]] |
| 139 | + (->> (dt/range-dates from-date to-date (t/of-days days-per-weeks-page)) |
| 140 | + (mapv (fn [from-date] |
| 141 | + [weeks-page {:from-date from-date}]))) |
69 | 142 |
|
70 |
| - (->> (range notes-count) |
71 |
| - (mapv (fn [note-index] |
72 |
| - [note-page {:note-index note-index}])))))) |
| 143 | + (->> (dt/range-dates from-date to-date (t/of-days days-per-weeks-page)) |
| 144 | + (mapcat (fn [from-date] |
| 145 | + (let [weeks-to-date (t/>> from-date (t/of-days days-per-weeks-page))] |
| 146 | + (->> (dt/range-dates from-date weeks-to-date) |
| 147 | + (mapv (fn [date] |
| 148 | + [day-page {:date date |
| 149 | + :weeks-date from-date}])))))))))) |
73 | 150 |
|
74 | 151 | (comment
|
75 | 152 | (render/render-document
|
76 |
| - (document {:notes-count 200}))) |
| 153 | + (document {:from-date (t/new-date 2024 12 9) |
| 154 | + :to-date (t/new-date 2025 1 5)}))) |
0 commit comments