You can do this with (format stream (format nil ...))
where you generate the format control for justification using format
:
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5)))
"|1 2 3 4 5|"
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5 6 7 8 9 10)))
"|1 2 3 4 5 6 7 8 9 10|"
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)))
"|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15|"
If you don't want to generate the whole format control for the outer format
, you can use some variant of ~?
to process a string and some arguments recursively:
CL-USER> (format nil "|~@?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5)))
"|1 2 3 4 5|"
CL-USER> (format nil "|~@?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5 6 7 8 9 10)))
"|1 2 3 4 5 6 7 8 9 10|"
CL-USER> (format nil "|~@?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)))
"|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15|"
The recursive processing with ~?
only allows you to process another format control with a list of arguments; it doesn't give you a way to splice in a new format string. It appears that the text that is justified has to be present in the control string, so you'd really need a way to splice in a control string that already contains the text that you want.
Although the first of these seems simpler, there is a danger in it because you're putting the printed text into another format string, and you're not doing that in the second case. In the first case, if any of those numbers were replaced with format directives, the outer format would try to process them. In the second case, this doesn't happen. As such, I think I'd suggest the second.