Brandon Wong недель назад: 3
Родитель
Сommit
46abed816b

+ 3 - 5
frontend/src/cljs/microtables_frontend/core.cljs

@@ -1,12 +1,10 @@
 (ns microtables-frontend.core
 (ns microtables-frontend.core
   (:require
   (:require
-   [reagent.core :as reagent]
-   [re-frame.core :as re-frame]
+   [microtables-frontend.config :as config]
    [microtables-frontend.events :as events]
    [microtables-frontend.events :as events]
    [microtables-frontend.views :as views]
    [microtables-frontend.views :as views]
-   [microtables-frontend.config :as config]))
-
-
+   [re-frame.core :as re-frame]
+   [reagent.core :as reagent]))
 
 
 (defn dev-setup []
 (defn dev-setup []
   (when config/debug?
   (when config/debug?

+ 1 - 2
frontend/src/cljs/microtables_frontend/db.cljs

@@ -1,8 +1,7 @@
 (ns microtables-frontend.db)
 (ns microtables-frontend.db)
 
 
 (def default-db
 (def default-db
-  {
-   :controls nil
+  {:controls nil
    ;TODO: add "start" and "end" corners as selection
    ;TODO: add "start" and "end" corners as selection
    :position {:cursor nil
    :position {:cursor nil
               :selection nil #_{:start {:col "A" :row 5}
               :selection nil #_{:start {:col "A" :row 5}

+ 42 - 45
frontend/src/cljs/microtables_frontend/events.cljs

@@ -1,72 +1,69 @@
 (ns microtables-frontend.events
 (ns microtables-frontend.events
   (:require
   (:require
-   [re-frame.core :as re-frame]
    [microtables-frontend.db :as db]
    [microtables-frontend.db :as db]
-   [microtables-frontend.utils :as utils]))
-
-
-
+   [microtables-frontend.utils :as utils]
+   [re-frame.core :as re-frame]))
 
 
 (re-frame/reg-event-db
 (re-frame/reg-event-db
  ::initialize-db
  ::initialize-db
  (fn [_ _]
  (fn [_ _]
    (println "initializing db")
    (println "initializing db")
    (-> db/default-db
    (-> db/default-db
-       (update-in [:table-data] #(utils/walk-modify-data % (fn [c r datum] (if (= (first (:value datum)) "=") (assoc datum :dirty true) datum))))
+       (update-in [:table-data] #(utils/walk-modify-data
+                                  %
+                                  (fn [_c _r datum]
+                                    (if (= (first (:value datum)) "=")
+                                      (assoc datum :dirty true)
+                                      datum))))
        (update-in [:table-data] utils/create-all-references)
        (update-in [:table-data] utils/create-all-references)
        (update-in [:table-data] utils/create-all-back-references)
        (update-in [:table-data] utils/create-all-back-references)
        (update-in [:table-data] utils/evaluate-all))))
        (update-in [:table-data] utils/evaluate-all))))
 
 
-
 (re-frame/reg-event-db
 (re-frame/reg-event-db
-  ::movement-enter-cell
-  (fn [db [_ c r]]
-    (println "::movement-enter-cell" c r)
-    (assoc-in db [:position :cursor] {:col c :row r})))
-
-
+ ::movement-enter-cell
+ (fn [db [_ c r]]
+   (println "::movement-enter-cell" c r)
+   (assoc-in db [:position :cursor] {:col c :row r})))
 
 
 (re-frame/reg-event-db
 (re-frame/reg-event-db
-  ::movement-leave-cell
-  (fn [db [_ c r]]
-    (println "::movement-leave-cell" c r)
-    (-> db
-        (assoc-in [:position :cursor] nil)
-        (assoc-in [:position :selection] nil)
-        (update-in [:table-data] #(utils/reset-references % c r))
-        (update-in [:table-data] #(utils/evaluate-from-cell % c r)))))
-
+ ::movement-leave-cell
+ (fn [db [_ c r]]
+   (println "::movement-leave-cell" c r)
+   (-> db
+       (assoc-in [:position :cursor] nil)
+       (assoc-in [:position :selection] nil)
+       (update-in [:table-data] #(utils/reset-references % c r))
+       (update-in [:table-data] #(utils/evaluate-from-cell % c r)))))
 
 
 (re-frame/reg-event-db
 (re-frame/reg-event-db
-  ::edit-cell-value
-  (fn [db [_ c r value]]
-    (println "::edit-cell-value" c r value)
-    (update-in db [:table-data] #(utils/change-datum-value % c r value))))
+ ::edit-cell-value
+ (fn [db [_ c r value]]
+   (println "::edit-cell-value" c r value)
+   (update-in db [:table-data] #(utils/change-datum-value % c r value))))
 
 
 ; handle pressing enter (move to the next cell down)
 ; handle pressing enter (move to the next cell down)
 ; tab is taken care of natively, and is good enough
 ; tab is taken care of natively, and is good enough
 (re-frame/reg-event-fx
 (re-frame/reg-event-fx
-  ::press-enter-in-cell
-  (fn [{:keys [db]} [_ c r]]
-    (let [max-row? (= (utils/highest-row (:table-data db)) r)
-          max-col? (= (utils/highest-col (:table-data db)) c)
-          new-col (if max-row?
-                    (if max-col?
-                      "A"
-                      (utils/next-letter c))
-                    c)
-          new-row (if max-row?
-                    1
-                    (inc r))]
-      (println "::press-enter-in-cell" c r)
-      {:focus-on-cell [new-col new-row]})))
+ ::press-enter-in-cell
+ (fn [{:keys [db]} [_ c r]]
+   (let [max-row? (= (utils/highest-row (:table-data db)) r)
+         max-col? (= (utils/highest-col (:table-data db)) c)
+         new-col (if max-row?
+                   (if max-col?
+                     "A"
+                     (utils/next-letter c))
+                   c)
+         new-row (if max-row?
+                   1
+                   (inc r))]
+     (println "::press-enter-in-cell" c r)
+     {:focus-on-cell [new-col new-row]})))
 
 
 (re-frame/reg-fx
 (re-frame/reg-fx
-  :focus-on-cell
-  (fn [[c r]]
-    (println "fx for :press-enter" c r)
-    (.focus (.getElementById js/document (str c r)))))
-
+ :focus-on-cell
+ (fn [[c r]]
+   (println "fx for :press-enter" c r)
+   (.focus (.getElementById js/document (str c r)))))
 
 
 (re-frame/reg-event-db
 (re-frame/reg-event-db
  ::set-controls-state
  ::set-controls-state

+ 16 - 16
frontend/src/cljs/microtables_frontend/subs.cljs

@@ -1,13 +1,13 @@
 (ns microtables-frontend.subs
 (ns microtables-frontend.subs
   (:require
   (:require
-   [re-frame.core :as re-frame]
-   [microtables-frontend.utils :as utils]))
+   [microtables-frontend.utils :as utils]
+   [re-frame.core :as re-frame]))
 
 
 (re-frame/reg-sub
 (re-frame/reg-sub
  ::controls-state
  ::controls-state
  (fn [db]
  (fn [db]
-  (println "reporting state of controls")
-  (:controls db)))
+   (println "reporting state of controls")
+   (:controls db)))
 
 
 (defn highlight-cells
 (defn highlight-cells
   "Modify all cells in data (set :view to :highlighted) that are within the given range."
   "Modify all cells in data (set :view to :highlighted) that are within the given range."
@@ -27,17 +27,17 @@
 
 
 ;TODO: insert other display mode data? ("value": formula (cursor), "display" (default): evaluated, "highlighted": in a selection (just a class?))
 ;TODO: insert other display mode data? ("value": formula (cursor), "display" (default): evaluated, "highlighted": in a selection (just a class?))
 (re-frame/reg-sub
 (re-frame/reg-sub
-  ::table-data
-  (fn [db]
-    (println "returning table data")
-    (let [data (:table-data db)
-          cursor (get-in db [:position :cursor])
-          selection (get-in db [:position :selection])
-          highlighted (if selection
-                        (highlight-cells data selection)
-                        data)]
-      (if cursor
-        (assoc-in highlighted [(:col cursor) (:row cursor) :view] :value)
-        highlighted))))
+ ::table-data
+ (fn [db]
+   (println "returning table data")
+   (let [data (:table-data db)
+         cursor (get-in db [:position :cursor])
+         selection (get-in db [:position :selection])
+         highlighted (if selection
+                       (highlight-cells data selection)
+                       data)]
+     (if cursor
+       (assoc-in highlighted [(:col cursor) (:row cursor) :view] :value)
+       highlighted))))
 
 
 
 

+ 75 - 54
frontend/src/cljs/microtables_frontend/utils.cljs

@@ -1,25 +1,33 @@
 (ns microtables-frontend.utils
 (ns microtables-frontend.utils
   (:require
   (:require
-   ["mathjs" :as mathjs]))
+   ["mathjs" :as mathjs]
+   [clojure.set :refer [intersection]]
+   [clojure.string :as string]))
 
 
 ; to add an npm package to shadow-cljs:
 ; to add an npm package to shadow-cljs:
 ; https://clojureverse.org/t/guide-on-how-to-use-import-npm-modules-packages-in-clojurescript/2298
 ; https://clojureverse.org/t/guide-on-how-to-use-import-npm-modules-packages-in-clojurescript/2298
 ; https://shadow-cljs.github.io/docs/UsersGuide.html#npm
 ; https://shadow-cljs.github.io/docs/UsersGuide.html#npm
 
 
-
 (defn highest-col
 (defn highest-col
   "Return the highest column (letter) for which there is a non-empty cell"
   "Return the highest column (letter) for which there is a non-empty cell"
   [data]
   [data]
   ; choose the "max" (alphabetical order) value among the longest keys
   ; choose the "max" (alphabetical order) value among the longest keys
-  (apply max (val (apply max-key key (group-by #(.-length %) (keys data))))))
+  (->> data
+       keys
+       (group-by #(.-length %))
+       (apply max-key key)
+       val
+       (apply max)))
 
 
 (defn highest-row
 (defn highest-row
   "Return the highest row (number) for which there is a non-empty cell"
   "Return the highest row (number) for which there is a non-empty cell"
   [data]
   [data]
   ; get all the row keys from all the column objects (and flatten), then pick the max
   ; get all the row keys from all the column objects (and flatten), then pick the max
-  (apply max (flatten (map keys (vals data)))))
-
-
+  (->> data
+       vals
+       (map keys)
+       flatten
+       (apply max)))
 
 
 (defn increment-letter-code [s]
 (defn increment-letter-code [s]
   (let [l (last s)]
   (let [l (last s)]
@@ -28,13 +36,15 @@
       (= l 90) (conj (increment-letter-code (subvec s 0 (dec (count s)))) 65)
       (= l 90) (conj (increment-letter-code (subvec s 0 (dec (count s)))) 65)
       :else (conj (subvec s 0 (dec (count s))) (inc l)))))
       :else (conj (subvec s 0 (dec (count s))) (inc l)))))
 
 
-
 (defn next-letter [lc]
 (defn next-letter [lc]
-  (apply str (map char (increment-letter-code (mapv #(.charCodeAt % 0) lc)))))
-
-
-(def col-letters (iterate next-letter "A"))
+  (->> lc
+       (mapv #(.charCodeAt % 0))
+       increment-letter-code
+       (map char)
+       (apply str)))
 
 
+(def col-letters
+  (iterate next-letter "A"))
 
 
 (defn order-two-cols
 (defn order-two-cols
   "Accepts two column names (letters) and returns them in order."
   "Accepts two column names (letters) and returns them in order."
@@ -52,8 +62,8 @@
         start-row (min row1 row2)
         start-row (min row1 row2)
         end-row (max row1 row2)]
         end-row (max row1 row2)]
     (for [col (take-while #(not= (next-letter end-col) %) (iterate next-letter start-col))
     (for [col (take-while #(not= (next-letter end-col) %) (iterate next-letter start-col))
-             row (range start-row (inc end-row))]
-         {:col col :row row})))
+          row (range start-row (inc end-row))]
+      {:col col :row row})))
 
 
 ; the order goes top to bottom, then left to right - that makes the most sense to me
 ; the order goes top to bottom, then left to right - that makes the most sense to me
 ; I don't know why a different order would be important, or even in what situation order is important at all
 ; I don't know why a different order would be important, or even in what situation order is important at all
@@ -69,17 +79,19 @@
 (def range->commalist
 (def range->commalist
   "Converts a range in \"A1:B2\" notation to a comma-separated list of cells: \"A1,A2,B1,B2\"."
   "Converts a range in \"A1:B2\" notation to a comma-separated list of cells: \"A1,A2,B1,B2\"."
   (memoize (fn [range-string]
   (memoize (fn [range-string]
-            (let [cell-list (parse-range range-string)
-                  strings (map #(str (:col %) (:row %)) cell-list)]
-             (str "(" (clojure.string/join "," strings) ")")))))
+             (let [cell-list (parse-range range-string)
+                   strings (map #(str (:col %) (:row %)) cell-list)]
+               (str "(" (string/join "," strings) ")")))))
 
 
 (def replace-ranges-in-expression
 (def replace-ranges-in-expression
   "Receives an expression string, and replaces all ranges in colon notation (\"A1:B2\") into a comma-separated list of cells (\"A1,A2,B1,B2\")."
   "Receives an expression string, and replaces all ranges in colon notation (\"A1:B2\") into a comma-separated list of cells (\"A1,A2,B1,B2\")."
   (memoize (fn [expression]
   (memoize (fn [expression]
-             (clojure.string/replace expression #"\(\s*[A-Z]+[0-9]+\s*:\s*[A-Z]+[0-9]+\s*\)" range->commalist))))
+             (string/replace expression #"\(\s*[A-Z]+[0-9]+\s*:\s*[A-Z]+[0-9]+\s*\)" range->commalist))))
 
 
 (defn formula?
 (defn formula?
-  "Determines if a value is a fomula. If it is, it returns it (without the leading equals sign. If not, it returns nil."
+  "Determines if a value is a fomula.
+  If it is, it returns it (without the leading equals sign).
+  If not, it returns nil."
   [value]
   [value]
   (if (= (first value) "=")
   (if (= (first value) "=")
     (subs value 1)
     (subs value 1)
@@ -92,7 +104,6 @@
                                   (map #(.toUpperCase %) $)
                                   (map #(.toUpperCase %) $)
                                   (filter #(re-matches #"[A-Z]+[0-9]+" %) $)))))
                                   (filter #(re-matches #"[A-Z]+[0-9]+" %) $)))))
 
 
-
 (def str->rc (memoize (fn [s]
 (def str->rc (memoize (fn [s]
                         (let [c (re-find #"^[A-Z]+" s)
                         (let [c (re-find #"^[A-Z]+" s)
                               r (.parseInt js/window (re-find #"[0-9]+$" s))]
                               r (.parseInt js/window (re-find #"[0-9]+$" s))]
@@ -124,6 +135,7 @@
     (let [target (first refs)
     (let [target (first refs)
           de-notified (update-in data [(:col target) (:row target) :inbound] (partial filter #(not= % origin)))]
           de-notified (update-in data [(:col target) (:row target) :inbound] (partial filter #(not= % origin)))]
       (recur de-notified origin (rest refs)))))
       (recur de-notified origin (rest refs)))))
+
 (defn notify-references
 (defn notify-references
   "Update references in all cells referenced by this cell"
   "Update references in all cells referenced by this cell"
   [data origin refs]
   [data origin refs]
@@ -132,38 +144,45 @@
     (let [target (first refs)
     (let [target (first refs)
           notified (update-in data [(:col target) (:row target) :inbound] conj origin)]
           notified (update-in data [(:col target) (:row target) :inbound] conj origin)]
       (recur notified origin (rest refs)))))
       (recur notified origin (rest refs)))))
+
 (defn create-all-references
 (defn create-all-references
-  "Starting from a clean slate, add in all references. This wipes any references that may have been present."
+  "Starting from a clean slate, add in all references.
+  This wipes any references that may have been present."
   [data]
   [data]
   (reduce-kv
   (reduce-kv
-    (fn [columns c curr-column]
-      (assoc columns c (reduce-kv
-                         (fn [rows r datum]
-                           (assoc rows r (add-references (dissoc (dissoc datum :refs) :inbound))))
-                         {}
-                         curr-column)))
-    {}
-    data))
+   (fn [columns c curr-column]
+     (assoc columns c (reduce-kv
+                       (fn [rows r datum]
+                         (assoc rows r (add-references (dissoc (dissoc datum :refs) :inbound))))
+                       {}
+                       curr-column)))
+   {}
+   data))
 
 
 ;TODO: re-write create-all-references to use walk-modify-data instead
 ;TODO: re-write create-all-references to use walk-modify-data instead
 (defn walk-modify-data
 (defn walk-modify-data
   "Walks through the data map and updates each datum by applying f (a function accepting col, row, datum)."
   "Walks through the data map and updates each datum by applying f (a function accepting col, row, datum)."
   [data f]
   [data f]
   (reduce-kv
   (reduce-kv
-    (fn [columns c curr-column]
-      (assoc columns c (reduce-kv
-                         (fn [rows r datum]
-                           (assoc rows r (f c r datum)))
-                         {}
-                         curr-column)))
-    {}
-    data))
-
+   (fn [columns c curr-column]
+     (assoc columns c (reduce-kv
+                       (fn [rows r datum]
+                         (assoc rows r (f c r datum)))
+                       {}
+                       curr-column)))
+   {}
+   data))
 
 
 (defn walk-get-refs
 (defn walk-get-refs
   "Walks through the data map and returns a list of :col/:row maps for each cell which satisfies the predicate (a function accepting col, row, datum)."
   "Walks through the data map and returns a list of :col/:row maps for each cell which satisfies the predicate (a function accepting col, row, datum)."
   [data pred]
   [data pred]
-  (reduce-kv (fn [l c column] (concat l (map (fn [[r _]] {:col c :row r}) (filter (fn [[r datum]] (pred c r datum)) column)))) '() data))
+  (reduce-kv (fn [l c column]
+               (->> column
+                    (filter (fn [[r datum]] (pred c r datum)))
+                    (map (fn [[r _]] {:col c :row r}))
+                    (concat l)))
+             '()
+             data))
 
 
 ; proposed alternative (the beginning of one) to walk-get-refs
 ; proposed alternative (the beginning of one) to walk-get-refs
 ;(defn col-map? [m] (and (map? m) (every? #(and (string? %) (re-matches #"[A-Z]+" %)) (keys m))))
 ;(defn col-map? [m] (and (map? m) (every? #(and (string? %) (re-matches #"[A-Z]+" %)) (keys m))))
@@ -183,7 +202,8 @@
         (recur updated-one (rest formulas))))))
         (recur updated-one (rest formulas))))))
 
 
 (defn set-dirty-flags
 (defn set-dirty-flags
-  "Sets the target cell to \"dirty\" and recursively repeat with its back-references all the way up. Returns the new data set."
+  "Sets the target cell to \"dirty\" and recursively repeat with its back-references all the way up.
+  Returns the new data set."
   ([data c r]
   ([data c r]
    (set-dirty-flags data (list {:col c :row r})))
    (set-dirty-flags data (list {:col c :row r})))
   ([data queue]
   ([data queue]
@@ -199,7 +219,6 @@
                new-queue (concat (rest queue) (:inbound datum))]
                new-queue (concat (rest queue) (:inbound datum))]
            (recur new-data new-queue)))))))
            (recur new-data new-queue)))))))
 
 
-
 (defn change-datum-value
 (defn change-datum-value
   "Modify the value of a datum in the table, and update all applicable references"
   "Modify the value of a datum in the table, and update all applicable references"
   [data c r value]
   [data c r value]
@@ -224,28 +243,29 @@
 (defn remove-valueless-range-elements
 (defn remove-valueless-range-elements
   "Remove nil values specifically from ranges (to solve issues with some functions like average)."
   "Remove nil values specifically from ranges (to solve issues with some functions like average)."
   [variables var-list]
   [variables var-list]
-  (let [l (clojure.string/split (clojure.string/replace (first var-list) #"[()]" "") #",")
+  (let [l (string/split (string/replace (first var-list) #"[()]" "") #",")
         has-values (filter #(not (nil? (variables %))) l)]
         has-values (filter #(not (nil? (variables %))) l)]
-    (str "(" (clojure.string/join "," has-values) ")")))
-
-
+    (str "(" (string/join "," has-values) ")")))
 
 
 (defn preprocess-expression
 (defn preprocess-expression
   "Handle range cases, rename certain functions (to work with math.js), prepare expression and variables for processing."
   "Handle range cases, rename certain functions (to work with math.js), prepare expression and variables for processing."
   [expression variables]
   [expression variables]
-  (let [renamed-expression (clojure.string/replace expression #"\baverage\(" "mean(")
-        new-expression (clojure.string/replace renamed-expression #"\(([A-Z]+[0-9]+,)*[A-Z]+[0-9]+\)" (partial remove-valueless-range-elements variables))
+  (let [renamed-expression (string/replace expression #"\baverage\(" "mean(")
+        new-expression (string/replace renamed-expression
+                                       #"\(([A-Z]+[0-9]+,)*[A-Z]+[0-9]+\)"
+                                       (partial remove-valueless-range-elements variables))
         new-variables (reduce-kv #(assoc %1 %2 (if (nil? %3) "0" %3)) {} variables)]
         new-variables (reduce-kv #(assoc %1 %2 (if (nil? %3) "0" %3)) {} variables)]
     (println "PREPROCESS" {:expression new-expression :variables new-variables})
     (println "PREPROCESS" {:expression new-expression :variables new-variables})
     {:expression new-expression
     {:expression new-expression
      :variables new-variables}))
      :variables new-variables}))
 
 
-
 (def evaluate-expression
 (def evaluate-expression
-  "Convert (via mathjs) an expression string to a final answer (also a string).  A map of variables must also be provided. If there is an error, it will return :calc-error."
+  "Convert (via mathjs) an expression string to a final answer (also a string).
+  A map of variables must also be provided. If there is an error, it will return :calc-error."
   (memoize (fn [expression variables]
   (memoize (fn [expression variables]
              (let [range-replaced (replace-ranges-in-expression expression)
              (let [range-replaced (replace-ranges-in-expression expression)
-                   {ready-expression :expression ready-variables :variables} (preprocess-expression range-replaced variables)]
+                   {ready-expression :expression
+                    ready-variables :variables} (preprocess-expression range-replaced variables)]
                (try
                (try
                  (.evaluate mathjs ready-expression (clj->js ready-variables))
                  (.evaluate mathjs ready-expression (clj->js ready-variables))
                  (catch js/Error e
                  (catch js/Error e
@@ -264,14 +284,15 @@
          current {:col c :row r}
          current {:col c :row r}
          this-and-above (conj ancest current)
          this-and-above (conj ancest current)
          inbound (:inbound datum)
          inbound (:inbound datum)
-         found-repeat (not (empty? (clojure.set/intersection this-and-above (set inbound))))]
+         found-repeat (not (empty? (intersection this-and-above (set inbound))))]
      (if found-repeat
      (if found-repeat
        :cycle-error
        :cycle-error
        (some #(find-cycle data (:col %) (:row %) this-and-above) inbound)))))
        (some #(find-cycle data (:col %) (:row %) this-and-above) inbound)))))
 
 
-
 (defn gather-variables-and-evaluate-cell
 (defn gather-variables-and-evaluate-cell
-  "Assumes that all the cell's immediate references have been resolved. Collects the final values from them, then evaluates the current cell's expression. Returns the new data map."
+  "Assumes that all the cell's immediate references have been resolved.
+  Collects the final values from them, then evaluates the current cell's expression.
+  Returns the new data map."
   [data c r]
   [data c r]
   (let [datum (dissoc (dissoc (get-in data [c r]) :dirty) :display) ; get rid of the dirty flag right away (it must be included with the returned data to have effect)
   (let [datum (dissoc (dissoc (get-in data [c r]) :dirty) :display) ; get rid of the dirty flag right away (it must be included with the returned data to have effect)
         refs (:refs datum)
         refs (:refs datum)
@@ -302,7 +323,6 @@
                   new-datum (assoc datum :display evaluated-value)]
                   new-datum (assoc datum :display evaluated-value)]
               (assoc-in data [c r] new-datum)))))
               (assoc-in data [c r] new-datum)))))
 
 
-
 ; THE NEW EVALUATE FUNCTION
 ; THE NEW EVALUATE FUNCTION
 ; - check for cycles in the back references, starting from the target cell (if any, use another function to mark it and its back references with :cycle-error and remove :dirty)
 ; - check for cycles in the back references, starting from the target cell (if any, use another function to mark it and its back references with :cycle-error and remove :dirty)
 ; - if any of the forward references are dirty, mark the cell (and recurse up) with an error (and set a TODO to think about this further)
 ; - if any of the forward references are dirty, mark the cell (and recurse up) with an error (and set a TODO to think about this further)
@@ -341,7 +361,8 @@
 
 
 ;TODO: does this need a cycle check?
 ;TODO: does this need a cycle check?
 (defn evaluate-all
 (defn evaluate-all
-  "Evaluates all cells marked as \"dirty\". Generally reserved for the initialization."
+  "Evaluates all cells marked as \"dirty\".
+  Generally reserved for the initialization."
   ([data]
   ([data]
    (evaluate-all data (walk-get-refs data #(:dirty %3))))
    (evaluate-all data (walk-get-refs data #(:dirty %3))))
   ([data queue]
   ([data queue]

+ 7 - 9
frontend/src/cljs/microtables_frontend/views.cljs

@@ -1,10 +1,9 @@
 (ns microtables-frontend.views
 (ns microtables-frontend.views
   (:require
   (:require
-   [re-frame.core :as re-frame]
-   [microtables-frontend.subs :as subs]
    [microtables-frontend.events :as events]
    [microtables-frontend.events :as events]
-   [microtables-frontend.utils :as utils]))
-
+   [microtables-frontend.subs :as subs]
+   [microtables-frontend.utils :as utils]
+   [re-frame.core :as re-frame]))
 
 
 ;; TABLE COMPONENTS
 ;; TABLE COMPONENTS
 
 
@@ -31,8 +30,8 @@
 (defn header-row [cols]
 (defn header-row [cols]
   ^{:key "header"} [:tr
   ^{:key "header"} [:tr
                     (cons
                     (cons
-                      ^{:key "corner"} [:th]
-                      (map (fn [c] ^{:key (str "col-head-" c)} [:th c]) cols))])
+                     ^{:key "corner"} [:th]
+                     (map (fn [c] ^{:key (str "col-head-" c)} [:th c]) cols))])
 
 
 (defn sheet [data]
 (defn sheet [data]
   [:table
   [:table
@@ -44,9 +43,8 @@
           maxcol "Z";(utils/highest-col data)
           maxcol "Z";(utils/highest-col data)
           cols (take-while (partial not= (utils/next-letter maxcol)) utils/col-letters)]
           cols (take-while (partial not= (utils/next-letter maxcol)) utils/col-letters)]
       (cons
       (cons
-        (header-row cols)
-        (map #(row % cols data) (range 1 (inc maxrow)))))]])
-
+       (header-row cols)
+       (map #(row % cols data) (range 1 (inc maxrow)))))]])
 
 
 (defn extend-range
 (defn extend-range
   []
   []