Created
March 5, 2015 16:02
-
-
Save yogthos/5bacdfae6472262bada0 to your computer and use it in GitHub Desktop.
ascii table renderer for clj-pdf table format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ascii-table) | |
(defn transpose [m] | |
(apply mapv vector m)) | |
(defn col-width [rows text-width] | |
(let [num-cols (-> rows first count)] | |
(int (/ (- text-width 2 (dec num-cols)) num-cols)))) | |
(defn height [length width] | |
(if (<= length width) | |
1 | |
(int (+ (/ length width) (if (pos? (mod length width)) 1 0))))) | |
(defn pad-text [width text] | |
(let [delta (- width (count text))] | |
(if (pos? delta) | |
(concat text (repeat delta " ")) | |
text))) | |
(defn partition-col [col width] | |
(let [partitioned (vec (partition-all width col))] | |
(map (partial apply str) | |
(update-in partitioned [(dec (count partitioned))] (partial pad-text width))))) | |
(defn set-column-height [width padding row] | |
(let [text-length (apply max (map count row)) | |
num-lines (height text-length width)] | |
(for [col row] | |
(let [col-height (height (count col) width)] | |
(concat (partition-col col width) | |
(repeat (- num-lines col-height) padding)))))) | |
(defn col-to-text [col & [text]] | |
(cond | |
(coll? col) | |
(apply str (map col-to-text (if (map? (second col)) (drop 2 col) (rest col)))) | |
:else | |
(if text (str text " " col) col))) | |
(defn cols-to-text [row] | |
(map col-to-text row)) | |
(defn to-table [[_ {:keys [header]} & rows] text-width] | |
(let [rows (map cols-to-text (if header (cons header rows) rows)) | |
width (col-width rows text-width) | |
padding (clojure.string/join (repeat width " "))] | |
(map (partial set-column-height width padding) rows))) | |
(defn ascii-table [table width] | |
(let [sb (StringBuilder.) | |
rows (to-table table width) | |
col-count (count (first rows)) | |
col-width (count (first (ffirst rows))) | |
width (+ (inc col-count) (* col-count col-width))] | |
(.append sb (apply str (repeat width "-"))) | |
(.append sb "\n") | |
(doseq [row rows] | |
(doseq [col (transpose row)] | |
(.append sb "|") | |
(doseq [line (interpose "|" col)] | |
(.append sb line)) | |
(.append sb "|\n")) | |
(.append sb (apply str (repeat width "-"))) | |
(.append sb "\n")) | |
(.toString sb))) | |
;;example usage | |
#_(def data | |
[:table {:header ["Row 1" "Row 2" "Row 3"] :width 50 :border false :cell-border false} | |
[[:cell {:colspan 2} "Foo"] "Bar" "baz"] | |
["12345678910" "bar1" "baz1"] | |
["foo2" "bar212345566" "baz2"] | |
["foo4" "bar212345566" "ba234324z2"]]) | |
#_(spit "table.txt" (ascii-table data 80)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment