[Openmcl-devel] Building tables with format
Camille Troillard
tuscland at mac.com
Wed Aug 18 06:36:00 PDT 2004
Hi Hamilton,
Your solution inspired me, and I found a way to do just what I was
searching for (note that it is specific to OpenMCL), so here is the
code :
The arg is printed to a string of COLS constant width.
Padding is done with PADCHARs, with a minimum of MINPAD.
'@' and ':' options can be used and have the same meaning than in ~A
and ~S formatter options.
Use: ~COLS,MINPAD,PADCHAR#
Example: ; Simple tuncation.
CL-USER> (format nil "~10#" "azertyuiopqsdfghjklmwxcvbn")
"azertyuiop"
; Simple padding.
CL-USER> (format nil "~10#" "azerty")
"azerty "
; Padding occurs because we asked a minimum of 2 characters.
; PADCHAR is '-' here, (note the notation "'-").
; It can be specified by an ASCII code number too.
; MINPAD has no use here.
CL-USER> (format nil "~10,2,'-#" "azerty")
"azerty----"
; Same example as the latter, but MINPAD is useful here.
CL-USER> (format nil "~10,2,45#" "azertyuiopqsdfghjklmwxcvbn")
"azertyui--"
The code:
(in-package :cl-user)
(defun format-fixed-field (s arg atsignp cols minpad padchar)
(let* ((padding (max minpad (- cols (length arg))))
(width (- cols padding)))
(unless (characterp padchar)
(if (typep padchar `(integer 0 #.char-code-limit))
(setq padchar (code-char padchar))
(format-error "Padchar must be a character or integer from 0 to
~a - ~S"
char-code-limit padchar)))
(when atsignp
(loop for i below padding
do (write-char padchar s)))
(write-string (subseq arg 0 (min width (length arg))) s)
(unless atsignp
(loop for i below padding
do (write-char padchar s)))))
(ccl::defformat #\# format-fixed (stream colon atsign &rest parms)
(declare (dynamic-extent parms))
(let ((arg (ccl::pop-format-arg)))
(if (null parms)
(princ (or arg (if colon "()" nil)) stream)
(ccl::with-format-parameters parms ((cols 0) (minpad 0) (padchar
#\space))
(format-fixed-field
stream
(if (or arg (not colon))
(princ-to-string arg)
"()")
atsign cols minpad padchar)))))
Best Regards,
Camille
On 18 août 04, at 05:56, Hamilton Link wrote:
> Wow, good question! I love format. Mind you I never write a format
> control string without CLTL2 handy...
>
> After much searching, and deciding there was no straightforward way of
> doing as you yourself discovered, I revisited the pretty printing
> chapter of CLTL2. I think ~/.../ may do what you need. Look in section
> 27.4 of CLTL2, and check this out:
>
> ? (defun chop (s arg &optional colonp atsignp &rest parameters)
> (print s)
> (print arg)
> (print colonp)
> (print atsignp)
> (print parameters)
> (let ((full-result (format nil "~a" arg)))
> (format s "~a" (subseq full-result 0 (min 10 (length
> full-result))))))
> CHOP
> ? (format nil "~1,2,3:@/CHOP/" "This string is far, far too long!")
> ;; this was all my debugging output
> #<STRING-OUTPUT-STREAM #x8155244E>
> "This string is far, far too long!"
> T
> T
> (1 2 3)
> ;; this was what was printed by the format command, using CHOP
> "This strin"
> ?
>
> And of course you could make chop take minlength, maxlength, and
> padchar as parameters and DWYM.
>
> h
>
> On Aug 17, 2004, at 10:06 AM, Camille Troillard wrote:
>
>> Hello,
>>
>> I fear my question is a little bit off topic.
>>
>> I would like to output a table with fixed-width cells. This means I
>> need to truncate string arguments in order to keep the cell width
>> constant. FORMAT offers a way to add a padding, but there is not way
>> to truncate a string argument (I would have used an option to the ~A
>> or ~S directives).
>>
>> Is there any way to extend OpenMCL's FORMAT mechanism in order to do
>> just that?
>>
>>
>> Thanks for your help,
>> Camille
>>
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel
>>
>
More information about the Openmcl-devel
mailing list