11. Strings

Strings are a type of array which are constants (they self-evaluate) and have as their printed representation a sequence of characters enclosed in quote marks, for example "foo bar" . Strings are the right data type to use for text-processing. The functions described in this section provide a variety of useful operations on strings. Several of the functions actually work on any type of 1-dimensional array and may be useful for other than string processing. art-16b arrays (arrays of 16-bit positive numbers) are often used as strings; the extra bits allow for an expanded character set. In place of a string, most of these functions will accept a symbol or a fixnum as an argument, and will coerce it into a string. Given a symbol, its print name, which is a string, will be used. Given a fixnum, a 1 character long string containing the character designated by that fixnum will be used. Note that the length of a string is computed using array-active-length , so that if a string has an array-leader, element 0 of the leader (called the fill pointer ) will be taken as the length. Since strings are arrays, the usual array-referencing function aref is used to extract the characters of the string as fixnums. For example,

(aref "frob" 1) => 162  ;lower-case r 
It is also legal to store into strings (using aset ). As with rplaca on lists, this changes the actual object; one must be careful to understand where side-effects will propagate to.
11.1 String Manipulation
character x
character coerces x to a single character, represented as a fixnum. If x is a number, it is returned. If x is a string or an array, its first element is returned. If x is a symbol, the first character of its pname is returned. Otherwise, an error occurs.
char-equal ch1 ch2
This is the primitive for comparing characters for equality; many of the string functions call it. ch1 and ch2 must be fixnums. The result is t if the characters are equal ignoring case and font, otherwise nil . %%ch-char is the byte-specifier for the portion of a character which excludes the font information.
char-lessp ch1 ch2
This is the primitive for comparing characters for order; many of the string functions call it. ch1 and ch2 must be fixnums. The result is t if ch1 comes before ch2 ignoring case and font, otherwise nil .
alphabetic-case-affects-string-comparison Variable
This variable is normally nil . If it is t , char-equal , char-lessp , and the string searching and comparison functions will distinguish between upper-case and lower-case letters. It is alright to bind this to t , but changing its global value to t will break many system functions and user interfaces and so is not recommended.
string x
string coerces x into a string. Most of the string functions apply this to their string arguments. If x is a string or an array, it is returned. If x is a symbol, its pname is returned. If x is a number, a 1-character long string containing it is returned. Otherwise, an error occurs.
string-length string
string-length returns the number of characters in string . This is 1 if string is a number, the array-active-length (see LINK:(array-active-length-fun)) if string is an array, or the array-active-length of the pname if string is a symbol.
string-equal string1 string2 &optional (idx1 0) (idx2 0) lim1 lim2
string-equal compares two strings, returning t if they are equal and nil if they are not. The comparison ignores the extra "font" bits in 16-bit strings and ignores alphabetic case. equal calls string-equal if applied to two strings. The optional arguments idx1 and idx2 are the starting indices into the strings. The optional arguments lim1 and lim2 are the final indices; the comparison stops just before the final index. lim1 and lim2 default to the lengths of the strings. These arguments are provided so that you can efficiently compare substrings.
Examples:
(string-equal "Foo" "foo") => t
(string-equal "foo" "bar") => nil
(string-equal "element" "select" 0 1 3 4) => t
%string-equal string1 idx1 string2 idx2 count
%string-equal is the microcode primitive which string-equal calls. It returns t if the count characters of string1 starting at idx1 are char-equal to the count characters of string2 starting at idx2 , or nil if the characters are not equal or if count runs off the length of either array. Instead of a fixnum, count may also be nil . In this case, %string-equal compares the substring from idx1 to (string-length string1) against the substring from idx2 to (string-length string2) . If the lengths of these substrings differ, then they are not equal and nil is returned.
Examples:
To compare the two strings foo and bar: 
(%string-equal foo  0 bar  nil)
To see if the string foo starts with the characters "bar": 
(%string-equal foo  0 "bar" 0 3)
string-lessp string1 string2
string-lessp compares two strings using dictionary order. The result is t if string1 is the lesser, and nil if they are equal or string2 is the lesser.
substring string start &optional end area
This extracts a substring of string , starting at the character specified by start and going up to but not including the character specified by end . start and end are 0-origin indices. The length of the returned string is end minus start . If end is not specified it defaults to the length of string . The area in which the result is to be consed may be optionally specified.
Example:
(substring "Nebuchadnezzar" 4 8) => "chad"
nsubstring string start &optional end area
nsubstring is the same as substring except that the substring is not copied; instead an indirect array (see this link) is created which shares part of the argument string . Modifying one string will modify the other. Note that nsubstring does not necessarily use less storage than substring ; an nsubstring of any length uses the same amount of storage as a substring 12 characters long.
string-append &rest strings
Any number of strings are copied and concatenated into a single string. With a single argument, string-append simply copies it. If the first argument is an array, the result will be an array of the same type. Thus string-append can be used to copy and concatenate any type of 1-dimensional array.
Example:
(string-append 41 "foo" 41) => "!foo!"
string-trim char-list string
This returns a substring of string , with all characters in char-list stripped off of the beginning and end.
Example:
(string-trim '(40) "  Dr. No  ") => "Dr. No"
string-left-trim char-list string
This returns a substring of string , with all characters in char-list stripped off of the beginning.
string-right-trim char-list string
This returns a substring of string , with all characters in char-list stripped off of the end.
char-upcase ch
If ch , which must be a fixnum, is a lower-case alphabetic character its upper-case form is returned; otherwise, ch itself is returned. If font information is present it is preserved.
char-downcase ch
If ch , which must be a fixnum, is a upper-case alphabetic character its lower-case form is returned; otherwise, ch itself is returned. If font information is present it is preserved.
string-upcase string
Returns a copy of string , with all lower case alphabetic characters replaced by the corresponding upper case characters.
string-downcase string
Returns a copy of string , with all upper case alphabetic characters replaced by the corresponding lower case characters.
string-reverse string
Returns a copy of string with the order of characters reversed. This will reverse a 1-dimensional array of any type.
string-nreverse string
Returns string with the order of characters reversed, smashing the original string, rather than creating a new one. If string is a number, it is simply returned without consing up a string. This will reverse a 1-dimensional array of any type.
string-search-char char string &optional (from 0) to
string-search-char searches through string starting at the index from , which defaults to the beginning, and returns the index of the first character which is char-equal to char , or nil if none is found. If the to argument is supplied, it is used in place of (string-length string) to limit the extent of the search.
Example:
(string-search-char 101 "banana") => 1
%string-search-char char string from to
%string-search-char is the microcode primitive which string-search-char and other functions call. string must be an array and char , from , and to must be fixnums. Except for this lack of type-coercion, and the fact that none of the arguments is optional, %string-search-char is the same as string-search-char .
string-search-not-char char string &optional (from 0) to
string-search-not-char searches through string starting at the index from , which defaults to the beginning, and returns the index of the first character which is not char-equal to char , or nil if none is found. If the to argument is supplied, it is used in place of (string-length string) to limit the extent of the search.
Example:
(string-search-char 102 "banana") => 1
string-search-set char-list string &optional (from 0) to
string-search-set searches through string looking for a character which is in char-list . The search begins at the index from , which defaults to the beginning. It returns the index of the first character which is char-equal to some element of char-list , or nil if none is found. If the to argument is supplied, it is used in place of (string-length string) to limit the extent of the search.
Example:
(string-search-set '(116 117) "banana") => 2
string-search-not-set char-list string &optional (from 0) to
string-search-not-set searches through string looking for a character which is not in char-list . The search begins at the index from , which defaults to the beginning. It returns the index of the first character which is not char-equal to any element of char-list , or nil if none is found. If the to argument is supplied, it is used in place of (string-length string) to limit the extent of the search.
Example:
(string-search-not-set '(141 142) "banana") => 2
string-reverse-search-char char string &optional from (to 0)
string-reverse-search-char searches through string in reverse order, starting from the index one less than from , which defaults to the length of string , and returns the index of the first character which is char-equal to char , or nil if none is found. Note that the index returned is from the beginning of the string, although the search starts from the end. If the to argument is supplied, it limits the extent of the search.
Example:
(string-reverse-search-char 156 "banana") => 4
string-reverse-search-not-char char string &optional from (to 0)
string-reverse-search-not-char searches through string in reverse order, starting from the index one less than from , which defaults to the length of string , and returns the index of the first character which is not char-equal to char , or nil if none is found. Note that the index returned is from the beginning of the string, although the search starts from the end. If the to argument is supplied, it limits the extent of the search.
Example:
(string-reverse-search-not-char 101 "banana") => 4
string-reverse-search-set char-list string &optional from (to 0)
string-reverse-search-set searches through string in reverse order, starting from the index one less than from , which defaults to the length of string , and returns the index of the first character which is char-equal to some element of char-list , or nil if none is found. Note that the index returned is from the beginning of the string, although the search starts from the end. If the to argument is supplied, it limits the extent of the search.
(string-reverse-search-set '(141 142) "banana") => 5
string-reverse-search-not-set char-list string &optional from (to 0)
string-reverse-search-not-set searches through string in reverse order, starting from the index one less than from , which defaults to the length of string , and returns the index of the first character which is not char-equal to any element of char-list , or nil if none is found. Note that the index returned is from the beginning of the string, although the search starts from the end. If the to argument is supplied, it limits the extent of the search.
(string-reverse-search-not-set '(141 156) "banana") => 0
See also intern (LINK:(intern-fun)), which given a string will return "the" symbol with that print name.
11.2 String Manipulation
The special forms in this section allow you to create I/O streams which input from or output to a string rather than a real I/O device. See LINK:(streams) for documentation of I/O streams.
with-input-from-string Special Form
The form
(with-input-from-string (var string )
    body )
evaluates the forms in body with the variable var bound to a stream which reads characters from the string which is the value of the form string . The value of the special form is the value of the last form in its body. The stream is a "downward closure", so be careful what you do with it. You cannot use it after control leaves the body, and you cannot nest two with-input-from-string special forms and use both streams since the special-variable bindings associated with the stream will conflict. It is done this way to avoid any consing. After string you may optionally specify two additional "arguments".
(with-input-from-string (var string index )
    body )
uses index as the starting index into the string, and updates it when it is done to the index of the first character not read (the length of the string if all of it was read.) Since index is updated it may not be a general expression; it must be a variable or a setf -able reference. The index is not updated in the event of an abnormal exit from the body, such as a *throw . Use of the index feature prevents multiple values from being returned out of the body, currently.
(with-input-from-string (var string index limit )
    body )
uses the value of the form limit in place of the length of the string if it is not nil . If you want to specify a limit but not an index , put nil for index .
with-output-to-string Special Form
This special form provides a variety of ways to send output to a string through an i/o stream.
(with-output-to-string (var )
  body )
evaluates the forms in body with var bound to a stream which saves the characters output to it in a string. The value of the special form is the string.
(with-output-to-string (var string )
  body )
will append its output to the string which is the value of the form string . (This is like the string-nconc function.) The value returned is the value of the last form in the body, rather than the string. Multiple values are not returned. If string has an array-leader, element 0 of the array-leader will be used as the fill-pointer. If string is too small to contain all the output, adjust-array-size will be used to make it bigger.
(with-output-to-string (var string index )
  body )
is similar to the above except that index is a variable or setf -able reference which contains the index of the next character to be stored into. It must be initialized outside the with-output-to-string and will be updated upon normal exit. The stream is a "downward closure", so be careful what you do with it. You cannot use it after control leaves the body, and you cannot nest two with-input-from-string special forms and use both streams since the special-variable bindings associated with the stream will conflict. It is done this way to avoid any consing.
11.3 Maclisp-compatible Functions
alphalessp string1 string2
(alphalessp string1 string2) is equivalent to (string-lessp string1 string2) .
getchar string index
Returns the index 'th character of string as a symbol. Note that 1-origin indexing is used. This function is mainly for Maclisp compatibility; aref should be used to index into strings (however aref will not coerce symbols or numbers into strings).
getcharn string index
Returns the index 'th character of string as a fixnum. Note that 1-origin indexing is used. This function is mainly for Maclisp compatibility; aref should be used to index into strings (however aref will not coerce symbols or numbers into strings).
ascii x
ascii is like character , but returns a symbol whose printname is the character instead of returning a fixnum.
Examples:
(ascii 101) => A
(ascii 56) => /.
The symbol returned is interned in the user package.
maknam char-list
maknam returns an uninterned symbol whose print-name is a string made up of the characters in char-list .
Example:
(maknam '(a b 60 d)) => ab0d
implode char-list
implode is like maknam except that the returned symbol is interned in the current package.
The samepnamep function is also provided; see LINK:(samepnamep-fun).
11.4 Formatted Output

format destination control-string &rest args
format is used to produce formatted output. format outputs the characters of control-string , except that a tilde ("SAIL~") introduces a directive. The character after the tilde, possibly preceded by arguments and modifiers, specifies what kind of formatting is desired. Some directives use one or more elements of args to create their output. The output is sent to destination . If destination is nil , a string is created which contains the output; this string is returned as the value of the call to format . If destination is a stream, the output is sent to it. If destination is t , the output is sent to standard-output . If destination is a string with an array-leader, such as would be acceptable to string-nconc , the output is added to the end of that string. A directive consists of a tilde, optional decimal numeric parameters separated by commas, optional colon (": ") and atsign ("@ ") modifiers, and a single character indicating what kind of directive this is. The alphabetic case of the character is ignored. Examples of control strings:
"~S"        ; This is an S directive with no parameters. 
"~3,4:@s"   ; This is an S directive with two parameters, 3 and 4, 
            ;    and both the colon and atsign flags. 
Sometimes a numeric parameter is used to specify a character, for instance the padding character in a right- or left-justifying operation. In this case a single quote ("' ") followed by the desired character may be used as a numeric argument. For example, you can use
"~5,'0d"
to print a decimal number in five columns with leading zeros. The kinds of directives will now be described. arg will be used to refer to the next argument from args .
~Darg , a number, is printed as a decimal integer. ~nD uses a column width of n ; spaces are inserted on the left if the number requires less than n columns for its digits and sign. If the number doesn't fit in n columns, additional columns are used as needed. ~n,mD uses m as the pad character instead of 40 (space). If arg is not a number, it is printed in ~A format. The @ modifier causes the number's sign to be printed always; the default is only to print it if the number is negative. The : modifier causes commas to be printed betweens of three digits; the third numeric parameter may be used to change the character used as the comma. Thus the most general form of ~D is ~mincol,padchar,commacharD .
~OThis is just like ~D but prints in octal instead of decimal.
~Farg is printed in floating point. ~nF rounds arg to a precision of n digits. The minimum value of n is 2, since a decimal point is always printed. If the magnitude of arg is too large or too small, it is printed in exponential notation. If arg is not a number, it is printed in ~A format.
~Earg is printed in exponential notation. This is identical to ~F , including the use of a numeric parameter to specify the number of digits, except that the number is always printed with a trailing exponent, even if it is within a reasonable range.
~Aarg , any Lisp object, is printed without slashification (like princ ). ~:A prints () if arg is nil ; this is useful when printing something that is always supposed to be a list. ~nA inserts spaces on the right, if necessary, to make the column width at least n . The @ modifier causes the spaces to be inserted on the left rather than the right. ~mincol,colinc,minpad,padcharA is the full form of ~A , which allows elaborate control of the padding. The string is padded on the right with at least minpad copies of padchar ; padding characters are then inserted colinc characters at a time until the total width is at least mincol . The defaults are 0 for mincol and minpad , 1 for colinc , and space for padchar .
~SThis is just like ~A , but arg is printed with slashification (like prin1 rather than princ ).
~C(character arg) is printed as a keyboard character (see LINK:(%%kbd)). Any control bits are printed first by representing them with Greek letters: alpha (Control), beta (Meta), epsilon (Control and Meta), lambda (Hyper), pi (Super). If the character itself is alpha, beta, epsilon, lambda, pi, or equivalence-sign, then it is preceded by an equivalence-sign to quote it. With the colon flag (~:C ), the name of the control bits are spelled out (e.g. "Control-Meta-F "), and also non-printing characters (those in the 200 to 377 range) are represented by their names (e.g. "Return "). With both colon and atsign (~:@C ), the colon-only format is printed, and then if the character requires the Top, Front, or Greek key(s) to type it, this fact is mentioned (e.g. "≥ (Top-L) "). For all three of these formats, if the character is not a keyboard character but a mouse "character", it is printed as "Mouse-", the name of the button, "-", and the number of clicks. With just an atsign (~@C ), the character is printed in such a way that the READ function can understand it, using "#/ " or "#\ ". Examples:
(setq a `(44 1440 403 215 611 ,(dpb 1 %%kbd-mouse 11)))
(format nil "~{<~C>~}" a)  =>
  "<$>< ><><
><	><Mouse-Middle-Twice>"
(format nil "~{<~:C>~}" a)  =>
  "<$><Control-Meta-Space><Control-><Return><Control-Tab><Mouse-Middle-Twice>"
(format nil "~{<~:@C>~}" a)  =>
  "<$><Control-Meta-Space><Control- (Top-X)><Return><Control-Tab><Mouse-Middle-Twice>"
(format nil "~{<~@C>~}" a)  =>
  "<#//$><#\SPACE><#//><#\RETURN><#\TAB><#\MOUSE-M-2>"
~%Outputs a newline. ~n% outputs n newlines. No argument is used.
~&The :fresh-line operation is performed on the output stream. Unless the stream knows that it is already at the front of a line, this outputs a newline. ~n& does a :fresh-line operation and then outputs n-1 newlines.
~|Outputs a formfeed. ~n| outputs n formfeeds. With a : , performs a :clear-screen operation on the output stream if the stream supports that operation; otherwise it behaves as if no : were present (outputs formfeed(s)).
~XOutputs a space. ~nX outputs n spaces.
~~Outputs a tilde. ~n~ outputs n tildes.
~ <CR>Tilde immediately followed by a carriage return ignores the carriage return and any whitespace at the beginning of the next line. With a : , the whitespace is left in place. With an @ , the carriage return is left in place.
~*arg is ignored. ~n* ignores the next n arguments. ~:* "ignores backwards"; that is, it backs up in the list of arguments so that the argument last processed will be processed again. ~:n* backs up n arguments. When within a ~{ construct, the ignoring (in either direction) is relative to the list of arguments being processed by the iteration.
~PIf arg is not 1 , a lower-case s is printed. ("P" for "plural".) ~:P does the same thing, after doing a ~:* ; that is, it prints a lower-case s if the last argument was not 1. ~@P prints "y" if the argument is 1, or "ies" if it is not. ~:@P does the same thing, but backs up first.
~TSpaces over to a given column. ~n,mT will output sufficient spaces to move the cursor to column n . If the cursor is already past column n , it will output spaces to move it to column n +mk , for the smallest integer value k possible. n and m default to 1 . Without the colon flag, n and m are in units of characters; with it, they are in units of pixels. Note : this operation only works properly on streams that support the :read-cursorpos and :set-cursorpos stream operations (see LINK:(read-cursorpos)). On other streams (and when format is creating a string), any ~T operation will simply output two spaces.
~RIf there is no parameter, then arg is printed as a cardinal English number, e.g. four. With the colon modifier, arg is printed as an ordinal number, e.g. fourth. With the atsign modifier, arg is printed as a Roman numeral, e.g. IV. With both atsign and colon, arg is printed as an old Roman numeral, e.g. IIII. If there is a parameter, then it is the radix in which to print the number. The flags and any remaining parameters are used as for the ~D directive. Indeed, ~D is the same as ~10R . The full form here is therefore ~radix,mincol,padchar,commacharR .
~n  G"Goes to" the n th argument. ~0G goes back to the first argument in args . Directives after a ~nG will take sequential arguments after the one gone to. When within a ~{ construct, the "goto" is relative to the list of arguments being processed by the iteration. This is an "absolute goto"; for a "relative goto", see ~* .
~[str0 ~;str1 ~;... ~;strn ~]
This is a set of alternative control strings. The alternatives (called clauses ) are separated by ~; and the construct is terminated by ~] . For example, "~[Siamese ~;Manx ~;Persian ~;Tortoise-Shell ~;Tiger ~;Yu-Hsiang ~]kitty ". The arg th alternative is selected; 0 selects the first. If a numeric parameter is given (i.e. ~n[ ), then the parameter is used instead of an argument (this is useful only if the parameter is "# "). If arg is out of range no alternative is selected. After the selected alternative has been processed, the control string continues after the ~] . ~[str0 ~;str1 ~;... ~;strn ~:;default ~] has a default case. If the last ~; used to separate clauses is instead ~:; , then the last clause is an "else" clause, which is performed if no other clause is selected. For example, "~[Siamese ~;Manx ~;Persian ~;Tortoise-Shell ~;Tiger ~;Yu-Hsiang ~:;Unknown ~] kitty ". ~[~tag00 ,tag01 ,... ;str0 ~tag10 ,... ;str1... ~] allows the clauses to have explicit tags. The parameters to each ~; are numeric tags for the clause which follows it. That clause is processed which has a tag matching the argument. If ~:a1,a2,b1,b2,...; is used, then the following clause is tagged not by single values but by ranges of values a1 through a2 (inclusive), b1 through b2 , etc. ~:; with no parameters may be used at the end to denote a default clause. For example, "~[~'+,'-,'*,'//;operator ~'A,'Z,'a,'z;letter ~'0,'9;digit ~:;other ~] ". ~:[false~;true~] selects the false control string if arg is nil , and selects the true control string otherwise. ~@[true~] tests the argument. If it is not nil , then the argument is not used up, but is the next one to be processed, and the one clause is processed. If it is nil , then the argument is used up, and the clause is not processed.
(setq prinlevel nil prinlength 5)
(format nil "~@[ PRINLEVEL=~D~]~@[ PRINLENGTH=~D]" prinlevel prinlength)
   =>  " PRINLENGTH=5"
~;Separates clauses in ~[ and ~< constructions. It is undefined elsewhere.
~]Terminates a ~[ . It is undefined elsewhere.
~{str ~}This is an iteration construct. The argument should be a list, which is used as a set of arguments as if for a recursive call to format . The string str is used repeatedly as the control string. Each iteration can absorb as many elements of the list as it likes. If before any iteration step the list is empty, then the iteration is terminated. Also, if a numeric parameter n is given, then there will be at most n repetitions of processing of str . ~:{str~} is similar, but the argument should be a list of sublists. At each repetition step one sublist is used as the set of arguments for processing str ; on the next repetition a new sublist is used, whether or not all of the last sublist had been processed. ~@{str~} is similar to ~{str~} , but instead of using one argument which is a list, all the remaining arguments are used as the list of arguments for the iteration. ~:@{str~} combines the features of ~:{str~} and ~@{str~} . All the remaining arguments are used, and each one must be a list. On each iteration one argument is used as a list of arguments. Terminating the repetition construct with ~:} instead of ~} forces str to be processed at least once even if the initial list of arguments is null (however, it will not override an explicit numeric parameter of zero). If str is null, then an argument is used as str . It must be a string, and precedes any arguments processed by the iteration. As an example, the following are equivalent:
(apply (function format) (list* stream string args))
(format stream "~1{~:}" string args)
This will use string as a formatting string. The ~1{ says it will be processed at most once, and the ~:} says it will be processed at least once. Therefore it is processed exactly once, using args as the arguments. As another example, the format function itself uses format-error (a routine internal to the format package) to signal error messages, which in turn uses ferror , which uses format recursively. Now format-error takes a string and arguments, just like format , but also prints some addtitional information: if the control string in ctl-string actually is a string (it might be a list -- see below), then it prints the string and a little arrow showing where in the processing of the control string the error occurred. The variable ctl-index points one character after the place of the error.
(DEFUN FORMAT-ERROR (STRING &REST ARGS)
       (COND ((STRINGP CTL-STRING)
	      (FERROR NIL "~1{~:}~%~VTSAIL~%~3X/"~A/"~%"
		      STRING ARGS (+ CTL-INDEX 3) CTL-STRING))
	     (T (FERROR NIL "~1{~:}" STRING ARGS))))
This first processes the given string and arguments using ~1{~:} , then tabs a variable amount for printing the down-arrow, then prints the control string between double-quotes. The effect is something like this:
(format t "The item is a ~[Foo~;Bar~;Loser~]." 'quux)
>>ERROR: The argument to the FORMAT "~[" command must be a number
                   SAIL
   "The item is a ~[Foo~;Bar~;Loser~]."
SAIL...
~}Terminates a ~{ . It is undefined elsewhere. ~^This is an escape construct. If there are no more arguments remaining to be processed, then the immediately enclosing ~{ or ~< construct is terminated. (In the latter case, the ~< formatting is performed, but no more clauses are processed before doing the justification. The ~^ should appear only at the beginning of a ~< clause, because it aborts the entire clause. It may appear anywhere in a ~{ construct.) If there is no such enclosing construct, then the entire formatting operation is terminated. If a numeric parameter is given, then termination occurs if the parameter is zero. (Hence ~^ is the same as ~#^.) If two parameters are given, termination occurs if they are equal. If three are given, termination occurs if the second is between the other two in ascending order. If ~^ is used within a ~:{ construct, then it merely terminates the current iteration step (because in the standard case it tests for remaining arguments of the current step only); the next iteration step commences immediately. To terminate the entire iteration process, use ~:^. ~<~mincol,colinc,minpad,padchar<text~> justifies text within a field mincol wide. Text may be divided up into clauses with ~SAIL;--the spacing is evenly divided between the text segments. With no modifiers, the leftmost text segment is left justified in the field, and the rightmost text segment right justified; if there is only one, as a special case, it is right justified. The colon modifier causes spacing to be introduced before the first text segment; the atsign modifier causes spacing to be added after the last. Minpad, default 0, is the minimum number of padchar (default space) padding characters to be output between each segment. If the total width needed to satisfy these constraints is greater than mincol, then mincol is adjusted upwards in colinc increments. Colinc defaults to 1.
(format nil "~10<foo~;bar~>")    =>  "foo    bar"
(format nil "~10:<foo~;bar~>")   =>  "  foo  bar"
(format nil "~10:@<foo~;bar~>")  =>  "  foo bar "
(format nil "~10<foobar~>")      =>  "    foobar"
(format nil "$~10,,'*<~3f~>" 2.59023)  =>  "$******2.59"
If ~^ is used within a ~< construct, then only the clauses which were completely processed are used. For example:
(format nil "~15<~S~;~^~S~;~^~S~>" 'foo)            =>  "            FOO"
(format nil "~15<~S~;~^~S~;~^~S~>" 'foo 'bar)       =>  "BAR         FOO"
(format nil "~15<~S~;~^~S~;~^~S~>" 'foo 'bar 'baz)  =>  "FOO   BAR   BAZ"
If the first clause of a ~< is terminated with ~:; instead of ~;, then it is used in a special way. All of the clauses are processed (subject to ~^, of course), but the first one is omitted in performing the spacing and padding. When the padded result has been determined, then if it will fit on the current line of output, it is output, and the text for the first clause is discarded. If, however, the padded text will not fit on the current line, then a newline is output, then the text for the first clause, then the padded text. The first clause is always processed, and so any arguments it refers to will be used; the decision is whether to use the resulting piece of text, not whether to process the first clause. If the ~:; has a numeric parameter n, then the padded text must fit on the current line with n character positions to spare to avoid outputting the newline. For example, the control string "~%;; ~{~<;; ~:1; ~S~>~^,~}.~%" can be used to print a list of items separated by commas, without breaking items over line boundaries, and beginning each line with ";; ". The argument 1 in ~:1; accounts for the width of the comma which will follow the justified item if it is not the last element in the list. If ~:; has a second numeric parameter m, then m is used as the width of the line, thus overriding the natural line width of the output stream. To make the preceding example use a line width of 50, one would write "~%;; ~{~<;; ~:1,30; ~S~>~^,~}.~%". ~>Terminates a ~<. It is undefined elsewhere. In place of a numeric parameter to a directive, you can put the letter V, which takes an argument from args as a parameter to the directive. Normally this should be a number but it doesn't really have to be. This feature allows variable column-widths and the like. Also, you can use the character # in place of a parameter; it represents the number of arguments remaining to be processed. This is useful, for example, for dealing with English conventions for printing lists:
(setq foo "Items:~#[ none~; ~S~; ~S and ~S~:;~@{~#[~1; and~] ~S~^,~}~].")
(format nil foo)  =>  "Items: none."
(format nil foo 'foo)  =>  "Items: FOO."
(format nil foo 'foo 'bar)  =>  "Items: FOO and BAR."
(format nil foo 'foo 'bar 'baz)  =>  "Items: FOO, BAR, and BAZ."
(format nil foo 'foo 'bar 'baz 'quux)  =>  "Items: FOO, BAR, BAZ, and QUUX."
The user can define his own directives. How to do this is not documented here; read the code. Names of user-defined directives longer than one character may be used if they are enclosed in backslashes (e.g. ~4,3\GRAPH\).
Examples:
(format nil "foo") => "foo"
(setq x 5)
(format nil "The answer is ~D." x) => "The answer is 5."
(format nil "The answer is ~3D." x) => "The answer is   5."
(setq y "elephant")
(format nil "Look at the ~A!" y) => "Look at the elephant!"
(format nil "The character ~:@C is strange." 1003)
      => "The character Meta-SAIL (Top-X) is strange."
(setq n 3)
(format nil "~D item~P found." n n) => "3 items found."
(format nil "~R dog~:[s are~; is~] here." n (= n 1))
      => "three dogs are here."
(format nil "~R dog~[~1; is~:;s are~] here." n)
      => "three dogs are here."
(format nil "Here ~[~1;is~:;are~] ~:*~R pupp~:P." n)
      => "Here are three puppies."
format also allows control-string to be a list of strings and lists, which is processed from left to right. Strings are interpreted as in the simple case. Lists are taken as extended directives; the first element is the directive letter, and the remaining elements are the numeric parameters to the directive. If the car of a list is not a recognized directive, the list is simply evaluated as a form; anything it writes to the standard-output stream will appear in the result of format.
format:print-list destination element-format list &optional separator start-line options
This function provides a simpler interface for the specific purpose of printing comma-separated lists with no list element split across two lines. destination tells where to send the output; it can be t, nil, or a stream, as with format. element-format is a format-control-string which tells how to print each element of list; it is used as the body of a "~{...~}" construct. separator, which defaults to ",SAIL " (comma, space) is a string which goes after each element except the last. Format-control commands are not recommended in separator. start-line, which defaults to three spaces, is a format-control-string which is used as a prefix at the beginning of each line of output, except the first. Format-control commands are allowed in separator, but they should not swallow arguments from list. options is a string inserted before the opening "{"; it defaults to the null string, but allows you to insert colon and/or atsign.
For formatting Lisp code (as opposed to text and tables), there is the Grind package. See LINK:(grind).