This question will probably end in a facepalm, but I've tried for a while and am still stuck despite reading through the hyperspec.
Basically what I want to do is something like
(format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890)))
but instead of hard-coding the 5 it should be calculated from the list (length of longest element from any nested list + 1) to give something like
| 1 23 2 312|
| 23 456 1 7890|
Maybe I'm thinking way too complicated here and there is an easier way to do what I want, but I think I ran myself into a mental corner that I can't get out of.
I think that you have two options: let the format
magic go and use other looping constructs or generate the format string itself:
(defun facepalm-printer (lol)
(format t (format nil "~~{|~~{ ~~~ad~~}|~~%~~}"
(longest-member lol))
lol))
The definition of longest-member
is left as an exercise to the reader.
Assuming the required width is bound to width
, then you can do this:
(format t "~{|~{ ~Vd~}|~%~}" width '((1 23 2 312) (23 456 1 7890)))
5
has been replaced by V
and width
has been added as an argument to FORMAT
/
edit: original answer did not correctly account for the nested directives
In a format control string V
may be used in place of any constant value, indicating that the corresponding value is to be taken from the argument list instead.
You can try this:
(setf width 5)
(setf data '((1 23 2 312) (23 456 1 7890)))
(format t "~{|~{ ~{~Vd~}~}|~%~}"
(mapcar #'(lambda (r) (mapcar #'(lambda (v) (list width v)) r)) data) )
This format string requires the desired width to precede each value. The (mapcar ...)
expression accomplishes this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With