From: Vladimir Zolotykh
Subject: format: fill the text
Date: 
Message-ID: <20060617162245.2c5dd118.gsmith@eurocom.od.ua>
Frequently find myself in need to get some text in a string filled
within proper bounds. Skimmed through CLHS 22.3 Section "Formatted
Output" and found "22.3.5.2 Tilde Less-Than-Sign: Logical
Block". Which says

  "~<...~:> supports a feature not supported by
   pprint-logical-block. If ··@> is used to terminate the directive
   (i.e., ~<·····@>), then a fill-style conditional newline is
   automatically inserted after each group of blanks immediately
   contained in the body (except for blanks after a <Newline>
   directive). This makes it easy to achieve the equivalent of
   paragraph filling."

However, what they suggest there seems don't work (ACL80) or, maybe, I
used it improperly?

  cl-user(93): (format nil "~<Art expert Prof. Christopher Cornford, of the Royal College of Art, analyzed the painting and found a complex underlying geometry based on the ···········@>")
  "#<Printer Error, obj=#x71000685: Insufficient format args>"
  cl-user(94): 

After peeking in someone else's code found that using ·@< might help

  (let ((*print-right-margin* 52))
    (format nil ··@<Art expert Prof. Christopher Cornford, of the Royal College of Art, analyzed the painting and found a complex underlying geometry based on the ···········@>"))

the above form gives the text properly filled. Not quite sure which is
right? What I read in CLHS or what I get in the CL implementation
(ACL80) ?

Unfortunately, the ·@<·····@> doesn't fill the string supplied as an
argument to FORMAT directive.

  (let ((*print-right-margin* 52)
	(m "Art expert Prof. Christopher Cornford, of the Royal College of Art, analyzed the painting and found a complex underlying geometry based on the pentagon."))
    (format nil ··@<····@>" m))

Could you please advise how to fill a text if it is already a variable
(as in the last example)?

The only way to do that I could think of is

  (let ((*print-right-margin* 52)
	(m "Art expert Prof. Christopher Cornford, of the Royal College of Art, analyzed the painting and found a complex underlying geometry based on the pentagon."))
    (format nil ··@<~{~A~^ ····@>" (split-into-words m)))

However, it inserts extra spaces and I don't think I'll ever be able
to remember ·@<~{~A~^ ····@>" ;-)


-- 
Vladimir Zolotykh
From: Thomas A. Russ
Subject: Re: format: fill the text
Date: 
Message-ID: <ymilkrt7yoj.fsf@sevak.isi.edu>
Vladimir Zolotykh <······@eurocom.od.ua> writes:

> Frequently find myself in need to get some text in a string filled
> within proper bounds. Skimmed through CLHS 22.3 Section "Formatted
> Output" and found "22.3.5.2 Tilde Less-Than-Sign: Logical
> Block". Which says
...
> Could you please advise how to fill a text if it is already a variable
> (as in the last example)?
> 
> The only way to do that I could think of is
> 
>   (let ((*print-right-margin* 52)
> 	(m "Art expert Prof. Christopher Cornford, of the Royal College of Art, analyzed the painting and found a complex underlying geometry based on the pentagon."))
        >     (format nil ··@<~{~A~^ ····@>" (split-into-words m)))

Well, the other alternative would be to use nested formats.  One format
which builds the format string (note the doubled ~ characters), and then
executes it:

  (let ((*print-right-margin* 52)
	(m "Art expert Prof. Christopher Cornford, of the Royal College of Art, analyzed the painting and found a complex underlying geometry based on the pentagon."))

    (format nil (format nil ···@<·····@>" m)))

==>
"Art expert Prof. Christopher Cornford, of the Royal
College of Art, analyzed the painting and found a
complex underlying geometry based on the pentagon."


> However, it inserts extra spaces and I don't think I'll ever be able
> to remember ·@<~{~A~^ ····@>" ;-)

It's not so hard, especially if you already know the ~{~A~^ ~} idiom for
printing out list values.  It's useful enough to be worth having in
memory.  From there it's a simple step...


-- 
Thomas A. Russ,  USC/Information Sciences Institute