## 4.30 Formatted Write

The current version of SWI-Prolog provides two formatted write predicates. The first is writef/[1,2], which is compatible with Edinburgh C-Prolog. The second is format/[1,2], which is compatible with Quintus Prolog. We hope the Prolog community will once define a standard formatted write predicate. If you want performance use format/[1,2] as this predicate is defined in C. Otherwise compatibility reasons might tell you which predicate to use.

### 4.30.1 Writef

writeln(+Term)
  Equivalent to `write(Term), nl.`
writef(+Atom)
  Equivalent to `writef(Atom, []).`
writef(+Format, +Arguments)
  Formatted write. Format is an atom whose characters will be printed. Format may contain certain special character sequences which specify certain formatting and substitution actions. Arguments then provides all the terms required to be output.

  Escape sequences to generate a single special character:

  `\n` | Output a newline character (see also nl/[0,1])
  `\l` | Output a line separator (same as `\n`)
  `\r` | Output a carriage-return character (ASCII 13)
  `\t` | Output the ASCII character TAB (9)
  `\\` | The character ``\`` is output
  `\%` | The character ``%`` is output
  `\nnn` | where <nnn> is an integer (1-3 digits) the character with character code <nnn> is output (NB : <nnn> is read as decimal)

  Note that `\l`, `\nnn` and `\\` are interpreted differently when character-escapes are in effect. See section 2.15.1.2.

  Escape sequences to include arguments from Arguments. Each time a % escape sequence is found in Format the next argument from Arguments is formatted according to the specification.

  `%t` | print/1 the next item (mnemonic: term)
  `%w` | write/1 the next item
  `%q` | writeq/1 the next item
  `%d` | Write the term, ignoring operators. See also write_term/2. Mnemonic: old Edinburgh display/1.
  `%p` | print/1 the next item (identical to `%t`)
  `%n` | Put the next item as a character (i.e., it is a character code)
  `%r` | Write the next item N times where N is the second item (an integer)
  `%s` | Write the next item as a String (so it must be a list of characters)
  `%f` | Perform a ttyflush/0 (no items used)
  `%Nc` | Write the next item Centered in N columns.
  `%Nl` | Write the next item Left justified in N columns.
  `%Nr` | Write the next item Right justified in N columns. N is a decimal number with at least one digit. The item must be an atom, integer, float or string.

swritef(-String, +Format, +Arguments)
  Equivalent to writef/2, but ``writes'' the result on String instead of the current output stream. Example:

      ?- swritef(S, '%15L%w', ['Hello', 'World']).

      S = "Hello          World"

swritef(-String, +Format)
  Equivalent to `swritef(String, Format, []).`

### 4.30.2 Format

The format-family of predicates is the most versatile and portable66Unfortunately not coverted by any standard. way to produce textual output.

