Improve markdown and add colored code syntax

This commit is contained in:
Martin Delille 2020-04-23 11:50:15 +02:00
parent f082897a23
commit c38ad5bdfb
No known key found for this signature in database
GPG Key ID: 9E8539581F123D43
2 changed files with 67 additions and 42 deletions

View File

@ -6,7 +6,7 @@
The model for emitting YAML is `std::ostream` manipulators. A `YAML::Emitter` objects acts as an output stream, and its output can be retrieved through the `c_str()` function (as in `std::string`). For a simple example: The model for emitting YAML is `std::ostream` manipulators. A `YAML::Emitter` objects acts as an output stream, and its output can be retrieved through the `c_str()` function (as in `std::string`). For a simple example:
``` ```cpp
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
int main() int main()
@ -23,7 +23,7 @@ int main()
A `YAML::Emitter` object acts as a state machine, and we use manipulators to move it between states. Here's a simple sequence: A `YAML::Emitter` object acts as a state machine, and we use manipulators to move it between states. Here's a simple sequence:
``` ```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginSeq; out << YAML::BeginSeq;
out << "eggs"; out << "eggs";
@ -31,15 +31,18 @@ out << "bread";
out << "milk"; out << "milk";
out << YAML::EndSeq; out << YAML::EndSeq;
``` ```
produces produces
```
```yaml
- eggs - eggs
- bread - bread
- milk - milk
``` ```
A simple map: A simple map:
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginMap; out << YAML::BeginMap;
out << YAML::Key << "name"; out << YAML::Key << "name";
@ -48,14 +51,17 @@ out << YAML::Key << "position";
out << YAML::Value << "LF"; out << YAML::Value << "LF";
out << YAML::EndMap; out << YAML::EndMap;
``` ```
produces produces
```
```yaml
name: Ryan Braun name: Ryan Braun
position: LF position: LF
``` ```
These elements can, of course, be nested: These elements can, of course, be nested:
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginMap; out << YAML::BeginMap;
out << YAML::Key << "name"; out << YAML::Key << "name";
@ -64,8 +70,10 @@ out << YAML::Key << "children";
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq; out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
out << YAML::EndMap; out << YAML::EndMap;
``` ```
produces produces
```
```yaml
name: Barack Obama name: Barack Obama
children: children:
- Sasha - Sasha
@ -75,30 +83,37 @@ children:
# Using Manipulators # # Using Manipulators #
To deviate from standard formatting, you can use manipulators to modify the output format. For example, To deviate from standard formatting, you can use manipulators to modify the output format. For example,
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::Literal << "A\n B\n C"; out << YAML::Literal << "A\n B\n C";
``` ```
produces produces
```
```yaml
| |
A A
B B
C C
``` ```
and and
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::Flow; out << YAML::Flow;
out << YAML::BeginSeq << 2 << 3 << 5 << 7 << 11 << YAML::EndSeq; out << YAML::BeginSeq << 2 << 3 << 5 << 7 << 11 << YAML::EndSeq;
``` ```
produces produces
```
```yaml
[2, 3, 5, 7, 11] [2, 3, 5, 7, 11]
``` ```
Comments act like manipulators: Comments act like manipulators:
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginMap; out << YAML::BeginMap;
out << YAML::Key << "method"; out << YAML::Key << "method";
@ -106,13 +121,16 @@ out << YAML::Value << "least squares";
out << YAML::Comment("should we change this method?"); out << YAML::Comment("should we change this method?");
out << YAML::EndMap; out << YAML::EndMap;
``` ```
produces produces
```
```yaml
method: least squares # should we change this method? method: least squares # should we change this method?
``` ```
And so do aliases/anchors: And so do aliases/anchors:
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginSeq; out << YAML::BeginSeq;
out << YAML::Anchor("fred"); out << YAML::Anchor("fred");
@ -123,8 +141,10 @@ out << YAML::EndMap;
out << YAML::Alias("fred"); out << YAML::Alias("fred");
out << YAML::EndSeq; out << YAML::EndSeq;
``` ```
produces produces
```
```yaml
- &fred - &fred
name: Fred name: Fred
age: 42 age: 42
@ -133,7 +153,8 @@ produces
# STL Containers, and Other Overloads # # STL Containers, and Other Overloads #
We overload `operator <<` for `std::vector`, `std::list`, and `std::map`, so you can write stuff like: We overload `operator <<` for `std::vector`, `std::list`, and `std::map`, so you can write stuff like:
```
```cpp
std::vector <int> squares; std::vector <int> squares;
squares.push_back(1); squares.push_back(1);
squares.push_back(4); squares.push_back(4);
@ -150,8 +171,10 @@ out << YAML::Flow << squares;
out << ages; out << ages;
out << YAML::EndSeq; out << YAML::EndSeq;
``` ```
to produce
``` produces
```yaml
- [1, 4, 9, 16] - [1, 4, 9, 16]
- -
Daniel: 26 Daniel: 26
@ -159,7 +182,8 @@ to produce
``` ```
Of course, you can overload `operator <<` for your own types: Of course, you can overload `operator <<` for your own types:
```
```cpp
struct Vec3 { int x; int y; int z; }; struct Vec3 { int x; int y; int z; };
YAML::Emitter& operator << (YAML::Emitter& out, const Vec3& v) { YAML::Emitter& operator << (YAML::Emitter& out, const Vec3& v) {
out << YAML::Flow; out << YAML::Flow;
@ -177,7 +201,7 @@ We also overload `operator << ` for `YAML::Node`s in both APIs, so you can outpu
The output is always UTF-8. By default, yaml-cpp will output as much as it can without escaping any characters. If you want to restrict the output to ASCII, use the manipulator `YAML::EscapeNonAscii`: The output is always UTF-8. By default, yaml-cpp will output as much as it can without escaping any characters. If you want to restrict the output to ASCII, use the manipulator `YAML::EscapeNonAscii`:
``` ```cpp
emitter.SetOutputCharset(YAML::EscapeNonAscii); emitter.SetOutputCharset(YAML::EscapeNonAscii);
``` ```
@ -186,7 +210,8 @@ emitter.SetOutputCharset(YAML::EscapeNonAscii);
Manipulators affect the **next** output item in the stream. If that item is a `BeginSeq` or `BeginMap`, the manipulator lasts until the corresponding `EndSeq` or `EndMap`. (However, within that sequence or map, you can override the manipulator locally, etc.; in effect, there's a "manipulator stack" behind the scenes.) Manipulators affect the **next** output item in the stream. If that item is a `BeginSeq` or `BeginMap`, the manipulator lasts until the corresponding `EndSeq` or `EndMap`. (However, within that sequence or map, you can override the manipulator locally, etc.; in effect, there's a "manipulator stack" behind the scenes.)
If you want to permanently change a setting, there are global setters corresponding to each manipulator, e.g.: If you want to permanently change a setting, there are global setters corresponding to each manipulator, e.g.:
```
```cpp
YAML::Emitter out; YAML::Emitter out;
out.SetIndent(4); out.SetIndent(4);
out.SetMapStyle(YAML::Flow); out.SetMapStyle(YAML::Flow);
@ -196,10 +221,10 @@ out.SetMapStyle(YAML::Flow);
If something goes wrong when you're emitting a document, it must be something like forgetting a `YAML::EndSeq`, or a misplaced `YAML::Key`. In this case, emitting silently fails (no more output is emitted) and an error flag is set. For example: If something goes wrong when you're emitting a document, it must be something like forgetting a `YAML::EndSeq`, or a misplaced `YAML::Key`. In this case, emitting silently fails (no more output is emitted) and an error flag is set. For example:
``` ```cpp
YAML::Emitter out; YAML::Emitter out;
assert(out.good()); assert(out.good());
out << YAML::Key; out << YAML::Key;
assert(!out.good()); assert(!out.good());
std::cout << "Emitter error: " << out.GetLastError() << "\n"; std::cout << "Emitter error: " << out.GetLastError() << "\n";
``` ```

View File

@ -2,7 +2,7 @@
A typical example, loading a configuration file, might look like this: A typical example, loading a configuration file, might look like this:
``` ```cpp
YAML::Node config = YAML::LoadFile("config.yaml"); YAML::Node config = YAML::LoadFile("config.yaml");
if (config["lastLogin"]) { if (config["lastLogin"]) {
@ -22,7 +22,7 @@ fout << config;
All nodes in a YAML document (including the root) are represented by `YAML::Node`. You can check what kind it is: All nodes in a YAML document (including the root) are represented by `YAML::Node`. You can check what kind it is:
``` ```cpp
YAML::Node node = YAML::Load("[1, 2, 3]"); YAML::Node node = YAML::Load("[1, 2, 3]");
assert(node.Type() == YAML::NodeType::Sequence); assert(node.Type() == YAML::NodeType::Sequence);
assert(node.IsSequence()); // a shortcut! assert(node.IsSequence()); // a shortcut!
@ -30,7 +30,7 @@ assert(node.IsSequence()); // a shortcut!
Collection nodes (sequences and maps) act somewhat like STL vectors and maps: Collection nodes (sequences and maps) act somewhat like STL vectors and maps:
``` ```cpp
YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]"); YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]");
for (std::size_t i=0;i<primes.size();i++) { for (std::size_t i=0;i<primes.size();i++) {
std::cout << primes[i].as<int>() << "\n"; std::cout << primes[i].as<int>() << "\n";
@ -46,7 +46,7 @@ assert(primes.size() == 6);
and and
``` ```cpp
YAML::Node lineup = YAML::Load("{1B: Prince Fielder, 2B: Rickie Weeks, LF: Ryan Braun}"); YAML::Node lineup = YAML::Load("{1B: Prince Fielder, 2B: Rickie Weeks, LF: Ryan Braun}");
for(YAML::const_iterator it=lineup.begin();it!=lineup.end();++it) { for(YAML::const_iterator it=lineup.begin();it!=lineup.end();++it) {
std::cout << "Playing at " << it->first.as<std::string>() << " is " << it->second.as<std::string>() << "\n"; std::cout << "Playing at " << it->first.as<std::string>() << " is " << it->second.as<std::string>() << "\n";
@ -59,7 +59,7 @@ assert(lineup.size() == 5);
Querying for keys does **not** create them automatically (this makes handling optional map entries very easy) Querying for keys does **not** create them automatically (this makes handling optional map entries very easy)
``` ```cpp
YAML::Node node = YAML::Load("{name: Brewers, city: Milwaukee}"); YAML::Node node = YAML::Load("{name: Brewers, city: Milwaukee}");
if (node["name"]) { if (node["name"]) {
std::cout << node["name"].as<std::string>() << "\n"; std::cout << node["name"].as<std::string>() << "\n";
@ -72,7 +72,7 @@ assert(node.size() == 2); // the previous call didn't create a node
If you're not sure what kind of data you're getting, you can query the type of a node: If you're not sure what kind of data you're getting, you can query the type of a node:
``` ```cpp
switch (node.Type()) { switch (node.Type()) {
case Null: // ... case Null: // ...
case Scalar: // ... case Scalar: // ...
@ -84,7 +84,7 @@ switch (node.Type()) {
or ask directly whether it's a particular type, e.g.: or ask directly whether it's a particular type, e.g.:
``` ```cpp
if (node.IsSequence()) { if (node.IsSequence()) {
// ... // ...
} }
@ -94,7 +94,7 @@ if (node.IsSequence()) {
You can build `YAML::Node` from scratch: You can build `YAML::Node` from scratch:
``` ```cpp
YAML::Node node; // starts out as null YAML::Node node; // starts out as null
node["key"] = "value"; // it now is a map node node["key"] = "value"; // it now is a map node
node["seq"].push_back("first element"); // node["seq"] automatically becomes a sequence node["seq"].push_back("first element"); // node["seq"] automatically becomes a sequence
@ -110,7 +110,7 @@ node[node["mirror"]] = node["seq"]; // and strange loops :)
The above node is now: The above node is now:
``` ```yaml
&1 &1
key: value key: value
&2 seq: [&3 "element #1", second element] &2 seq: [&3 "element #1", second element]
@ -123,7 +123,7 @@ self: *1
Sequences can be turned into maps by asking for non-integer keys. For example, Sequences can be turned into maps by asking for non-integer keys. For example,
``` ```cpp
YAML::Node node = YAML::Load("[1, 2, 3]"); YAML::Node node = YAML::Load("[1, 2, 3]");
node[1] = 5; // still a sequence, [1, 5, 3] node[1] = 5; // still a sequence, [1, 5, 3]
node.push_back(-3) // still a sequence, [1, 5, 3, -3] node.push_back(-3) // still a sequence, [1, 5, 3, -3]
@ -132,7 +132,7 @@ node["key"] = "value"; // now it's a map! {0: 1, 1: 5, 2: 3, 3: -3, key: value}
Indexing a sequence node by an index that's not in its range will _usually_ turn it into a map, but if the index is one past the end of the sequence, then the sequence will grow by one to accommodate it. (That's the **only** exception to this rule.) For example, Indexing a sequence node by an index that's not in its range will _usually_ turn it into a map, but if the index is one past the end of the sequence, then the sequence will grow by one to accommodate it. (That's the **only** exception to this rule.) For example,
``` ```cpp
YAML::Node node = YAML::Load("[1, 2, 3]"); YAML::Node node = YAML::Load("[1, 2, 3]");
node[3] = 4; // still a sequence, [1, 2, 3, 4] node[3] = 4; // still a sequence, [1, 2, 3, 4]
node[10] = 10; // now it's a map! {0: 1, 1: 2, 2: 3, 3: 4, 10: 10} node[10] = 10; // now it's a map! {0: 1, 1: 2, 2: 3, 3: 4, 10: 10}
@ -142,7 +142,7 @@ node[10] = 10; // now it's a map! {0: 1, 1: 2, 2: 3, 3: 4, 10: 10}
Yaml-cpp has built-in conversion to and from most built-in data types, as well as `std::vector`, `std::list`, and `std::map`. The following examples demonstrate when those conversions are used: Yaml-cpp has built-in conversion to and from most built-in data types, as well as `std::vector`, `std::list`, and `std::map`. The following examples demonstrate when those conversions are used:
``` ```cpp
YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}"); YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}");
// this needs the conversion from Node to double // this needs the conversion from Node to double
@ -160,13 +160,13 @@ std::string str = node[v].as<std::string>();
To use yaml-cpp with your own data types, you need to specialize the YAML::convert<> template class. For example, suppose you had a simple `Vec3` class: To use yaml-cpp with your own data types, you need to specialize the YAML::convert<> template class. For example, suppose you had a simple `Vec3` class:
``` ```cpp
struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ }; struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ };
``` ```
You could write You could write
``` ```cpp
namespace YAML { namespace YAML {
template<> template<>
struct convert<Vec3> { struct convert<Vec3> {
@ -194,7 +194,7 @@ struct convert<Vec3> {
Then you could use `Vec3` wherever you could use any other type: Then you could use `Vec3` wherever you could use any other type:
``` ```cpp
YAML::Node node = YAML::Load("start: [1, 3, 0]"); YAML::Node node = YAML::Load("start: [1, 3, 0]");
Vec3 v = node["start"].as<Vec3>(); Vec3 v = node["start"].as<Vec3>();
node["end"] = Vec3(2, -1, 0); node["end"] = Vec3(2, -1, 0);