Skip to content

Commit

Permalink
Support more data shapes directly
Browse files Browse the repository at this point in the history
- Vector-of-vectors will use the first row as the header row
- Plain maps will appear with "Key", "Value" headers
- Other values will just appear with a "Value" header
  • Loading branch information
jgdavey committed Jul 12, 2021
1 parent cf847c3 commit 86aa275
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- New table option `:max-width` to resize columns that would be too
big, defaults to terminal width if possible.
- Support more shapes of data directly, i.e. vector of vectors, or a
single map.

### Changed
- The RenderTable/render-table protocol method signature has changed.
Expand Down
5 changes: 3 additions & 2 deletions src/crockery/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[crockery.gfm :as gfm]
[crockery.tsv :as tsv]
[crockery.protocols :as p]
[crockery.util :refer [to-column-map normalize-column]]))
[crockery.util :refer [to-column-map normalize-column data->cols-rows]]))

(def ^:dynamic *default-options* {:format :org
:defaults {:align :left}})
Expand Down Expand Up @@ -83,12 +83,13 @@
(let [{:keys [format defaults] :as opts} (merge *default-options* opts)
renderer (get (builtin-renderers) format format)
;;_ (assert (satisfies? p/RenderTable renderer))
[detected-cols data] (data->cols-rows data)
cols (into [] (comp (map to-column-map)
(map #(merge defaults %))
(map normalize-column))
(or cols
(:columns opts)
(-> data first keys)))]
detected-cols))]
(p/render-table renderer opts cols data))))

(defn print-table
Expand Down
29 changes: 29 additions & 0 deletions src/crockery/util.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,35 @@
s
(pad-spaces (Math/ceil half-padding)))))))


(defn- non-string-seq? [coll]
(and (seqable? coll) (not (string? coll))))

(defn data->cols-rows [data]
(cond
(map? data)
[[:key :value]
(map (fn [[k v]] {:key k :value v}) data)]

(non-string-seq? data)
(let [f (first data)]
(cond
(map? f)
[(keys f)
data]

(non-string-seq? f)
[(map-indexed (fn [i h] {:name i :title h}) f)
(rest data)]

:else
[[:value]
(map (fn [v] {:value v}) data)]))

:else
[[:value]
[{:value data}]]))

(defn normalize-column [{:keys [key-fn title title-align align render-title render-cell] :as col}]
(let [nm (:name col)]
(merge col
Expand Down
45 changes: 45 additions & 0 deletions test/crockery/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,51 @@
people)
expected))))

(deftest test-vec-of-vecs
(let [expected ["|-----------+-----|"
"| Name | Age |"
"|-----------+-----|"
"| Alice | 29 |"
"| Bob | 22 |"
"| Charlotte | 42 |"
"|-----------+-----|"]
data (into [["Name" "Age"]]
(map (juxt :name :age))
people)]
(is (table? (table-as-string data) expected))))

(deftest test-vec-of-strings
(let [expected ["|-------|"
"| Value |"
"|-------|"
"| a |"
"| bbb |"
"| c |"
"|-------|"]
data ["a" "bbb" "c"]]
(is (table? (table-as-string data) expected))))

(deftest test-plain-map
(let [expected ["|---------+----------|"
"| Key | Value |"
"|---------+----------|"
"| :what | 1 |"
"| :are | 42 |"
"| :you | testtest |"
"| :Saying | 10.0 |"
"|---------+----------|"]
data {:what "1" :are 42 :you "testtest" :Saying 10.0}]
(is (table? (table-as-string data) expected))))

(deftest test-plain-value
(let [data #inst "2014-04-17T12:34:56.789-00:00"
expected ["|--------------------------|"
"| Value |"
"|--------------------------|"
"| 2014-04-17T12:34:56.789Z |"
"|--------------------------|"]]
(is (table? (table-as-string data) expected))))

(deftest test-alignment
(testing "Title alignment can differ"
(let [rendered (table-as-string [{:key-fn :name
Expand Down

0 comments on commit 86aa275

Please sign in to comment.