# String Formatting Standard string formatting functions `format`, `print`, and `println` are based on Common Lisp's `format` function. These functions accept a format string, containing text and formatting directives, and a series of arguments processed according to the format string. The `format` function returns formatted output as a string; `print` writes formatted output to stdout; and `println` writes to stdout, followed by a newline. Formatting string directives may consume an input argument in a variety of ways, including conditional, iteration, and transformation operations. Formatting directives consist of a tilde (`~`), followed by optional flags indicated by the `:` and `@` characters, zero or more optional comma-separated parameters, concluded with a single character. Directive parameters may be literal numbers; character constants, preceded by a `'`; the character `v`, which indicates to consume an input argument for the parameter value; or the character `#`, which indicates to use the number of remaining arguments as the parameter value. ## `a` - Aesthetic Formats a value in a manner similar to the Rust `fmt::Display` trait. Parameters are *min-col*,*col-inc*,*min-pad*,*pad-char*. The string is right-padded (or left-padded if the `@` flag is present) with *min-pad* *pad-char*s. Then, *col-inc* *pad-char*s are inserted until the result is at least *min-col* chars long. *min-col* and *min-pad* default to `0`; *col-inc* defaults to `1`; *pad-char* defaults to space. ```lisp (format "~a" "foo") => "foo" (format "~10a" "foo") => "foo " (format "~10@a" "foo") => " foo" ``` ## `s` - Standard Formats a value in a manner similar to the Rust `fmt::Debug` trait. Parameters are identical to the `a` directive. ```lisp (format "~s" #'a') => "#'a'" ``` ## `c` - Character Outputs the value of a character. ```lisp (format "~c~c~c" #'a' #'b' #'c') => "abc" ``` ## `f` - Float Formats a floating point value in standard notation. Parameters are *width*,*precision*,*pad-char*. *width* and *precision* are passed to the Rust float formatter. *pad-char* is used to pad the result and defaults to space. If the `@` flag is present, the sign of the value is always displayed. ```lisp (format "~5,2f" 3.14159) => " 3.14" ``` ## `e` - Exponent Formats a floating point value in exponent notation. Parameters are identical to `f` directive. ## `d`, `b`, `o`, `x` - Integer The `d`, `b`, `o`, and `x` directives format an integer in decimal, binary, octal, or hexadecimal, respectively. Parameters are *min-col*,*pad-char*,*comma-char*,*comma-interval*. The result is padded with *pad-char* to at least *min-col* characters. *min-col* defaults to `0`; *pad-char* defaults to space. If the `@` flag is present, the sign of the value is always displayed. If the `:` flag is present, *comma-char* will be inserted into the result every *comma-interval* digits, starting from the least significant digit. *comma-char* defaults to `,`; *comma-interval* defaults to `3`. ## `r` - Radix If given at least one parameter, the `r` directive will format an integer in a given base in the range `[2, 36]`. Remaining parameters are handled as for the above integer formatting directives. With no parameters, `~r` will produce the following output: * `~r` will output the cardinal; e.g. `one`, `two`, etc. * `~:r` will output the ordinal; e.g. `first`, `second`, etc. * `~@r` will output Roman numerals; e.g. `4` as `IV`. * `~@:r` will output old Roman numerals; e.g. `4` as `IIII`. ## `p` - Plural Formats a standard English plural or singular suffix based on a numeric value. If the value is `1`, nothing is output; otherwise `s` is output. When the `@` flag is present, `y` is output for a value of `1` and `ies` is output for any other value. When the `:` flag is present, the directive will first back up one argument before consuming an argument. ```lisp (format "~d friend~:p, ~d enem~:@p" 1 2) => "1 friend, 2 enemies" (format "~d friend~:p, ~d enem~:@p" 2 1) => "2 friends, 1 enemy" (format "~d friend~:p, ~d enem~:@p" 3 0) => "3 friends, 0 enemies" ``` ## `t` - Tabulate Spaces over to a given column. Parameters are *col-num*,*col-inc*. The directive will space over to at least *col-num*th column, in *col-inc* increments. If the `@` flag is present, the parameters are *col-rel*,*col-inc*. the directive will output *col-rel* spaces, then output enough spaces to advance to a column that is a multiple of *col-inc*, if necessary. ## `z` - Pretty Print Formats a value in a human-readable fashion, inserting newlines and indentation into nested lists. Accepts a single parameter, *indent*. Values within lists are indented, starting at *indent* characters from the first column. The top level value is not indented. ```lisp (println "~z" '(foo (bar (baz)))) (println " ~2z" '(foo (bar (baz)))) ``` ## `?` - Indirection The directive will consume a string and a list, processing the string as a format string and using the list as arguments. If the `@` flag is present, only a format string argument is consumed and the arguments from the current formatting operation are used. ## `*` - Goto This directive adjusts which input argument will be consumed by the next formatting directive. A single integer parameter, *n*, is accepted. The directive will advance *n* arguments forward. If the `:` flag is present, the directive will instead move backward. If the `@` flag is present, the integer argument is taken as an absolute index pointing to the next argument to be consumed. ## `<` / `>` - Justification Formats contained directives and left-, right-, or center-justifies resulting output. The contents of `~<` and `~>` may be split into segments using `~;`, in which case, spacing is evenly divided between segments. With no flags, the leftmost text is left-justified and the rightmost text is right-justified; if there is only one segment, it is right-justified. If the `:` flag is present, spacing is added before the first segment. If the `@` flag is present, spacing is added after the last segment. Parameters are *min-col*,*col-inc*,*min-pad*,*pad-char*. The text is padded with *min-pad* instances of *pad-char*. Then, *col-inc* padding characters are added until *min-col* is reached. *min-col* and *min-pad* default to `0`; *col-inc* defaults to `1`; *pad-char* defaults to space. ## `(` / `)` - Case conversion Performs case conversion on resulting text. * `~(...~)` transforms all letters to lowercase. * `~@(...~)` capitalizes the first letter. * `~:(...~)` capitalizes the first letter of each word. * `~@:(...~)` transforms all letters to uppercase. ## `[` / `]` - Conditional Given no flags, the directive consumes an integer argument and selects one of the contained branches, separated by `~;`, starting at `0`. If the argument index exceeds the branches contained, no text is output. However, the last branch may be indicated as a default branch by preceding it with `~:;`. If a parameter is given, it is used in place of consuming a value. If the `:` flag is present, a boolean value is consumed. The first branch is output if the value is `false`; otherwise, the second branch is output. If the `@` flag is present, the next argument is tested. If it is `()`, nothing is output and the value is consumed; otherwise, the value is not consumed and the sole contained clause is output. Therefore, the clause should typically consume exactly one argument. ## `{` / `}` - Iteration Consumes a list value and outputs the contained directives until the list is empty. Each iteration may consume as many arguments as it desires. The `~^` directive may be used to terminate iteration if no arguments remain. If the `:` flag is present, the consumed list is instead a list of sublists. The values of each sublist are made available to each iteration. If the `@` flag is present, remaining arguments are used instead of a single list argument. If both `:` and `@` flags are present, the remaining arguments are used, each required to be a list. ## `^` - Terminate Terminates a grouping directive if no arguments remain to be consumed. If `~^` is used within a `~:{...~}` group, only the current iteration is terminated. Use `~:^` instead to terminate the entire iteration. ## `|` - Page Inserts a page feed character (`\x0c`). If a parameter *n* is given, inserts *n* page feed characters. ## `%` - Newline Inserts a newline character (`\n`). If a parameter *n* is given, inserts *n* newline characters. ## `&` - Fresh line If output will be written an empty line, this directive does nothing; otherwise, it outputs a newline (`\n`). If a parameter *n* is given, it will then output *n*-1 newlines. ## `\n` - Newline continuation `~` followed by a newline character (`\n`) will consume the newline and any following non-newline whitespace characters. ## `~` - Tilde Outputs a literal tilde character (`~`). If a parameter *n* is given, outputs *n* tilde characters.