From 4fc3fce9cbf916fe6889752421ded17ab2512e0f Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 29 May 2024 19:01:09 -0700 Subject: [PATCH] Improve syntax markdown --- doc/syntax.md | 191 ++++++++++++++++++++++++++++---------------------- 1 file changed, 108 insertions(+), 83 deletions(-) diff --git a/doc/syntax.md b/doc/syntax.md index 014b41aa..e2a5219d 100644 --- a/doc/syntax.md +++ b/doc/syntax.md @@ -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 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: - "First, thou shalt count to {0}" // References the first argument - "Bring me a {}" // Implicitly references the first argument - "From {} to {}" // Same as "From {0} to {1}" +```c++ +"First, thou shalt count to {0}" // References the first argument +"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 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 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 @@ -81,12 +83,11 @@ type ::= "a" | "A" | "b" | "B" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "o" | "p" | "s" | "x" | "X" | "?" -The *fill* character can be any Unicode code point other than `'{'` or -`'}'`. The presence of a fill character is signaled by the character -following it, which must be one of the alignment options. If the second -character of *format_spec* is not a valid alignment option, then it is -assumed that both the fill character and the alignment option are -absent. +The *fill* character can be any Unicode code point other than `'{'` or `'}'`. +The presence of a fill character is signaled by the character following it, +which must be one of the alignment options. If the second character of +*format_spec* is not a valid alignment option, then it is assumed that both +the fill character and the alignment option are absent. 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. | | none | The same as `'p'`. | -## Chrono Format Specifications {#chrono-specs} +## Chrono Format Specifications Format specifications for chrono duration and time point types as well as `std::tm` have the following syntax:
-chrono_format_spec ::= [[fill]align][width]["." precision][chrono_specs]
+chrono_format_spec ::= [[fill]align][width]["." precision][chrono_specs]
 chrono_specs       ::= [chrono_specs] conversion_spec | chrono_specs literal_char
 conversion_spec    ::= "%" [modifier] chrono_type
 literal_char       ::= 
@@ -358,24 +359,26 @@ characters or strings are printed according to the provided specification.
 
 Examples:
 
-    fmt::format("{}", std::vector{10, 20, 30});
-    // Result: [10, 20, 30]
-    fmt::format("{::#x}", std::vector{10, 20, 30});
-    // Result: [0xa, 0x14, 0x1e]
-    fmt::format("{}", vector{'h', 'e', 'l', 'l', 'o'});
-    // Result: ['h', 'e', 'l', 'l', 'o']
-    fmt::format("{:n}", vector{'h', 'e', 'l', 'l', 'o'});
-    // Result: 'h', 'e', 'l', 'l', 'o'
-    fmt::format("{:s}", vector{'h', 'e', 'l', 'l', 'o'});
-    // Result: "hello"
-    fmt::format("{:?s}", vector{'h', 'e', 'l', 'l', 'o', '\n'});
-    // Result: "hello\n"
-    fmt::format("{::}", vector{'h', 'e', 'l', 'l', 'o'});
-    // Result: [h, e, l, l, o]
-    fmt::format("{::d}", vector{'h', 'e', 'l', 'l', 'o'});
-    // Result: [104, 101, 108, 108, 111]
+```c++
+fmt::print("{}", std::vector{10, 20, 30});
+// Output: [10, 20, 30]
+fmt::print("{::#x}", std::vector{10, 20, 30});
+// Output: [0xa, 0x14, 0x1e]
+fmt::print("{}", std::vector{'h', 'e', 'l', 'l', 'o'});
+// Output: ['h', 'e', 'l', 'l', 'o']
+fmt::print("{:n}", std::vector{'h', 'e', 'l', 'l', 'o'});
+// Output: 'h', 'e', 'l', 'l', 'o'
+fmt::print("{:s}", std::vector{'h', 'e', 'l', 'l', 'o'});
+// Output: "hello"
+fmt::print("{:?s}", std::vector{'h', 'e', 'l', 'l', 'o', '\n'});
+// Output: "hello\n"
+fmt::print("{::}", std::vector{'h', 'e', 'l', 'l', 'o'});
+// Output: [h, e, l, l, o]
+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
 the printf formatting.
@@ -389,88 +392,110 @@ the following examples.
 
 Accessing arguments by position:
 
-    fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
-    // Result: "a, b, c"
-    fmt::format("{}, {}, {}", 'a', 'b', 'c');
-    // Result: "a, b, c"
-    fmt::format("{2}, {1}, {0}", 'a', 'b', 'c');
-    // Result: "c, b, a"
-    fmt::format("{0}{1}{0}", "abra", "cad");  // arguments' indices can be repeated
-    // Result: "abracadabra"
+```c++
+fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
+// Result: "a, b, c"
+fmt::format("{}, {}, {}", 'a', 'b', 'c');
+// Result: "a, b, c"
+fmt::format("{2}, {1}, {0}", 'a', 'b', 'c');
+// Result: "c, b, a"
+fmt::format("{0}{1}{0}", "abra", "cad");  // arguments' indices can be repeated
+// Result: "abracadabra"
+```
 
 Aligning the text and specifying a width:
 
-    fmt::format("{:<30}", "left aligned");
-    // Result: "left aligned                  "
-    fmt::format("{:>30}", "right aligned");
-    // Result: "                 right aligned"
-    fmt::format("{:^30}", "centered");
-    // Result: "           centered           "
-    fmt::format("{:*^30}", "centered");  // use '*' as a fill char
-    // Result: "***********centered***********"
+```c++
+fmt::format("{:<30}", "left aligned");
+// Result: "left aligned                  "
+fmt::format("{:>30}", "right aligned");
+// Result: "                 right aligned"
+fmt::format("{:^30}", "centered");
+// Result: "           centered           "
+fmt::format("{:*^30}", "centered");  // use '*' as a fill char
+// Result: "***********centered***********"
+```
 
 Dynamic width:
 
-    fmt::format("{:<{}}", "left aligned", 30);
-    // Result: "left aligned                  "
+```c++
+fmt::format("{:<{}}", "left aligned", 30);
+// Result: "left aligned                  "
+```
 
 Dynamic precision:
 
-    fmt::format("{:.{}f}", 3.14, 1);
-    // Result: "3.1"
+```c++
+fmt::format("{:.{}f}", 3.14, 1);
+// Result: "3.1"
+```
 
 Replacing `%+f`, `%-f`, and `% f` and specifying a sign:
 
-    fmt::format("{:+f}; {:+f}", 3.14, -3.14);  // show it always
-    // Result: "+3.140000; -3.140000"
-    fmt::format("{: f}; {: f}", 3.14, -3.14);  // show a space for positive numbers
-    // 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"
+```c++
+fmt::format("{:+f}; {:+f}", 3.14, -3.14);  // show it always
+// Result: "+3.140000; -3.140000"
+fmt::format("{: f}; {: f}", 3.14, -3.14);  // show a space for positive numbers
+// 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:
 
