rapidyaml 0.16.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
YAML styles

Functions

void sample_style ()
 query/set node styles
void sample_style_flow_formatting ()
 control formatting of flow containers
void sample_style_flow_ml_indent ()
 control indentation of FLOW_ML1 and FLOW_MLN containers

Detailed Description

Function Documentation

◆ sample_style()

void sample_style ( )

query/set node styles

query/set/modify node style to control formatting of emitted YAML code.

See also:

See also
See more details about formatting flow containers in sample_style_flow_formatting() (below).

see also:

Definition at line 5101 of file quickstart.cpp.

5102{
5103 // we will be using these helpers throughout this function
5104 auto tostr = [](ryml::ConstNodeRef n) {
5106 };
5107 auto tostr_opts = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5108 return ryml::emitrs_yaml<std::string>(n, opts);
5109 };
5110 // let's parse this yaml:
5111 ryml::csubstr yaml = ""
5112 "block map:" "\n"
5113 " block key: block val" "\n"
5114 "block seq:" "\n"
5115 " - block val 1" "\n"
5116 " - block val 2" "\n"
5117 " - 'quoted'" "\n"
5118 "flow map, singleline: {flow key: flow val}" "\n"
5119 "flow seq, singleline: [flow val,flow val]" "\n"
5120 "flow map, multiline: {" "\n"
5121 " flow key: flow val" "\n"
5122 " }" "\n"
5123 "flow seq, multiline: [" "\n"
5124 " flow val," "\n"
5125 " flow val" "\n"
5126 " ]" "\n"
5127 "";
5128 ryml::Tree tree = ryml::parse_in_arena(yaml);
5129 // while parsing, ryml marks parsed nodes with their original style:
5130 CHECK(tree.rootref().is_block());
5131 CHECK(tree["block map"].is_key_plain());
5132 CHECK(tree["block seq"].is_key_plain());
5133 CHECK(tree["flow map, singleline"].is_key_plain());
5134 CHECK(tree["flow seq, singleline"].is_key_plain());
5135 CHECK(tree["flow map, multiline"].is_key_plain());
5136 CHECK(tree["flow seq, multiline"].is_key_plain());
5137 CHECK(tree["block map"].is_block());
5138 CHECK(tree["block seq"].is_block());
5139 // flow is either singleline (FLOW_SL) or multiline (FLOW_ML1)
5140 CHECK(tree["flow map, singleline"].is_flow_sl());
5141 CHECK(tree["flow seq, singleline"].is_flow_sl());
5142 CHECK(tree["flow map, multiline"].is_flow_ml1());
5143 CHECK(tree["flow seq, multiline"].is_flow_ml1());
5144 // is_flow() is equivalent to (is_flow_sl() || is_flow_ml1() || is_flow_mln())
5145 CHECK(tree["flow map, singleline"].is_flow());
5146 CHECK(tree["flow seq, singleline"].is_flow());
5147 CHECK(tree["flow map, multiline"].is_flow());
5148 CHECK(tree["flow seq, multiline"].is_flow());
5149 //
5150 // since the tree nodes are marked with their original parsed
5151 // style, emitting the parsed tree will preserve the original
5152 // style (minus whitespace):
5153 //
5154 CHECK(tostr(tree) == yaml); // same as before!
5155 //
5156 // you can set/modify the style programatically!
5157 //
5158 // here are more examples.
5159 //
5160 {
5161 ryml::NodeRef n = tree["block map"]; // Let's look at one node
5162 // It looks like this originally:
5163 CHECK(tostr(n) ==
5164 "block map:\n"
5165 " block key: block val\n"
5166 "");
5167 // let's modify its style:
5168 n.set_key_style(ryml::KEY_SQUO); // scalar style: to single-quoted scalar
5169 n.set_container_style(ryml::FLOW_SL); // container style: to flow singleline
5170 // now it looks like this:
5171 CHECK(tostr(n) ==
5172 "'block map': {block key: block val}\n"
5173 "");
5174 }
5175 // next example
5176 {
5177 ryml::NodeRef n = tree["block seq"];
5178 CHECK(tostr(n) == ""
5179 "block seq:\n"
5180 " - block val 1\n"
5181 " - block val 2\n"
5182 " - 'quoted'\n"
5183 "");
5184 n.set_key_style(ryml::KEY_DQUO); // scalar style: to double-quoted scalar
5185 n[2].set_val_style(ryml::VAL_PLAIN); // scalar style: to plain
5186 n.set_container_style(ryml::FLOW_MLN); // container style: to flow multiline, N values per line
5187 CHECK(tostr(n) == ""
5188 "\"block seq\": [\n"
5189 " block val 1,block val 2,quoted\n"
5190 " ]\n");
5191 n.set_container_style(ryml::FLOW_MLN|ryml::FLOW_SPC); // force space after comma
5192 CHECK(tostr(n) == ""
5193 "\"block seq\": [\n"
5194 " block val 1, block val 2, quoted\n"
5195 " ]\n");
5196 auto maxcols20 = ryml::EmitOptions{}.max_cols(20); // set the max number of cols for FLOW_MLN
5197 CHECK(tostr_opts(n, maxcols20) == ""
5198 "\"block seq\": [\n"
5199 " block val 1, block val 2,\n"
5200 " quoted\n"
5201 " ]\n");
5202 n.set_container_style(ryml::FLOW_MLN); // no spaces now
5203 CHECK(tostr_opts(n, maxcols20) == ""
5204 "\"block seq\": [\n"
5205 " block val 1,block val 2,\n"
5206 " quoted\n"
5207 " ]\n");
5208 n.set_container_style(ryml::FLOW_SL); // to flow singleline
5209 CHECK(tostr(n) == ""
5210 "\"block seq\": [block val 1,block val 2,quoted]\n");
5211 n.set_container_style(ryml::FLOW_SL|ryml::FLOW_SPC); // now with space after comma
5212 CHECK(tostr(n) == ""
5213 "\"block seq\": [block val 1, block val 2, quoted]\n");
5214 n.set_container_style(ryml::FLOW_ML1); // to flow multiline, 1 value per line
5215 CHECK(tostr(n) == ""
5216 "\"block seq\": [\n"
5217 " block val 1,\n"
5218 " block val 2,\n"
5219 " quoted\n"
5220 " ]\n");
5221 /// @see See more details about formatting flow containers in
5222 /// @ref sample_style_flow_formatting() (below).
5223 }
5224 // next example
5225 {
5226 ryml::NodeRef n = tree["flow map, singleline"];
5227 CHECK(tostr(n) == "flow map, singleline: {flow key: flow val}\n");
5229 n["flow key"].set_val_style(ryml::VAL_LITERAL);
5230 CHECK(tostr(n) == ""
5231 "flow map, singleline:\n"
5232 " flow key: |-\n"
5233 " flow val\n"
5234 "");
5235 }
5236 // next example
5237 {
5238 ryml::NodeRef n = tree["flow map, multiline"];
5239 CHECK(tostr(n) == ""
5240 "flow map, multiline: {\n"
5241 " flow key: flow val\n"
5242 " }\n"
5243 "");
5245 CHECK(tostr(n) == ""
5246 "flow map, multiline:\n"
5247 " flow key: flow val\n"
5248 "");
5249 }
5250 // next example
5251 {
5252 ryml::NodeRef n = tree["flow seq, singleline"];
5253 CHECK(tostr(n) == "flow seq, singleline: [flow val,flow val]\n");
5258 CHECK(tostr(n) == ""
5259 "? >-\n"
5260 " flow seq, singleline\n"
5261 ":\n"
5262 " - 'flow val'\n"
5263 " - \"flow val\"\n"
5264 "");
5265 }
5266 // next example
5267 {
5268 ryml::NodeRef n = tree["flow seq, multiline"];
5269 CHECK(tostr(n) == ""
5270 "flow seq, multiline: [\n"
5271 " flow val,\n"
5272 " flow val\n"
5273 " ]\n"
5274 "");
5276 CHECK(tostr(n) == "flow seq, multiline: [flow val,flow val]\n");
5277 }
5278 // note the full tree now:
5279 CHECK(tostr(tree) != yaml);
5280 CHECK(tostr(tree) ==
5281 "'block map': {block key: block val}" "\n"
5282 "\"block seq\": [" "\n"
5283 " block val 1," "\n"
5284 " block val 2," "\n"
5285 " quoted" "\n"
5286 " ]" "\n"
5287 "flow map, singleline:" "\n"
5288 " flow key: |-" "\n"
5289 " flow val" "\n"
5290 "? >-" "\n"
5291 " flow seq, singleline" "\n"
5292 ":" "\n"
5293 " - 'flow val'" "\n"
5294 " - \"flow val\"" "\n"
5295 "flow map, multiline:" "\n"
5296 " flow key: flow val" "\n"
5297 "flow seq, multiline: [flow val,flow val]" "\n"
5298 "");
5299 // you can clear the style of single nodes:
5300 tree["block map"].clear_style();
5301 tree["block seq"].clear_style();
5302 CHECK(tostr(tree) ==
5303 "block map:" "\n"
5304 " block key: block val" "\n"
5305 "block seq:" "\n"
5306 " - block val 1" "\n"
5307 " - block val 2" "\n"
5308 " - quoted" "\n"
5309 "flow map, singleline:" "\n"
5310 " flow key: |-" "\n"
5311 " flow val" "\n"
5312 "? >-" "\n"
5313 " flow seq, singleline" "\n"
5314 ":" "\n"
5315 " - 'flow val'" "\n"
5316 " - \"flow val\"" "\n"
5317 "flow map, multiline:" "\n"
5318 " flow key: flow val" "\n"
5319 "flow seq, multiline: [flow val,flow val]" "\n"
5320 "");
5321 // you can clear the style recursively:
5322 tree.rootref().clear_style(/*recurse*/true);
5323 // when emitting nodes which have no style set, ryml will default
5324 // to block format for containers, and call
5325 // ryml::scalar_style_choose() to pick the style for each scalar
5326 // (at the cost of a scan over each scalar). Note that ryml picks
5327 // single-quoted for scalars containing commas:
5328 CHECK(tostr(tree) ==
5329 "block map:" "\n"
5330 " block key: block val" "\n"
5331 "block seq:" "\n"
5332 " - block val 1" "\n"
5333 " - block val 2" "\n"
5334 " - quoted" "\n"
5335 "flow map, singleline:" "\n"
5336 " flow key: flow val" "\n"
5337 "flow seq, singleline:" "\n"
5338 " - flow val" "\n"
5339 " - flow val" "\n"
5340 "flow map, multiline:" "\n"
5341 " flow key: flow val" "\n"
5342 "flow seq, multiline:" "\n"
5343 " - flow val" "\n"
5344 " - flow val" "\n"
5345 "");
5346 // you can set the style based on type conditions:
5347 //
5348 // eg, set a single key to single-quoted
5349 tree["block map"].set_style_conditionally(/*type_mask*/ryml::KEY,
5350 /*remflags*/ryml::KEY_STYLE,
5351 /*addflags*/ryml::KEY_SQUO,
5352 /*recurse*/false);
5353 CHECK(tostr(tree) ==
5354 "'block map':" "\n"
5355 " block key: block val" "\n"
5356 "block seq:" "\n"
5357 " - block val 1" "\n"
5358 " - block val 2" "\n"
5359 " - quoted" "\n"
5360 "flow map, singleline:" "\n"
5361 " flow key: flow val" "\n"
5362 "flow seq, singleline:" "\n"
5363 " - flow val" "\n"
5364 " - flow val" "\n"
5365 "flow map, multiline:" "\n"
5366 " flow key: flow val" "\n"
5367 "flow seq, multiline:" "\n"
5368 " - flow val" "\n"
5369 " - flow val" "\n"
5370 "");
5371 // change all keys to single-quoted:
5372 tree.rootref().set_style_conditionally(/*type_mask*/ryml::KEY,
5373 /*remflags*/ryml::KEY_STYLE,
5374 /*addflags*/ryml::KEY_SQUO,
5375 /*recurse*/true);
5376 // change all vals to double-quoted
5377 tree.rootref().set_style_conditionally(/*type_mask*/ryml::VAL,
5378 /*remflags*/ryml::VAL_STYLE,
5379 /*addflags*/ryml::VAL_DQUO,
5380 /*recurse*/true);
5381 // change all seqs to flow
5382 tree.rootref().set_style_conditionally(/*type_mask*/ryml::SEQ,
5383 /*remflags*/ryml::CONTAINER_STYLE,
5384 /*addflags*/ryml::FLOW_SL,
5385 /*recurse*/true);
5386 // change all maps to flow
5387 tree.rootref().set_style_conditionally(/*type_mask*/ryml::MAP,
5388 /*remflags*/ryml::CONTAINER_STYLE,
5389 /*addflags*/ryml::BLOCK,
5390 /*recurse*/true);
5391 // done!
5392 CHECK(tostr(tree) == ""
5393 "'block map':" "\n"
5394 " 'block key': \"block val\"" "\n"
5395 "'block seq': [\"block val 1\",\"block val 2\",\"quoted\"]" "\n"
5396 "'flow map, singleline':" "\n"
5397 " 'flow key': \"flow val\"" "\n"
5398 "'flow seq, singleline': [\"flow val\",\"flow val\"]" "\n"
5399 "'flow map, multiline':" "\n"
5400 " 'flow key': \"flow val\"" "\n"
5401 "'flow seq, multiline': [\"flow val\",\"flow val\"]" "\n"
5402 "");
5403 // you can also set a conditional style in a single node (or its branch if recurse is true):
5404 tree["flow seq, singleline"].set_style_conditionally(/*type_mask*/ryml::SEQ,
5405 /*remflags*/ryml::CONTAINER_STYLE,
5406 /*addflags*/ryml::BLOCK,
5407 /*recurse*/false);
5408 CHECK(tostr(tree) == ""
5409 "'block map':" "\n"
5410 " 'block key': \"block val\"" "\n"
5411 "'block seq': [\"block val 1\",\"block val 2\",\"quoted\"]" "\n"
5412 "'flow map, singleline':" "\n"
5413 " 'flow key': \"flow val\"" "\n"
5414 "'flow seq, singleline':" "\n"
5415 " - \"flow val\"" "\n"
5416 " - \"flow val\"" "\n"
5417 "'flow map, multiline':" "\n"
5418 " 'flow key': \"flow val\"" "\n"
5419 "'flow seq, multiline': [\"flow val\",\"flow val\"]" "\n"
5420 "");
5421 /// see also:
5422 /// - @ref ryml::scalar_style_choose_block()
5423 /// - @ref ryml::scalar_style_choose_flow()
5424 /// - @ref ryml::scalar_style_choose_json()
5425 /// - @ref ryml::scalar_style_query_squo()
5426 /// - @ref ryml::scalar_style_query_plain_flow()
5427 /// - @ref ryml::scalar_style_query_plain_block()
5428}
Holds a pointer to an existing tree, and a node id.
Definition node.hpp:737
A reference to a node in an existing yaml tree, offering a more convenient API than the index-based A...
Definition node.hpp:1063
void set_style_conditionally(NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
Definition node.hpp:1311
void clear_style(bool recurse=false)
Definition node.hpp:1305
void set_container_style(type_bits style)
Definition node.hpp:1267
void set_key_style(type_bits style)
Definition node.hpp:1268
void set_val_style(type_bits style)
Definition node.hpp:1269
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
Definition tree.cpp:56
void clear_style(id_type node, bool recurse=false)
Definition tree.cpp:1404
void set_style_conditionally(id_type node, NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
Definition tree.cpp:1414
substr emitrs_yaml(Tree const &t, id_type id, EmitOptions const &opts, CharOwningContainer *cont, bool append=false)
(1) emit+resize: emit YAML to the given std::string/std::vector<char>-like container,...
@ KEY_DQUO
mark key scalar as double quoted "
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:35
@ KEY
the scalar to the left of : in a map's member
Definition node_type.hpp:33
@ FLOW_ML1
mark container with multi-line flow style, 1 element per line
Definition node_type.hpp:75
@ VAL_STYLE
mask of VALQUO|VAL_PLAIN : all the val scalar styles for val (not container styles!...
@ FLOW_SL
mark container with single-line flow style
Definition node_type.hpp:56
@ VAL
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
Definition node_type.hpp:34
@ FLOW_MLN
mark container with multi-line flow style, n elements per line, wrapped (as set by EmitOptions::max_c...
Definition node_type.hpp:90
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:36
@ VAL_SQUO
mark val scalar as single quoted '
@ KEY_STYLE
mask of KEYQUO|KEY_PLAIN : all the key scalar styles for key (not container styles!...
@ VAL_PLAIN
mark val scalar as plain scalar (unquoted, even when multiline)
@ BLOCK
mark container with block style
@ FLOW_SPC
mark container with spaces after comma when in flow mode. Applies to both FLOW_SL and FLOW_MLN (but n...
@ VAL_DQUO
mark val scalar as double quoted "
@ CONTAINER_STYLE
mask of CONTAINER_STYLE_FLOW|CONTAINER_STYLE_BLOCK : all container style flags
@ KEY_SQUO
mark key scalar as single quoted '
@ VAL_LITERAL
mark val scalar as multiline, block literal |
@ KEY_FOLDED
mark key scalar as multiline, block folded >
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, Tree *tree, id_type node_id)
(1) parse YAML into an existing tree node. The filename will be used in any error messages arising du...
Definition parse.cpp:209
#define CHECK(predicate)
a testing assertion, used only in this quickstart
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356
A lightweight object containing options to be used when emitting.
EmitOptions & max_cols(id_type cols) noexcept
Set max columns for the emitted YAML in FLOW_MLN mode.
bool is_block() const RYML_NOEXCEPT
Forward to Tree::is_block().
Definition node.hpp:242

Referenced by main().

◆ sample_style_flow_formatting()

void sample_style_flow_formatting ( )

control formatting of flow containers

Shows how to control formatting of flow styles.

Definition at line 5434 of file quickstart.cpp.

5435{
5436 // we will be using this helper throughout this function
5437 auto tostr = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5438 return ryml::emitrs_yaml<std::string>(n, opts);
5439 };
5440 auto tostr_json = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5441 return ryml::emitrs_json<std::string>(n, opts);
5442 };
5443 const ryml::EmitOptions emit_defaults = ryml::EmitOptions{};
5444 // let's parse this, which is in FLOW_ML1 (flow multiline, 1 value per line):
5445 ryml::csubstr yaml = ""
5446 "{" "\n"
5447 " map: {" "\n"
5448 " seq: [" "\n"
5449 " 0," "\n"
5450 " 1," "\n"
5451 " 2," "\n"
5452 " 3," "\n"
5453 " [40,41]" "\n"
5454 " ]" "\n"
5455 " }" "\n"
5456 "}" "\n"
5457 "";
5458 // note that the parser defaults to detecting multiline flow
5459 // (FLOW_ML1) containers:
5460 {
5461 const ryml::Tree tree = ryml::parse_in_arena(yaml);
5462 CHECK(tree["map"].is_flow_ml1()); // etc
5463 CHECK(tree["map"]["seq"].is_flow_ml1()); // etc
5464 CHECK(tree["map"]["seq"][4].is_flow_sl()); // etc
5465 // emitted yaml is exactly equal to parsed yaml:
5466 CHECK(tostr(tree, emit_defaults) == yaml);
5467 // json looks similar (except for the double quotes):
5468 CHECK(tostr_json(tree, emit_defaults) ==
5469 "{" "\n"
5470 " \"map\": {" "\n"
5471 " \"seq\": [" "\n"
5472 " 0," "\n"
5473 " 1," "\n"
5474 " 2," "\n"
5475 " 3," "\n"
5476 " [40,41]" "\n"
5477 " ]" "\n"
5478 " }" "\n"
5479 "}" "\n"
5480 "");
5481 }
5482 // if you prefer to shorten the emitted yaml, you can set the
5483 // parser to disable flow multiline detection. It will then pick
5484 // singleline flow (FLOW_SL) for all flow containers:
5485 {
5487 .detect_flow_ml(false);
5488 const ryml::Tree tree = ryml::parse_in_arena(yaml, opts);
5489 CHECK(tree["map"].is_flow_sl()); // etc
5490 // notice how this is smaller now:
5491 CHECK(tostr(tree, emit_defaults) ==
5492 "{map: {seq: [0,1,2,3,[40,41]]}}");
5493 // and json as well
5494 CHECK(tostr_json(tree, emit_defaults) ==
5495 "{\"map\": {\"seq\": [0,1,2,3,[40,41]]}}");
5496 // you can also force spaces everywhere without adding
5497 // FLOW_SPC in individual containers:
5498 const ryml::EmitOptions with_spaces = ryml::EmitOptions{}
5499 .force_flow_spc(true);
5500 CHECK(tostr(tree, with_spaces) ==
5501 "{map: {seq: [0, 1, 2, 3, [40, 41]]}}");
5502 // and json as well
5503 CHECK(tostr_json(tree, with_spaces) ==
5504 "{\"map\": {\"seq\": [0, 1, 2, 3, [40, 41]]}}");
5505 }
5506 // or you can still have the default detection of flow_ml, but set
5507 // it to pick FLOW_MLN (multiline, n values per line), instead of
5508 // the default FLOW_ML1 (multiline, 1 values per line)
5509 {
5512 const ryml::Tree tree = ryml::parse_in_arena(yaml, opts);
5513 CHECK(tree["map"].is_flow_mln());
5514 CHECK(tree["map"]["seq"][4].is_flow_sl()); // [40,41] is FLOW_SL
5515 CHECK(tostr(tree, emit_defaults) ==
5516 "{" "\n"
5517 " map: {" "\n"
5518 " seq: [" "\n"
5519 " 0,1,2,3,[40,41]" "\n"
5520 " ]" "\n"
5521 " }" "\n"
5522 "}" "\n");
5523 CHECK(tostr_json(tree, emit_defaults) ==
5524 "{" "\n"
5525 " \"map\": {" "\n"
5526 " \"seq\": [" "\n"
5527 " 0,1,2,3,[40,41]" "\n"
5528 " ]" "\n"
5529 " }" "\n"
5530 "}" "\n");
5531 // now with spaces:
5532 const ryml::EmitOptions with_spaces = ryml::EmitOptions{}
5533 .force_flow_spc(true);
5534 CHECK(tostr(tree, with_spaces) ==
5535 "{" "\n"
5536 " map: {" "\n"
5537 " seq: [" "\n"
5538 " 0, 1, 2, 3, [40, 41]" "\n"
5539 " ]" "\n"
5540 " }" "\n"
5541 "}" "\n");
5542 CHECK(tostr_json(tree, with_spaces) ==
5543 "{" "\n"
5544 " \"map\": {" "\n"
5545 " \"seq\": [" "\n"
5546 " 0, 1, 2, 3, [40, 41]" "\n"
5547 " ]" "\n"
5548 " }" "\n"
5549 "}" "\n");
5550 }
5551 // you can also disable indentation of both FLOW_ML1 and FLOW_MLN
5552 // (see more details in @ref sample_style_flow_ml_indent())
5553 {
5554 const ryml::EmitOptions noindent = ryml::EmitOptions{}
5555 .indent_flow_ml(false);
5556 const ryml::Tree tree = ryml::parse_in_arena(yaml);
5557 CHECK(tree["map"].is_flow_ml1());
5558 CHECK(tree["map"]["seq"][4].is_flow_sl()); // [40,41] is FLOW_SL
5559 CHECK(tostr(tree, noindent) == ""
5560 "{" "\n"
5561 "map: {" "\n"
5562 "seq: [" "\n"
5563 "0," "\n"
5564 "1," "\n"
5565 "2," "\n"
5566 "3," "\n"
5567 "[40,41]" "\n"
5568 "]" "\n"
5569 "}" "\n"
5570 "}" "\n"
5571 "");
5572 CHECK(tostr_json(tree, noindent) == ""
5573 "{" "\n"
5574 "\"map\": {" "\n"
5575 "\"seq\": [" "\n"
5576 "0," "\n"
5577 "1," "\n"
5578 "2," "\n"
5579 "3," "\n"
5580 "[40,41]" "\n"
5581 "]" "\n"
5582 "}" "\n"
5583 "}" "\n"
5584 "");
5585 }
5586 // finally, you can control the number of columns in FLOW_MLN:
5587 {
5588 // let's pick a different example to make this clearer
5589 ryml::csubstr yaml2 = ""
5590 "[" "\n"
5591 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9," "\n"
5592 " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, " "\n"
5593 " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, " "\n"
5594 " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, " "\n"
5595 " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, " "\n"
5596 " 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, " "\n"
5597 " 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, " "\n"
5598 " 70, 71, 72, 73, 74, 75, 76, 77, 78, 79 " "\n"
5599 "]";
5600 // Let's force the parser to pick FLOW_MLN instead of
5601 // FLOW_ML1. We're doing that because wrapping is only done in
5602 // FLOW_MLN and -- as their names imply -- FLOW_SL is
5603 // single-line, and FLOW_ML1 is 1 value per line.
5606 const ryml::Tree tree = ryml::parse_in_arena(yaml2, opts);
5607 CHECK(tree.rootref().type().is_flow_mln());
5608 // default max columns is 80:
5609 CHECK(tostr(tree, emit_defaults) == ""
5610 "[\n"
5611 " 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,\n"
5612 " 30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,\n"
5613 " 56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79\n"
5614 "]\n"
5615 "");
5616 CHECK(tostr_json(tree, emit_defaults) == ""
5617 "[\n"
5618 " 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,\n"
5619 " 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,\n"
5620 " 55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79\n"
5621 "]\n"
5622 "");
5623 // let's try setting max columns to 40:
5624 const ryml::EmitOptions maxcols40 = ryml::EmitOptions{}
5625 .max_cols(40);
5626 CHECK(tostr(tree, maxcols40) == ""
5627 "[\n"
5628 " 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n"
5629 " 16,17,18,19,20,21,22,23,24,25,26,27,28,\n"
5630 " 29,30,31,32,33,34,35,36,37,38,39,40,41,\n"
5631 " 42,43,44,45,46,47,48,49,50,51,52,53,54,\n"
5632 " 55,56,57,58,59,60,61,62,63,64,65,66,67,\n"
5633 " 68,69,70,71,72,73,74,75,76,77,78,79\n"
5634 "]\n"
5635 "");
5636 CHECK(tostr_json(tree, maxcols40) == ""
5637 "[\n"
5638 " 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n"
5639 " 16,17,18,19,20,21,22,23,24,25,26,27,28,\n"
5640 " 29,30,31,32,33,34,35,36,37,38,39,40,41,\n"
5641 " 42,43,44,45,46,47,48,49,50,51,52,53,54,\n"
5642 " 55,56,57,58,59,60,61,62,63,64,65,66,67,\n"
5643 " 68,69,70,71,72,73,74,75,76,77,78,79\n"
5644 "]\n"
5645 "");
5646 // Note that you can globally force spaces everywhere through
5647 // the emit options:
5648 const ryml::EmitOptions with_spaces = ryml::EmitOptions{}
5649 .force_flow_spc(true);
5650 CHECK(tostr(tree, with_spaces) == ""
5651 "[\n"
5652 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5653 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5654 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5655 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79\n"
5656 "]\n"
5657 "");
5658 CHECK(tostr_json(tree, with_spaces) == ""
5659 "[\n"
5660 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5661 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5662 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5663 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79\n"
5664 "]\n"
5665 "");
5666 // and you can combine spaces with max columns:
5667 const ryml::EmitOptions maxcols40_spc = ryml::EmitOptions{}
5668 .max_cols(40)
5669 .force_flow_spc(true);
5670 CHECK(tostr(tree, maxcols40_spc) == ""
5671 "[\n"
5672 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n"
5673 " 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5674 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n"
5675 " 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5676 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n"
5677 " 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5678 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,\n"
5679 " 72, 73, 74, 75, 76, 77, 78, 79\n"
5680 "]\n"
5681 "");
5682 CHECK(tostr_json(tree, maxcols40_spc) == ""
5683 "[\n"
5684 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n"
5685 " 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5686 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n"
5687 " 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5688 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n"
5689 " 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5690 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,\n"
5691 " 72, 73, 74, 75, 76, 77, 78, 79\n"
5692 "]\n"
5693 "");
5694 // and you can combine spaces with max columns with no indentation:
5695 const ryml::EmitOptions maxcols40_spc_noindent = ryml::EmitOptions{}
5696 .max_cols(40)
5697 .force_flow_spc(true)
5698 .indent_flow_ml(false);
5699 CHECK(tostr(tree, maxcols40_spc_noindent) == ""
5700 "[\n"
5701 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n"
5702 "13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n"
5703 "23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n"
5704 "33, 34, 35, 36, 37, 38, 39, 40, 41, 42,\n"
5705 "43, 44, 45, 46, 47, 48, 49, 50, 51, 52,\n"
5706 "53, 54, 55, 56, 57, 58, 59, 60, 61, 62,\n"
5707 "63, 64, 65, 66, 67, 68, 69, 70, 71, 72,\n"
5708 "73, 74, 75, 76, 77, 78, 79\n"
5709 "]\n"
5710 "");
5711 CHECK(tostr_json(tree, maxcols40_spc_noindent) == ""
5712 "[\n"
5713 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n"
5714 "13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n"
5715 "23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n"
5716 "33, 34, 35, 36, 37, 38, 39, 40, 41, 42,\n"
5717 "43, 44, 45, 46, 47, 48, 49, 50, 51, 52,\n"
5718 "53, 54, 55, 56, 57, 58, 59, 60, 61, 62,\n"
5719 "63, 64, 65, 66, 67, 68, 69, 70, 71, 72,\n"
5720 "73, 74, 75, 76, 77, 78, 79\n"
5721 "]\n"
5722 "");
5723 }
5724 // Note that FLOW_SPC is /not/ detected by the parser, and that
5725 // depending on the parse options, either FLOW_ML1 or FLOW_MLN
5726 // will be used for /all/ multiline flow containers.
5727}
substr emitrs_json(Tree const &t, id_type id, EmitOptions const &opts, CharOwningContainer *cont, bool append=false)
(1) emit+resize: emit JSON to the given std::string/std::vector<char>-like container,...
bool indent_flow_ml() const noexcept
Indent the contents of FLOW_ML1 and FLOW_MLN containers.
EmitOptions & force_flow_spc(bool enabled) noexcept
Force everywhere a space after comma in flow mode, overriding the FLOW_SPC status of individual conta...
bool is_flow_mln() const noexcept
Options to give to the ParseEngine to control its behavior.
ParserOptions & detect_flow_ml(bool enabled) noexcept
enable/disable detection of flow multiline container style.
ParserOptions & flow_ml_style(NodeType style) noexcept
choose the default style of multiline flow containers, when a container is detected as flow multiline...
NodeType type() const RYML_NOEXCEPT
Forward to Tree::type().
Definition node.hpp:172

Referenced by main().

◆ sample_style_flow_ml_indent()

void sample_style_flow_ml_indent ( )

control indentation of FLOW_ML1 and FLOW_MLN containers

control the indentation of emitted flow multiline containers

Definition at line 5733 of file quickstart.cpp.

5734{
5735 // we will be using this helper throughout this function
5736 auto tostr = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5737 return ryml::emitrs_yaml<std::string>(n, opts);
5738 };
5739 ryml::csubstr yaml = "{map: {seq: [0, 1, 2, 3, [40, 41]]}}";
5740 ryml::Tree tree = ryml::parse_in_arena(yaml);
5741 ryml::EmitOptions defaults = {};
5743 CHECK(tostr(tree, defaults) == "{map: {seq: [0,1,2,3,[40,41]]}}");
5744 // let's now set the style to FLOW_ML1 (it was FLOW_SL)
5747 tree["map"]["seq"].set_container_style(ryml::FLOW_ML1);
5748 tree["map"]["seq"][4].set_container_style(ryml::FLOW_ML1);
5749 // by default FLOW_ML1 prints one value per line, indented:
5750 CHECK(tostr(tree, defaults) ==
5751 "{" "\n"
5752 " map: {" "\n"
5753 " seq: [" "\n"
5754 " 0," "\n"
5755 " 1," "\n"
5756 " 2," "\n"
5757 " 3," "\n"
5758 " [" "\n"
5759 " 40," "\n"
5760 " 41" "\n"
5761 " ]" "\n"
5762 " ]" "\n"
5763 " }" "\n"
5764 "}" "\n"
5765 "");
5766 // if we use the noindent options, then each value is put at the
5767 // beginning of the line
5768 CHECK(tostr(tree, noindent) ==
5769 "{" "\n"
5770 "map: {" "\n"
5771 "seq: [" "\n"
5772 "0," "\n"
5773 "1," "\n"
5774 "2," "\n"
5775 "3," "\n"
5776 "[" "\n"
5777 "40," "\n"
5778 "41" "\n"
5779 "]" "\n"
5780 "]" "\n"
5781 "}" "\n"
5782 "}" "\n"
5783 "");
5784 // Note that the noindent option will safely respect any prior
5785 // indent level from enclosing block containers! For example:
5787 CHECK(tostr(tree, noindent) == ""// notice it is indented at the map level
5788 "map: {" "\n"
5789 " seq: [" "\n"
5790 " 0," "\n"
5791 " 1," "\n"
5792 " 2," "\n"
5793 " 3," "\n"
5794 " [" "\n"
5795 " 40," "\n"
5796 " 41" "\n"
5797 " ]" "\n"
5798 " ]" "\n"
5799 " }" "\n"
5800 "");
5801 // Let's set it one BLOCK level further:
5802 tree["map"].set_container_style(ryml::BLOCK);
5803 CHECK(tostr(tree, noindent) == // notice it is indented one more level
5804 "map:" "\n"
5805 " seq: [" "\n"
5806 " 0," "\n"
5807 " 1," "\n"
5808 " 2," "\n"
5809 " 3," "\n"
5810 " [" "\n"
5811 " 40," "\n"
5812 " 41" "\n"
5813 " ]" "\n"
5814 " ]" "\n"
5815 "");
5816}
void set_container_style(id_type node, type_bits style)
Definition tree.hpp:658

Referenced by main().