format(+Format)
  Defined as ``format(Format) :- format(Format, []).`'
format(+Format, +Arguments)
  Format is an atom, list of character codes, or a Prolog string. Arguments provides the arguments required by the format specification. If only one argument is required and this single argument is not a list the argument need not be put in a list. Otherwise the arguments are put in a list.

  Special sequences start with the tilde (``~``), followed by an optional numeric argument, followed by a character describing the action to be undertaken. A numeric argument is either a sequence of digits, representing a positive decimal number, a sequence ``<character>`, representing the character code value of the character (only useful for `~t`) or a asterisk (``*``), in which case the numeric argument is taken from the next argument of the argument list, which should be a positive integer. E.g., the following three examples all pass 46 (``.``) to `~t`:

      ?- format('~w ~46t ~w~72|~n', ['Title', 'Page']).
      ?- format('~w ~`.t ~w~72|~n', ['Title', 'Page']).
      ?- format('~w ~*t ~w~72|~n', ['Title', 46, 'Page']).

  Numeric conversion (`d`, `D`, `e`, `E`, `f`, `g` and `G`) accept an arithmetic expression as argument. This is introduced to handle rational numbers transparently (see section 4.25.2.2. The floating point conversions allow for unlimited precision for printing rational numbers in decimal form. E.g., the following will write as many 3-s as you want by changing the `70'.

      ?- format('~70f', [10 rdiv 3]).
      3.3333333333333333333333333333333333333333333333333333333333333333333333

  - ``~``
    Output the tilde itself.

  - `a`
    Output the next argument, which must be an atom. This option is equivalent to w, except for that it requires the argument to be an atom.

  - `c`
    Interpret the next argument as an character code and add it to the output. This argument should be an integer in the range [0, ... , 255] (including 0 and 255).

  - `d`
    Output next argument as a decimal number. It should be an integer. If a numeric argument is specified a dot is inserted argument positions from the right (useful for doing fixed point arithmetic with integers, such as handling amounts of money).

  - `D`
    Same as d, but makes large values easier to read by inserting a comma every three digits left to the dot or right.

  - `e`
    Output next argument as a floating point number in exponential notation. The numeric argument specifies the precision. Default is 6 digits. Exact representation depends on the C library function printf(). This function is invoked with the format `%.<precision>e`.

  - `E`
    Equivalent to e, but outputs a capital E to indicate the exponent.

  - `f`
    Floating point in non-exponential notation. See C library function printf().
  - `g`
    Floating point in e or f notation, whichever is shorter.
  - `G`
    Floating point in E or f notation, whichever is shorter.
  - `i`
    Ignore next argument of the argument list. Produces no output.
  - `k`
    Give the next argument to (write_canonical/1).
  - `n`
    Output a newline character.
  - `N`
    Only output a newline if the last character output on this stream was not a newline. Not properly implemented yet.
  - `p`
    Give the next argument to print/1.
  - `q`
    Give the next argument to writeq/1.
  - `r`
    Print integer in radix the numeric argument notation. Thus `~16r` prints its argument hexadecimal. The argument should be in the range [2, ... , 36]. Lower case letters are used for digits above 9.
  - `R`
    Same as r, but uses upper case letters for digits above 9.

  - `s`
    Output text from a list of character codes or a string (see string/1 and section 4.22) from the next argument.67The s modifier also accept an atom for compatibility. This is deprecated due to the ambiguity of `[]`.

  - `@`
    Interpret the next argument as a goal and execute it. Output written to the `current_output` stream is inserted at this place. Goal is called in the module calling format/3. This option is not present in the original definition by Quintus, but supported by some other Prolog systems.

  - `t`
    All remaining space between 2 tab stops is distributed equally over `~t` statements between the tab stops. This space is padded with spaces by default. If an argument is supplied this is taken to be the character code of the character used for padding. This can be used to do left or right alignment, centering, distributing, etc. See also `~|` and `~+` to set tab stops. A tab stop is assumed at the start of each line.

  - ``|``
    Set a tab stop on the current position. If an argument is supplied set a tab stop on the position of that argument. This will cause all `~t`'s to be distributed between the previous and this tab stop.
  - ``+``
    Set a tab stop relative to the current position. Further the same as `~|`.
  - `w`
    Give the next argument to write/1.

  - `W`
    Give the next two argument to write_term/2. E.g. `format(' W', [Term, [numbervars(true)]])`. This option is SWI-Prolog specific.

  Example:

      simple_statistics :-
          <obtain statistics>         % left to the user
          format('~tStatistics~t~72|~n~n'),
          format('Runtime: ~`.t ~2f~34|  Inferences: ~`.t ~D~72|~n',
                                                  [RunT, Inf]),
          ....

  Will output

                                   Statistics

      Runtime: .................. 3.45  Inferences: .......... 60,345

format(+Output, +Format, +Arguments)
  As format/2, but write the output on the given Output. The de-facto standard only allows Output to be a stream. The SWI-Prolog implementation allows all valid arguments for with_output_to/2.68Earlier versions defined sformat/3 . These predicates have been moved to the library `library(backcomp)`. For example:

      ?- format(atom(A), '~D', [1000000]).
      A = '1,000,000'

### 4.30.3 Programming Format

format_predicate(+Char, +Head)
  If a sequence `~c` (tilde, followed by some character) is found, the format derivatives will first check whether the user has defined a predicate to handle the format. If not, the built in formatting rules described above are used. Char is either an ASCII value, or a one character atom, specifying the letter to be (re)defined. Head is a term, whose name and arity are used to determine the predicate to call for the redefined formatting character. The first argument to the predicate is the numeric argument of the format command, or the atom `default` if no argument is specified. The remaining arguments are filled from the argument list. The example below redefines `~n` to produce Arg times return followed by linefeed (so a (Grr.) DOS machine is happy with the output).

      :- format_predicate(n, dos_newline(_Arg)).

      dos_newline(default) :- !,
              dos_newline(1).
      dos_newline(N) :-
              (   N > 0
              ->  write('\r\n'),
                  N2 is N - 1,
                  dos_newline(N2)
              ;   true
              ).

current_format_predicate(?Code, ?:Head)
  Enumerates all user-defined format predicates. Code is the character code of the format character. Head is unified with a term with the same name and arity as the predicate. If the predicate does not reside in module `user`, Head is qualified with the definition module of the predicate.