-    fmt::format("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
-    // Result: "int: 42;  hex: 2a;  oct: 52; bin: 101010"
-    // with 0x or 0 or 0b as prefix:
-    fmt::format("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}", 42);
-    // Result: "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"
+```c++
+fmt::format("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
+// Result: "int: 42;  hex: 2a;  oct: 52; bin: 101010"
+// with 0x or 0 or 0b as prefix:
+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:
 
-    fmt::format("{:#04x}", 0);
-    // Result: "0x00"
+```c++
+fmt::format("{:#04x}", 0);
+// Result: "0x00"
+```
 
 Box drawing using Unicode fill:
 
-    fmt::print(
-      "┌{0:─^{2}}┐\n"
-      "│{1: ^{2}}│\n"
-      "└{0:─^{2}}┘\n", "", "Hello, world!", 20);
+```c++
+fmt::print(
+    "┌{0:─^{2}}┐\n"
+    "│{1: ^{2}}│\n"
+    "└{0:─^{2}}┘\n", "", "Hello, world!", 20);
+```
 
 prints:
 
-    ┌────────────────────┐
-    │   Hello, world!    │
-    └────────────────────┘
+```
+┌────────────────────┐
+│   Hello, world!    │
+└────────────────────┘
+```
 
 Using type-specific formatting:
 
-    #include 
+```c++
+#include 
 
-    auto t = tm();
-    t.tm_year = 2010 - 1900;
-    t.tm_mon = 7;
-    t.tm_mday = 4;
-    t.tm_hour = 12;
-    t.tm_min = 15;
-    t.tm_sec = 58;
-    fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
-    // Prints: 2010-08-04 12:15:58
+auto t = tm();
+t.tm_year = 2010 - 1900;
+t.tm_mon = 7;
+t.tm_mday = 4;
+t.tm_hour = 12;
+t.tm_min = 15;
+t.tm_sec = 58;
+fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
+// Prints: 2010-08-04 12:15:58
+```
 
 Using the comma as a thousands separator:
 
-    #include 
+```c++
+#include 
 
-    auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
-    // s == "1,234,567,890"
+auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
+// s == "1,234,567,890"
+```