Guest User

Untitled

a guest
Sep 1st, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defmacro defcolumn [header records]
  2.   `(def ~header
  3.      (let [header-str# (str (quote ~header))
  4.            size# (+ 3 (apply max (map count (cons header-str# ~records))))
  5.            hoffset# (int (- (/ size# 2) (/ (count header-str#) 2)))
  6.            size# (if (< hoffset# 2) (inc size#) size#)
  7.            hoffset# (if (< hoffset# 2) 2 hoffset#)]
  8.        {:header header-str# :records ~records :size size# :offset hoffset#})))
  9.  
  10. (defn pad [len c] (apply str (repeat len c)))
  11.  
  12. (defn col-rep [column]
  13.   (letfn [(rec-rep [siz off rec]
  14.                    (let [len (- siz (+ off (count rec)))]
  15.                      (str (pad off \ ) rec (pad len \ ) "|")))]
  16.     (let [grec-rep1 (partial rec-rep (:size column))
  17.           grec-rep2 (partial grec-rep1 1)
  18.           nil-rep (grec-rep2 "nil")
  19.           recs-rep (cons (grec-rep1 (:offset column) (:header column))
  20.                          (map grec-rep2 (:records column)))]
  21.       {:nil-rep nil-rep :recs-rep recs-rep})))
  22.  
  23. (defn table [cols]
  24.   (letfn [(get-record [col]
  25.                       (if (empty? (:recs-rep col)) (:nil-rep col)
  26.                         (first (:recs-rep col))))]
  27.     (if (empty? (remove #(< (count %) 2) (map :recs-rep cols)))
  28.       [(map get-record cols)]
  29.       (lazy-cat [(map get-record cols)]
  30.                 (table (map #(assoc % :recs-rep (rest (:recs-rep %)))
  31.                             cols))))))
  32.  
  33. (defmacro deftable [name columns] `(def ~name (table (map col-rep ~columns))))
  34.  
  35. (defn prn-table [t]
  36.   (let [header (apply str (first t))
  37.         len (count header)
  38.         border (str "+" (pad (- len 1) \-) "+")
  39.         prn-rec (fn [rec] (prn (apply str "|" rec)))]
  40.     (doall
  41.       ((prn border)
  42.       (prn-rec header)
  43.       (prn border)
  44.       (doall (map prn-rec (rest t)))
  45.       (prn border)))))
  46.  
  47. (comment
  48. (use 'programthis.table)
  49. (defcolumn ingredients ["milk" "eggs" "butter"])
  50.  
  51. (defcolumn substitutes ["splenda"])
  52. (deftable t [ingredients substitutes])
  53. (prn-table t)
  54. (defcolumn small ["short" "a really long record" "short again"])
  55. (deftable t [ingredients substitutes small])
  56. (prn-table t)
  57. )
Add Comment
Please, Sign In to add comment