Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defmacro defcolumn [header records]
- `(def ~header
- (let [header-str# (str (quote ~header))
- size# (+ 3 (apply max (map count (cons header-str# ~records))))
- hoffset# (int (- (/ size# 2) (/ (count header-str#) 2)))
- size# (if (< hoffset# 2) (inc size#) size#)
- hoffset# (if (< hoffset# 2) 2 hoffset#)]
- {:header header-str# :records ~records :size size# :offset hoffset#})))
- (defn pad [len c] (apply str (repeat len c)))
- (defn col-rep [column]
- (letfn [(rec-rep [siz off rec]
- (let [len (- siz (+ off (count rec)))]
- (str (pad off \ ) rec (pad len \ ) "|")))]
- (let [grec-rep1 (partial rec-rep (:size column))
- grec-rep2 (partial grec-rep1 1)
- nil-rep (grec-rep2 "nil")
- recs-rep (cons (grec-rep1 (:offset column) (:header column))
- (map grec-rep2 (:records column)))]
- {:nil-rep nil-rep :recs-rep recs-rep})))
- (defn table [cols]
- (letfn [(get-record [col]
- (if (empty? (:recs-rep col)) (:nil-rep col)
- (first (:recs-rep col))))]
- (if (empty? (remove #(< (count %) 2) (map :recs-rep cols)))
- [(map get-record cols)]
- (lazy-cat [(map get-record cols)]
- (table (map #(assoc % :recs-rep (rest (:recs-rep %)))
- cols))))))
- (defmacro deftable [name columns] `(def ~name (table (map col-rep ~columns))))
- (defn prn-table [t]
- (let [header (apply str (first t))
- len (count header)
- border (str "+" (pad (- len 1) \-) "+")
- prn-rec (fn [rec] (prn (apply str "|" rec)))]
- (doall
- ((prn border)
- (prn-rec header)
- (prn border)
- (doall (map prn-rec (rest t)))
- (prn border)))))
- (comment
- (use 'programthis.table)
- (defcolumn ingredients ["milk" "eggs" "butter"])
- (defcolumn substitutes ["splenda"])
- (deftable t [ingredients substitutes])
- (prn-table t)
- (defcolumn small ["short" "a really long record" "short again"])
- (deftable t [ingredients substitutes small])
- (prn-table t)
- )
Add Comment
Please, Sign In to add comment