Search code examples
printingcommon-lisp

Table printing a list of lists Common lisp


I wish to print this data in a table with the columns aligned. I tried with Format but the columns were not aligned. Does anyone know how to do it ? Thank you.

(("tiscali" 10000 2.31 0.84 -14700.0 "none")
 ("atlantia" 50 22.65 22.68 1.5 "none")
 ("bper-banca" 1000 1.59 2.01 423.0 "none")
 ("alerion-cleanpower" 30 44.14 36.45 -230.7   "none")
 ("tesmec" 10000 0.12 0.14 150.0 "none")
 ("cover-50" 120 8.95 9.6 78.0 "none")
 ("ovs" 1000 1.71 1.93 217.0 "none")
 ("credito-emiliano" 200 5.7 6.26 112.0 "none"))

I tried to align the columns wit the ~T directive, no way. Is there a piece of code that prints nicely table data?


Solution

  • Let's break this down.

    First, let's give your data a nice name:

    (defparameter *data* 
        '(("tiscali" 10000 2.31 0.84 -14700.0 "none")
          ("atlantia" 50 22.65 22.68 1.5 "none")
          ("bper-banca" 1000 1.59 2.01 423.0 "none")
          ("alerion-cleanpower" 30 44.14 36.45 -230.7   "none")
          ("tesmec" 10000 0.12 0.14 150.0 "none")
          ("cover-50" 120 8.95 9.6 78.0 "none")
          ("ovs" 1000 1.71 1.93 217.0 "none")
          ("credito-emiliano" 200 5.7 6.26 112.0 "none")))
    

    Now, come up with a way to print each line using format and destructuring-bind. Widths of various fields are hard-coded in.

    (defun print-line (line)
        (destructuring-bind (a b c d e f) line
            (format T "~20a ~5d ~6,2f ~6,2f ~10,2f ~4a~%"  a b c d e f)))
    

    Once you know you can print a line, you just need to do that for each line.

    (mapcar 'print-line *data*)
    

    Result:

    tiscali              10000   2.31   0.84  -14700.00 none
    atlantia                50  22.65  22.68       1.50 none
    bper-banca            1000   1.59   2.01     423.00 none
    alerion-cleanpower      30  44.14  36.45    -230.70 none
    tesmec               10000   0.12   0.14     150.00 none
    cover-50               120   8.95   9.60      78.00 none
    ovs                   1000   1.71   1.93     217.00 none
    credito-emiliano       200   5.70   6.26     112.00 none