Common Lisp the Language, 2nd Edition
Next: Compiling Format
Control Up: Pretty
Printing Previous: Dynamic
Control of
The primary interface to operations for dynamically determining the
arrangement of output is provided through the functions above. However,
an additional interface is provided via a set of format directives
because, as shown by the examples in this section and the next,
format
strings are typically a much more compact way to
specify pretty printing. In addition, without such an interface, one
would have to abandon the use of format
when interacting
with the pretty printer.
~W
Write. An arg, any Lisp object, is printed obeying
every printer control variable (as by write
). In
addition, ~W
interacts correctly with depth abbreviation by
not resetting the depth counter to zero. ~W
does not accept
parameters. If given the colon modifier, ~W
binds
*print-pretty*
to t
. If given the atsign
modifier, ~W
binds *print-level*
and
*print-length*
to nil
.
~W
provides automatic support for circularity detection.
If *print-circle*
(and possibly also
*print-shared*
) is not nil
and ~W
is applied to an argument that is a circular (or shared) reference, an
appropriate ``#
n
#
’’
marker is inserted in the output instead of printing the argument.
~_
Conditional newline. Without any modifiers, ~_
is
equivalent to (pprint-newline :linear)
. The directive
~@_
is equivalent to (pprint-newline :miser)
.
The directive ~:_
is equivalent to
(pprint-newline :fill)
. The directive ~:@_
is
equivalent to (pprint-newline :mandatory)
.
~<
str
~:>
Logical block. If ~:>
is used to terminate a
~<...
directive, the directive is equivalent to a call
on pprint-logical-block
. The format
argument
corresponding to the ~<...~:>
directive is treated in
the same way as the list argument to
pprint-logical-block
, thereby providing automatic support
for non-list arguments and the detection of circularity, sharing, and
depth abbreviation. The portion of the format
control
string nested within the ~<...~:>
specifies the
:prefix
(or :per-line-prefix
),
:suffix
, and body of the
pprint-logical-block
.
The format
string portion enclosed by
~<...~:>
can be divided into segments
~<
prefix
~;
body
~;
suffix
~:>
by ~;
directives. If the first section is terminated by
~@;
, it specifies a per-line prefix rather than a simple
prefix. The prefix and suffix cannot contain format
directives. An error is signaled if either the prefix or suffix fails to
be a constant string or if the enclosed portion is divided into more
than three segments.
If the enclosed portion is divided into only two segments, the suffix
defaults to the null string. If the enclosed portion consists of only a
single segment, both the prefix and the suffix default to the null
string. If the colon modifier is used (that is,
~:<...~:>
), the prefix and suffix default to
"("
and ")"
, respectively, instead of the null
string.
The body segment can be any arbitrary format
control
string. This format
control string is applied to the
elements of the list corresponding to the ~<...~:>
directive as a whole. Elements are extracted from this list using
pprint-pop
, thereby providing automatic support for
malformed lists and the detection of circularity, sharing, and length
abbreviation. Within the body segment, ~^
acts like
pprint-exit-if-list-exhausted
.
~<...~:>
supports a feature not supported by
pprint-logical-block
. If ~:@>
is used to
terminate the directive (that is, ~<...~:@>
), 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.
If the atsign modifier is used with ~<...~:>
, the
entire remaining argument list is passed to the directive as its
argument. All of the remaining arguments are always consumed by
~@<...~:>
, even if they are not all used by the
format
string nested in the directive. Other than the
difference in its argument, ~@<...~:>
is exactly the
same as ~<...~:>
, except that circularity (and
sharing) detection is not applied if the ~@<...~:>
is
at top level in a format
string. This ensures that
circularity detection is applied only to data lists and not to
format
argument lists.
To a considerable extent, the basic form of the directive
~<...~>
is incompatible with the dynamic control of
the arrangement of output by ~W
, ~_
,
~<...~:>
, ~I
, and ~:T
. As a
result, an error is signaled if any of these directives is nested within
~<...~>
. Beyond this, an error is also signaled if
the ~<...~:;...~>
form of ~<...~>
is used in the same format
string with ~W
,
~_
, ~<...~:>
, ~I
, or
~:T
.
~I
Indent. ~
n
I
is
equivalent to
(pprint-indent :block
n
)
.
~:
n
I
is equivalent to
(pprint-indent :current
n
)
.
In both cases, n defaults to zero if it is omitted.
~:T
Tabulate. If the colon modifier is used with the
~T
directive, the tabbing computation is done relative to
the column where the section immediately containing the directive
begins, rather than with respect to column zero.
~
n
,
m
:T
is equivalent to
(pprint-tab :section
n
m
)
.
~
n
,
m
:@T
is equivalent to
(pprint-tab :section-relative
n
m
)
.
The numerical parameters are both interpreted as being in units of ems
and both default to 1.
~/
name
/
Call function. User-defined functions can be called from within
a format
string by using the directive
~/
name
/
. The colon
modifier, the atsign modifier, and arbitrarily many parameters can be
specified with the
~/
name
/
directive. The
name can be any string that does not contain
``/
’‘. All of the characters in name are treated
as if they were upper case. If name contains a
``:
’’ or ``::
’‘, then everything up to but not
including the first ``:
’’ or ``::
’’ is taken
to be a string that names a package. Everything after the first
``:
’’ or ``::
’’ (if any) is taken to be a
string that names a symbol. The function corresponding to a
~/
name
/
directive is
obtained by looking up the symbol that has the indicated name in the
indicated package. If name does not contain a
``:
’’ or ``::
’’, then the whole name string is
looked up in the user
package.
When a ~/
name
/
directive is encountered, the indicated function is called with four or
more arguments. The first four arguments are the output stream, the
format
argument corresponding to the directive, the value
t
if the colon modifier was used (nil
otherwise), and the value t
if the atsign modifier was used
(nil
otherwise). The remaining arguments consist of any
parameters specified with the directive. The function should print the
argument appropriately. Any values returned by the function are
ignored.
The three functions pprint-linear
,
pprint-fill
, and pprint-tabular
are designed
so that they can be called by ~/.../
(that is,
~/pprint-linear/
, ~/pprint-fill/
, and
~/pprint-tabular/
. In particular they take colon and atsign
arguments.
As examples of the convenience of specifying pretty printing with
format
strings, consider the functions
pprint-defun
and pprint-let
used as examples
in the last section. They can be more compactly defined as follows. The
function pprint-vector
cannot be defined using
format
, because the data structure it traverses is not a
list. The function pprint-tabular
is inconvenient to define
using format
, because of the need to pass its
tabsize
argument through to a ~:T
directive
nested within an iteration over a list.
(defun pprint-defun (list)
(format t
"~:<~W ~@_~:I~W ~:_~W~1I ~_~W~:>"
list))
(defun pprint-let (list)
(format t "~:<~W~^ ~:<~@{~:<~@{~W~^ ~_~}~:>~^ ~:_~}~:>~1I~
~@{~^ ~_~W~}~:>"
list))
Next: Compiling Format
Control Up: Pretty
Printing Previous: Dynamic
Control of
AI.Repository@cs.cmu.edu