Improve syntax markdown

This commit is contained in:
Victor Zverovich
2024-05-29 19:01:09 -07:00
parent d6427ae7b2
commit 4fc3fce9cb

View File

@ -1,4 +1,4 @@
# Format String Syntax {#syntax} # Format String Syntax
[Formatting functions](api.md) such as `fmt::format` and `fmt::print` use the same [Formatting functions](api.md) such as `fmt::format` and `fmt::print` use the same
format string syntax described in this section. format string syntax described in this section.
@ -38,9 +38,11 @@ Named arguments can be referred to by their names or indices.
Some simple format string examples: Some simple format string examples:
"First, thou shalt count to {0}" // References the first argument ```c++
"Bring me a {}" // Implicitly references the first argument "First, thou shalt count to {0}" // References the first argument
"From {} to {}" // Same as "From {0} to {1}" "Bring me a {}" // Implicitly references the first argument
"From {} to {}" // Same as "From {0} to {1}"
```
The *format_spec* field contains a specification of how the value should The *format_spec* field contains a specification of how the value should
be presented, including such details as field width, alignment, padding, be presented, including such details as field width, alignment, padding,
@ -55,7 +57,7 @@ certain positions within it. These nested replacement fields can contain
only an argument id; format specifications are not allowed. This allows only an argument id; format specifications are not allowed. This allows
the formatting of a value to be dynamically specified. the formatting of a value to be dynamically specified.
See the [Format Examples](#formatexamples) section for some examples. See the [Format Examples](#format-examples) section for some examples.
## Format Specification Mini-Language ## Format Specification Mini-Language
@ -81,12 +83,11 @@ type ::= "a" | "A" | "b" | "B" | "c" | "d" | "e" | "E" | "f" | "F" |
"g" | "G" | "o" | "p" | "s" | "x" | "X" | "?" "g" | "G" | "o" | "p" | "s" | "x" | "X" | "?"
</pre> </pre>
The *fill* character can be any Unicode code point other than `'{'` or The *fill* character can be any Unicode code point other than `'{'` or `'}'`.
`'}'`. The presence of a fill character is signaled by the character The presence of a fill character is signaled by the character following it,
following it, which must be one of the alignment options. If the second which must be one of the alignment options. If the second character of
character of *format_spec* is not a valid alignment option, then it is *format_spec* is not a valid alignment option, then it is assumed that both
assumed that both the fill character and the alignment option are the fill character and the alignment option are absent.
absent.
The meaning of the various alignment options is as follows: The meaning of the various alignment options is as follows:
@ -257,14 +258,14 @@ The available presentation types for pointers are:
| `'p'` | Pointer format. This is the default type for pointers and may be omitted. | | `'p'` | Pointer format. This is the default type for pointers and may be omitted. |
| none | The same as `'p'`. | | none | The same as `'p'`. |
## Chrono Format Specifications {#chrono-specs} ## Chrono Format Specifications
Format specifications for chrono duration and time point types as well Format specifications for chrono duration and time point types as well
as `std::tm` have the following syntax: as `std::tm` have the following syntax:
<a id="chrono-format-spec"></a> <a id="chrono-format-spec"></a>
<pre> <pre>
chrono_format_spec ::= [[<a href="#replacement-field">fill</a>]<a href="#replacement-field">align</a>][<a href="#replacement-field">width</a>]["." <a href="#replacement-field">precision</a>][chrono_specs] chrono_format_spec ::= [[<a href="#format-spec">fill</a>]<a href="#format-spec">align</a>][<a href="#format-spec">width</a>]["." <a href="#format-spec">precision</a>][chrono_specs]
chrono_specs ::= [chrono_specs] conversion_spec | chrono_specs literal_char chrono_specs ::= [chrono_specs] conversion_spec | chrono_specs literal_char
conversion_spec ::= "%" [modifier] chrono_type conversion_spec ::= "%" [modifier] chrono_type
literal_char ::= <a character other than '{', '}' or '%'\> literal_char ::= <a character other than '{', '}' or '%'\>
@ -358,24 +359,26 @@ characters or strings are printed according to the provided specification.
Examples: Examples:
fmt::format("{}", std::vector{10, 20, 30}); ```c++
// Result: [10, 20, 30] fmt::print("{}", std::vector{10, 20, 30});
fmt::format("{::#x}", std::vector{10, 20, 30}); // Output: [10, 20, 30]
// Result: [0xa, 0x14, 0x1e] fmt::print("{::#x}", std::vector{10, 20, 30});
fmt::format("{}", vector{'h', 'e', 'l', 'l', 'o'}); // Output: [0xa, 0x14, 0x1e]
// Result: ['h', 'e', 'l', 'l', 'o'] fmt::print("{}", std::vector{'h', 'e', 'l', 'l', 'o'});
fmt::format("{:n}", vector{'h', 'e', 'l', 'l', 'o'}); // Output: ['h', 'e', 'l', 'l', 'o']
// Result: 'h', 'e', 'l', 'l', 'o' fmt::print("{:n}", std::vector{'h', 'e', 'l', 'l', 'o'});
fmt::format("{:s}", vector{'h', 'e', 'l', 'l', 'o'}); // Output: 'h', 'e', 'l', 'l', 'o'
// Result: "hello" fmt::print("{:s}", std::vector{'h', 'e', 'l', 'l', 'o'});
fmt::format("{:?s}", vector{'h', 'e', 'l', 'l', 'o', '\n'}); // Output: "hello"
// Result: "hello\n" fmt::print("{:?s}", std::vector{'h', 'e', 'l', 'l', 'o', '\n'});
fmt::format("{::}", vector{'h', 'e', 'l', 'l', 'o'}); // Output: "hello\n"
// Result: [h, e, l, l, o] fmt::print("{::}", std::vector{'h', 'e', 'l', 'l', 'o'});
fmt::format("{::d}", vector{'h', 'e', 'l', 'l', 'o'}); // Output: [h, e, l, l, o]
// Result: [104, 101, 108, 108, 111] fmt::print("{::d}", std::vector{'h', 'e', 'l', 'l', 'o'});
// Output: [104, 101, 108, 108, 111]
```
## Format Examples {#formatexamples} ## Format Examples
This section contains examples of the format syntax and comparison with This section contains examples of the format syntax and comparison with
the printf formatting. the printf formatting.
@ -389,88 +392,110 @@ the following examples.
Accessing arguments by position: Accessing arguments by position:
fmt::format("{0}, {1}, {2}", 'a', 'b', 'c'); ```c++
// Result: "a, b, c" fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
fmt::format("{}, {}, {}", 'a', 'b', 'c'); // Result: "a, b, c"
// Result: "a, b, c" fmt::format("{}, {}, {}", 'a', 'b', 'c');
fmt::format("{2}, {1}, {0}", 'a', 'b', 'c'); // Result: "a, b, c"
// Result: "c, b, a" fmt::format("{2}, {1}, {0}", 'a', 'b', 'c');
fmt::format("{0}{1}{0}", "abra", "cad"); // arguments' indices can be repeated // Result: "c, b, a"
// Result: "abracadabra" fmt::format("{0}{1}{0}", "abra", "cad"); // arguments' indices can be repeated
// Result: "abracadabra"
```
Aligning the text and specifying a width: Aligning the text and specifying a width:
fmt::format("{:<30}", "left aligned"); ```c++
// Result: "left aligned " fmt::format("{:<30}", "left aligned");
fmt::format("{:>30}", "right aligned"); // Result: "left aligned "
// Result: " right aligned" fmt::format("{:>30}", "right aligned");
fmt::format("{:^30}", "centered"); // Result: " right aligned"
// Result: " centered " fmt::format("{:^30}", "centered");
fmt::format("{:*^30}", "centered"); // use '*' as a fill char // Result: " centered "
// Result: "***********centered***********" fmt::format("{:*^30}", "centered"); // use '*' as a fill char
// Result: "***********centered***********"
```
Dynamic width: Dynamic width:
fmt::format("{:<{}}", "left aligned", 30); ```c++
// Result: "left aligned " fmt::format("{:<{}}", "left aligned", 30);
// Result: "left aligned "
```
Dynamic precision: Dynamic precision:
fmt::format("{:.{}f}", 3.14, 1); ```c++
// Result: "3.1" fmt::format("{:.{}f}", 3.14, 1);
// Result: "3.1"
```
Replacing `%+f`, `%-f`, and `% f` and specifying a sign: Replacing `%+f`, `%-f`, and `% f` and specifying a sign:
fmt::format("{:+f}; {:+f}", 3.14, -3.14); // show it always ```c++
// Result: "+3.140000; -3.140000" fmt::format("{:+f}; {:+f}", 3.14, -3.14); // show it always
fmt::format("{: f}; {: f}", 3.14, -3.14); // show a space for positive numbers // Result: "+3.140000; -3.140000"
// Result: " 3.140000; -3.140000" fmt::format("{: f}; {: f}", 3.14, -3.14); // show a space for positive numbers
fmt::format("{:-f}; {:-f}", 3.14, -3.14); // show only the minus -- same as '{:f}; {:f}' // Result: " 3.140000; -3.140000"
// Result: "3.140000; -3.140000" fmt::format("{:-f}; {:-f}", 3.14, -3.14); // show only the minus -- same as '{:f}; {:f}'
// Result: "3.140000; -3.140000"
```
Replacing `%x` and `%o` and converting the value to different bases: Replacing `%x` and `%o` and converting the value to different bases:
fmt::format("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); ```c++
// Result: "int: 42; hex: 2a; oct: 52; bin: 101010" fmt::format("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
// with 0x or 0 or 0b as prefix: // Result: "int: 42; hex: 2a; oct: 52; bin: 101010"
fmt::format("int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}", 42); // with 0x or 0 or 0b as prefix:
// Result: "int: 42; hex: 0x2a; oct: 052; bin: 0b101010" fmt::format("int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}", 42);
// Result: "int: 42; hex: 0x2a; oct: 052; bin: 0b101010"
```
Padded hex byte with prefix and always prints both hex characters: Padded hex byte with prefix and always prints both hex characters:
fmt::format("{:#04x}", 0); ```c++
// Result: "0x00" fmt::format("{:#04x}", 0);
// Result: "0x00"
```
Box drawing using Unicode fill: Box drawing using Unicode fill:
fmt::print( ```c++
"┌{0:─^{2}}┐\n" fmt::print(
"│{1: ^{2}}\n" "┌{0:─^{2}}\n"
"└{0:─^{2}}\n", "", "Hello, world!", 20); "│{1: ^{2}}\n"
"└{0:─^{2}}┘\n", "", "Hello, world!", 20);
```
prints: prints:
┌────────────────────┐ ```
│ Hello, world! │ ┌────────────────────┐
└────────────────────┘ │ Hello, world! │
└────────────────────┘
```
Using type-specific formatting: Using type-specific formatting:
#include <fmt/chrono.h> ```c++
#include <fmt/chrono.h>
auto t = tm(); auto t = tm();
t.tm_year = 2010 - 1900; t.tm_year = 2010 - 1900;
t.tm_mon = 7; t.tm_mon = 7;
t.tm_mday = 4; t.tm_mday = 4;
t.tm_hour = 12; t.tm_hour = 12;
t.tm_min = 15; t.tm_min = 15;
t.tm_sec = 58; t.tm_sec = 58;
fmt::print("{:%Y-%m-%d %H:%M:%S}", t); fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
// Prints: 2010-08-04 12:15:58 // Prints: 2010-08-04 12:15:58
```
Using the comma as a thousands separator: Using the comma as a thousands separator:
#include <fmt/format.h> ```c++
#include <fmt/format.h>
auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890); auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
// s == "1,234,567,890" // s == "1,234,567,890"
```