ketos 0.12.0

Lisp dialect scripting and extension language
Documentation
# 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.