How to correctly align column containing both unicode character and empty list ()

Viewed 64

I found that it is very difficult to align column if the row contains value which is a NIL

I try specified column width, however, in the output, NIL seems always has different width than other unicode characters so that always won't align properly. Is there a method to achieve better alignment? (yes I would prefer empty list to print out as NIL)

Thanks.

(progn
  (format t "~?" "~5@a ~5@a ~5@a ~5@a ~5@a~%" '(蘋果 () 桔子 () 西瓜))
  (format t "~?" "~5@a ~5@a ~5@a ~5@a ~5@a~%" '(() 茄子 () 菠菜 () 苦瓜)))

OUTPUT (Column not aligned even column width has already been specified 
   蘋果   NIL    桔子   NIL    西瓜
  NIL    茄子   NIL    菠菜   NIL

Would be expecting OUTPUT aligned like below (with NIL occupy the same width as specified) :
 
   蘋果   NIL    桔子   NIL   西瓜
   NIL   茄子    NIL   菠菜   NIL
1 Answers

I observed that the string formatting of () to NIL takes 3 characters, where the others take 2, so I tried changing the () padding to ~6@a. It turns out it works better:

(length (format nil "~a" nil))
3

(progn
  (format t "~?" "~5@a ~6@a ~5@a ~6@a ~5@a~%" '(蘋果 () 桔子 () 西瓜))
  (format t "~?" "~6@a ~5@a ~6@a ~5@a ~6@a~%" '(() 茄子 () 菠菜 () 苦瓜)))
   蘋果    NIL    桔子    NIL    西瓜
   NIL    茄子    NIL    菠菜    NIL

The width of latin and non-latin characters are different (see last column specifically), but the columns look aligned now.

So, you have to pre-calculate the padding for each entry.

You can use the ~v directive to insert a variable inside a directive .

(let ((padding 30))
    (format nil "~va" padding "foo"))
;; "foo                           "

(source: Cookbook)

Related