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:
```
```cpp
#include "yaml-cpp/yaml.h"
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:
```
```cpp
YAML::Emitter out;
out << YAML::BeginSeq;
out << "eggs";
@ -31,15 +31,18 @@ out << "bread";
out << "milk";
out << YAML::EndSeq;
```
produces
```
```yaml
- eggs
- bread
- milk
```
A simple map:
```
```cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "name";
@ -48,14 +51,17 @@ out << YAML::Key << "position";
out << YAML::Value << "LF";
out << YAML::EndMap;
```
produces
```
```yaml
name: Ryan Braun
position: LF
```
These elements can, of course, be nested:
```
```cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "name";
@ -64,8 +70,10 @@ out << YAML::Key << "children";
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
out << YAML::EndMap;
```
produces
```
```yaml
name: Barack Obama
children:
- Sasha
@ -75,30 +83,37 @@ children:
# Using Manipulators #
To deviate from standard formatting, you can use manipulators to modify the output format. For example,
```
```cpp
YAML::Emitter out;
out << YAML::Literal << "A\n B\n C";
```
produces
```
```yaml
|
A
B
C
```
and
```
```cpp
YAML::Emitter out;
out << YAML::Flow;
out << YAML::BeginSeq << 2 << 3 << 5 << 7 << 11 << YAML::EndSeq;
```
produces
```
```yaml
[2, 3, 5, 7, 11]
```
Comments act like manipulators:
```
```cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "method";
@ -106,13 +121,16 @@ out << YAML::Value << "least squares";
out << YAML::Comment("should we change this method?");
out << YAML::EndMap;
```
produces
```
```yaml
method: least squares # should we change this method?
```
And so do aliases/anchors:
```
```cpp
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::Anchor("fred");
@ -123,8 +141,10 @@ out << YAML::EndMap;
out << YAML::Alias("fred");
out << YAML::EndSeq;
```
produces
```
```yaml
- &fred
name: Fred
age: 42
@ -133,7 +153,8 @@ produces
# STL Containers, and Other Overloads #
We overload `operator <<` for `std::vector`, `std::list`, and `std::map`, so you can write stuff like:
```
```cpp
std::vector <int> squares;
squares.push_back(1);
squares.push_back(4);
@ -150,8 +171,10 @@ out << YAML::Flow << squares;
out << ages;
out << YAML::EndSeq;
```
to produce
```
produces
```yaml
- [1, 4, 9, 16]
-
Daniel: 26
@ -159,7 +182,8 @@ to produce
```
Of course, you can overload `operator <<` for your own types:
```
```cpp
struct Vec3 { int x; int y; int z; };
YAML::Emitter& operator << (YAML::Emitter& out, const Vec3& v) {
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`:
```
```cpp
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.)
If you want to permanently change a setting, there are global setters corresponding to each manipulator, e.g.:
```
```cpp
YAML::Emitter out;
out.SetIndent(4);
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:
```
YAML::Emitter out;
assert(out.good());
out << YAML::Key;
assert(!out.good());
std::cout << "Emitter error: " << out.GetLastError() << "\n";
```cpp
YAML::Emitter out;
assert(out.good());
out << YAML::Key;
assert(!out.good());
std::cout << "Emitter error: " << out.GetLastError() << "\n";
```

View File

@ -2,7 +2,7 @@
A typical example, loading a configuration file, might look like this:
```
```cpp
YAML::Node config = YAML::LoadFile("config.yaml");
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:
```
```cpp
YAML::Node node = YAML::Load("[1, 2, 3]");
assert(node.Type() == YAML::NodeType::Sequence);
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:
```
```cpp
YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]");
for (std::size_t i=0;i<primes.size();i++) {
std::cout << primes[i].as<int>() << "\n";
@ -46,7 +46,7 @@ assert(primes.size() == 6);
and
```
```cpp
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) {
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)
```
```cpp
YAML::Node node = YAML::Load("{name: Brewers, city: Milwaukee}");
if (node["name"]) {
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:
```
```cpp
switch (node.Type()) {
case Null: // ...
case Scalar: // ...
@ -84,7 +84,7 @@ switch (node.Type()) {
or ask directly whether it's a particular type, e.g.:
```
```cpp
if (node.IsSequence()) {
// ...
}
@ -94,7 +94,7 @@ if (node.IsSequence()) {
You can build `YAML::Node` from scratch:
```
```cpp
YAML::Node node; // starts out as null
node["key"] = "value"; // it now is a map node
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:
```
```yaml
&1
key: value
&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,
```
```cpp
YAML::Node node = YAML::Load("[1, 2, 3]");
node[1] = 5; // still a sequence, [1, 5, 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,
```
```cpp
YAML::Node node = YAML::Load("[1, 2, 3]");
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}
@ -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:
```
```cpp
YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}");
// 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:
```
```cpp
struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ };
```
You could write
```
```cpp
namespace YAML {
template<>
struct convert<Vec3> {
@ -194,7 +194,7 @@ struct convert<Vec3> {
Then you could use `Vec3` wherever you could use any other type:
```
```cpp
YAML::Node node = YAML::Load("start: [1, 3, 0]");
Vec3 v = node["start"].as<Vec3>();
node["end"] = Vec3(2, -1, 0);