format (macro)
Package: CURL.LANGUAGE.COMPILER

Format data to a TextOutputStream or a String under the control of a format string.

Signature

{define-proc public {format out:#TextOutputStream = null, locale:#Locale = null, fmt:String, ...:any }:String }
out: The TextOutputStream to which the data should be formatted. If this parameter is not supplied (or is specified as null), the data will be formatted to a String and returned.
locale: The Locale to be used when formatting the rest arguments. If not supplied, {get-syntax-locale} will be used.
fmt: The format string under whose control the formatting should be performed.
...: The data to be formatted.

Returns

If out is specified, the empty String; otherwise, a String containing the formatted data.

Description

If out is specified, then this macro formats the rest arguments (...) to the TextOutputStream out, and returns the empty String.

Otherwise, this macro formats the rest arguments (...) into a new String, and returns that String.

In either case, the format string fmt controls the formatting. It contains normal characters, which should be formatted as themselves, and special format specifiers, each starting with a leading percent sign (%), which will cause one (or more) of the rest arguments (...) to be formatted based on the particular format specifier and the actual rest arguments themselves.

For example:

"The number Pi can be approximated to %f"

In this example, %f is the format specifier for the number that you want to format. The format specifier tells Curl how you want to format the item. The item itself is supplied as a rest argument.

For example:

{format "The number Pi can be approximated to %f", 3.141592653589793238463}

{format "The absolute value of %d is %d", -3, {abs -3}}

Since a percent sign is used to introduce a format specifier, if you want to include a literal percent sign in fmt, you must prefix the percent sign with another percent sign.

For example:

{format "%s got 54%% of the vote", "Bill Clinton"}

The format specifiers that you can specify are similar to the ones used by printf in the C programming language.

The syntax of the normal format specifiers is as follows:

%[modifiers][width][.precision]key

Where:

modifiers alter the default operation of format:



You can specify more than one modifier in a single format specifier, and they can appear in any order.

width is optional. It indicates the minimum number of characters in the formatted output. If the width is not specified, there is no minimum number of characters. If you are formatting a value with more characters than width, the characters are not truncated. If you are formatting a string that has fewer characters than width, it is padded. It is possible to use a variable width, where one of the rest arguments determines the width. To use a variable width, specify an asterisk character (*) for width. Then place an int that specifies the width in the rest arguments before the item being formatted.

precision indicates the precision with which to format an item. precision is only valid for the following format keys, for which it has the given meaning:



If you include the period that precedes the precision, but do not specify the precision, it takes the value zero. It is possible to use a variable precision, where one of the rest arguments determines the width. To use a variable precision, specify an asterisk character (*) for precision. Then place an int that specifies the precision in the rest arguments before the item being formatted. If you use both variable width and precision, specify the width before the precision in the rest arguments.

key indicates information about the item that you want to format. Specify any of the following for key:



By default, the format specifiers and rest arguments are processed in order from left-to-right. However, you can specify a rest argument index for each format specifier. To specify a rest argument index for a format specifier, enclose the format specifier (except for the percent sign (%)) in exclamation marks (!) and place the rest argument index just after the percent sign.

For example, if you have the following format specifier:

%02d

And you want to apply it to the rest argument in position 3, change the format specifier to read:

%3!02d!

Mixing numbered and unnumbered specifiers in the same format string is allowed. In mixed format strings, the unnumbered specifiers refer to each rest argument in order, regardless of what numbered specifiers appear before it. For example:

{format "%2!s! %s %s %1!s!", 1, 2} == "2 1 2 1"

However, mixing specifier styles in this fashion is not recommended because it is confusing.

Example

This example shows some of the formatting operations that you can perform on integers.


Example: Formatting Integers
{let i:int = 1234}
{let j:int = -1234}
{let k:int = 56}

{Table
    columns = 4,
    cell-border-width = 2pt,
    {text Signed Decimal Integer},
    {format "%d", i},
    {format "%d", j},
    {format "%d", k},

    {text ... with {monospace +} modifier (sign)},
    {format "%+d", i},
    {format "%+d", j},
    {format "%+d", k},

    {text ... with {italic width} set to 1},
    {format "%1d", i},
    {format "%1d", j},
    {format "%1d", k},

    {text ... with {italic width} set to 8},
    {format "%8d", i},
    {format "%8d", j},
    {format "%8d", k},

    {text ... and {monospace 0} modifier (leading zeros)},
    {format "%08d", i},
    {format "%08d", j},
    {format "%08d", k},

    {text Unsigned Decimal Integer},
    {format "%u", i},
    {text N/A},
    {format "%u", k},

    {text Unsigned Octal Integer},
    {format "%o", i},
    {text N/A},
    {format "%o", k},

    {text ... with {monospace #} modifier},
    {format "%#o", i},
    {text N/A},
    {format "%#o", k},

    {text Unsigned Hexadecimal Integer},
    {format "%x", i},
    {text N/A},
    {format "%x", k},

    {text ... with {monospace #} modifier},
    {format "%#x", i},
    {text N/A},
    {format "%#x", k},

    {text Unsigned Binary Integer},
    {format "%b", i},
    {text N/A},
    {format "%b", k},

    {text ... with {monospace #} modifier},
    {format "%#b", i},
    {text N/A},
    {format "%#b", k}
}

Example

This example shows some of the formatting operations that you can perform on floating point numbers.


Example: Formatting Floating Point Numbers
{let i:double = 1357.6863}
{let j:double = 36.69}
{let k:double = -36.69}

{Table
    columns = 4,
    cell-border-width = 2pt,
    {text Standard Notation},
    {format "%f", i},
    {format "%f", j},
    {format "%f", k},

    {text ... with {monospace +} modifier (sign)},
    {format "%+f", i},
    {format "%+f", j},
    {format "%+f", k},

    {text ... with {italic width} set to 2},
    {format "%2f", i},
    {format "%2f", j},
    {format "%2f", k},

    {text ... with {italic width} set to 8},
    {format "%8f", i},
    {format "%8f", j},
    {format "%8f", k},

    {text ... with {italic precision} set to 2},
    {format "%.2f", i},
    {format "%.2f", j},
    {format "%.2f", k},

    {text ... and {monospace 0} modifier (leading zeros)},
    {format "%0.2f", i},
    {format "%0.2f", j},
    {format "%0.2f", k},

    {text ... with {italic precision} set to 8},
    {format "%.8f", i},
    {format "%.8f", j},
    {format "%.8f", k},

    {text Scientific Notation (e)},
    {format "%e", i},
    {format "%e", j},
    {format "%e", k},

    {text Scientific Notation (E)},
    {format "%E", i},
    {format "%E", j},
    {format "%E", k},

    {text Mixed Notation},
    {format "%g", i},
    {format "%g", j},
    {format "%g", k}
}

Example

This example shows some of the formatting operations that you can perform on strings.


Example: Formatting Strings
{let s1:String = "Hello!"}
{let s2:String = "Hello World!"}
{let s3:String = "Hello World, here comes... Curl!"}

{Table columns=4, cell-border-width=2pt,
       {text String},
       {format "%s", s1},
       {format "%s", s2},
       {format "%s", s3},

       {text ... with {italic width} set to 4},
       {format "%4s", s1},
       {format "%4s", s2},
       {format "%4s", s3},

       {text ... with {italic width} set to 26},
       {format "%26s", s1},
       {format "%26s", s2},
       {format "%26s", s3},

       {text ... with {italic precision} set to 4},
       {format "%.4s", s1},
       {format "%.4s", s2},
       {format "%.4s", s3},

       {text ... with {italic precision} set to 26},
       {format "%.26s", s1},
       {format "%.26s", s2},
       {format "%.26s", s3}
}

Example

This example shows the use of variable width and precision.


Example: Formatting With Width and Precision
|| Declare and initialize an int, a float, and a string
{let i:int = 12}
{let f:float = 56.789f}
{let s:String = "Hello World"}

|| Declare an initialize a variable that you can use for
|| the width and precision
{let v:int = 4}

|| Format and output the int, float, and string using a
|| variable width
{format "%0*d", v, i}
{br}{format "%*f", v, f}
{br}{format "%*s", v, s}

|| Change the value of the variable width and display
|| the int, float, and string
{set v = 8}
{format "%0*d", v, i}
{br}{format "%*f", v, f}
{br}{format "%*s", v, s}

|| Use variable precision
{format "%0.*d", v, i}
{br}{format "%.*f", v, f}
{br}{format "%.*s", v, s}

Example

This example demonstrates the ability to specify a rest argument index for each format specifier.


Example: Specifying Format Argument Indexes
|| Output a string with two formatting characters:
||  - A string %s.
||  - A decimal number with a 2-digit width.
{format "The %s concerns how computers deal with the year %02d", "Y2K problem", 0}

|| Output the same string; this time specifying the
|| rest arguments.
{format "The %1!s! concerns how computers deal with the year %2!02d!", "Y2K problem", 0}

|| And finally, mix things up a bit.
{format "The %2!s! concerns how computers deal with the year %1!02d!", 0, "Y2K problem"}

Notes

In the C/C++ programming languages, the printf format specifiers (from which ours were adopted) also have a size specification (h, l, L, or sometimes q) for the size of the item being formatted. For compatibility, Curl accepts any number of these codes in a format specifier, but simply ignores them completely.

Curl does not support the %n and %p format specifiers that are available in the C/C++ programming languages.

Curl allows %s to be used in ways which would be illegal in the C/C++ programming languages. Note that although %s is often semantically identical to other format specifiers, it is usually much faster, especially when no format modifiers are used.

The output from a format expression includes any spaces produced by the format string itself, or during the formatting, However, if you display the output of a format expression in a TextFlowBox (such as an applet), the whitespace will be collapsed.