rapidyaml 0.15.2
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 5017 of file quickstart.cpp.

5018{
5019 // we will be using these helpers throughout this function
5020 auto tostr = [](ryml::ConstNodeRef n) {
5022 };
5023 auto tostr_opts = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5024 return ryml::emitrs_yaml<std::string>(n, opts);
5025 };
5026 // let's parse this yaml:
5027 ryml::csubstr yaml = ""
5028 "block map:" "\n"
5029 " block key: block val" "\n"
5030 "block seq:" "\n"
5031 " - block val 1" "\n"
5032 " - block val 2" "\n"
5033 " - 'quoted'" "\n"
5034 "flow map, singleline: {flow key: flow val}" "\n"
5035 "flow seq, singleline: [flow val,flow val]" "\n"
5036 "flow map, multiline: {" "\n"
5037 " flow key: flow val" "\n"
5038 " }" "\n"
5039 "flow seq, multiline: [" "\n"
5040 " flow val," "\n"
5041 " flow val" "\n"
5042 " ]" "\n"
5043 "";
5044 ryml::Tree tree = ryml::parse_in_arena(yaml);
5045 // while parsing, ryml marks parsed nodes with their original style:
5046 CHECK(tree.rootref().is_block());
5047 CHECK(tree["block map"].is_key_plain());
5048 CHECK(tree["block seq"].is_key_plain());
5049 CHECK(tree["flow map, singleline"].is_key_plain());
5050 CHECK(tree["flow seq, singleline"].is_key_plain());
5051 CHECK(tree["flow map, multiline"].is_key_plain());
5052 CHECK(tree["flow seq, multiline"].is_key_plain());
5053 CHECK(tree["block map"].is_block());
5054 CHECK(tree["block seq"].is_block());
5055 // flow is either singleline (FLOW_SL) or multiline (FLOW_ML1)
5056 CHECK(tree["flow map, singleline"].is_flow_sl());
5057 CHECK(tree["flow seq, singleline"].is_flow_sl());
5058 CHECK(tree["flow map, multiline"].is_flow_ml1());
5059 CHECK(tree["flow seq, multiline"].is_flow_ml1());
5060 // is_flow() is equivalent to (is_flow_sl() || is_flow_ml1() || is_flow_mln())
5061 CHECK(tree["flow map, singleline"].is_flow());
5062 CHECK(tree["flow seq, singleline"].is_flow());
5063 CHECK(tree["flow map, multiline"].is_flow());
5064 CHECK(tree["flow seq, multiline"].is_flow());
5065 //
5066 // since the tree nodes are marked with their original parsed
5067 // style, emitting the parsed tree will preserve the original
5068 // style (minus whitespace):
5069 //
5070 CHECK(tostr(tree) == yaml); // same as before!
5071 //
5072 // you can set/modify the style programatically!
5073 //
5074 // here are more examples.
5075 //
5076 {
5077 ryml::NodeRef n = tree["block map"]; // Let's look at one node
5078 // It looks like this originally:
5079 CHECK(tostr(n) ==
5080 "block map:\n"
5081 " block key: block val\n"
5082 "");
5083 // let's modify its style:
5084 n.set_key_style(ryml::KEY_SQUO); // scalar style: to single-quoted scalar
5085 n.set_container_style(ryml::FLOW_SL); // container style: to flow singleline
5086 // now it looks like this:
5087 CHECK(tostr(n) ==
5088 "'block map': {block key: block val}\n"
5089 "");
5090 }
5091 // next example
5092 {
5093 ryml::NodeRef n = tree["block seq"];
5094 CHECK(tostr(n) == ""
5095 "block seq:\n"
5096 " - block val 1\n"
5097 " - block val 2\n"
5098 " - 'quoted'\n"
5099 "");
5100 n.set_key_style(ryml::KEY_DQUO); // scalar style: to double-quoted scalar
5101 n[2].set_val_style(ryml::VAL_PLAIN); // scalar style: to plain
5102 n.set_container_style(ryml::FLOW_MLN); // container style: to flow multiline, N values per line
5103 CHECK(tostr(n) == ""
5104 "\"block seq\": [\n"
5105 " block val 1,block val 2,quoted\n"
5106 " ]\n");
5107 n.set_container_style(ryml::FLOW_MLN|ryml::FLOW_SPC); // force space after comma
5108 CHECK(tostr(n) == ""
5109 "\"block seq\": [\n"
5110 " block val 1, block val 2, quoted\n"
5111 " ]\n");
5112 auto maxcols20 = ryml::EmitOptions{}.max_cols(20); // set the max number of cols for FLOW_MLN
5113 CHECK(tostr_opts(n, maxcols20) == ""
5114 "\"block seq\": [\n"
5115 " block val 1, block val 2,\n"
5116 " quoted\n"
5117 " ]\n");
5118 n.set_container_style(ryml::FLOW_MLN); // no spaces now
5119 CHECK(tostr_opts(n, maxcols20) == ""
5120 "\"block seq\": [\n"
5121 " block val 1,block val 2,\n"
5122 " quoted\n"
5123 " ]\n");
5124 n.set_container_style(ryml::FLOW_SL); // to flow singleline
5125 CHECK(tostr(n) == ""
5126 "\"block seq\": [block val 1,block val 2,quoted]\n");
5127 n.set_container_style(ryml::FLOW_SL|ryml::FLOW_SPC); // now with space after comma
5128 CHECK(tostr(n) == ""
5129 "\"block seq\": [block val 1, block val 2, quoted]\n");
5130 n.set_container_style(ryml::FLOW_ML1); // to flow multiline, 1 value per line
5131 CHECK(tostr(n) == ""
5132 "\"block seq\": [\n"
5133 " block val 1,\n"
5134 " block val 2,\n"
5135 " quoted\n"
5136 " ]\n");
5137 /// @see See more details about formatting flow containers in
5138 /// @ref sample_style_flow_formatting() (below).
5139 }
5140 // next example
5141 {
5142 ryml::NodeRef n = tree["flow map, singleline"];
5143 CHECK(tostr(n) == "flow map, singleline: {flow key: flow val}\n");
5145 n["flow key"].set_val_style(ryml::VAL_LITERAL);
5146 CHECK(tostr(n) == ""
5147 "flow map, singleline:\n"
5148 " flow key: |-\n"
5149 " flow val\n"
5150 "");
5151 }
5152 // next example
5153 {
5154 ryml::NodeRef n = tree["flow map, multiline"];
5155 CHECK(tostr(n) == ""
5156 "flow map, multiline: {\n"
5157 " flow key: flow val\n"
5158 " }\n"
5159 "");
5161 CHECK(tostr(n) == ""
5162 "flow map, multiline:\n"
5163 " flow key: flow val\n"
5164 "");
5165 }
5166 // next example
5167 {
5168 ryml::NodeRef n = tree["flow seq, singleline"];
5169 CHECK(tostr(n) == "flow seq, singleline: [flow val,flow val]\n");
5174 CHECK(tostr(n) == ""
5175 "? >-\n"
5176 " flow seq, singleline\n"
5177 ":\n"
5178 " - 'flow val'\n"
5179 " - \"flow val\"\n"
5180 "");
5181 }
5182 // next example
5183 {
5184 ryml::NodeRef n = tree["flow seq, multiline"];
5185 CHECK(tostr(n) == ""
5186 "flow seq, multiline: [\n"
5187 " flow val,\n"
5188 " flow val\n"
5189 " ]\n"
5190 "");
5192 CHECK(tostr(n) == "flow seq, multiline: [flow val,flow val]\n");
5193 }
5194 // note the full tree now:
5195 CHECK(tostr(tree) != yaml);
5196 CHECK(tostr(tree) ==
5197 "'block map': {block key: block val}" "\n"
5198 "\"block seq\": [" "\n"
5199 " block val 1," "\n"
5200 " block val 2," "\n"
5201 " quoted" "\n"
5202 " ]" "\n"
5203 "flow map, singleline:" "\n"
5204 " flow key: |-" "\n"
5205 " flow val" "\n"
5206 "? >-" "\n"
5207 " flow seq, singleline" "\n"
5208 ":" "\n"
5209 " - 'flow val'" "\n"
5210 " - \"flow val\"" "\n"
5211 "flow map, multiline:" "\n"
5212 " flow key: flow val" "\n"
5213 "flow seq, multiline: [flow val,flow val]" "\n"
5214 "");
5215 // you can clear the style of single nodes:
5216 tree["block map"].clear_style();
5217 tree["block seq"].clear_style();
5218 CHECK(tostr(tree) ==
5219 "block map:" "\n"
5220 " block key: block val" "\n"
5221 "block seq:" "\n"
5222 " - block val 1" "\n"
5223 " - block val 2" "\n"
5224 " - quoted" "\n"
5225 "flow map, singleline:" "\n"
5226 " flow key: |-" "\n"
5227 " flow val" "\n"
5228 "? >-" "\n"
5229 " flow seq, singleline" "\n"
5230 ":" "\n"
5231 " - 'flow val'" "\n"
5232 " - \"flow val\"" "\n"
5233 "flow map, multiline:" "\n"
5234 " flow key: flow val" "\n"
5235 "flow seq, multiline: [flow val,flow val]" "\n"
5236 "");
5237 // you can clear the style recursively:
5238 tree.rootref().clear_style(/*recurse*/true);
5239 // when emitting nodes which have no style set, ryml will default
5240 // to block format for containers, and call
5241 // ryml::scalar_style_choose() to pick the style for each scalar
5242 // (at the cost of a scan over each scalar). Note that ryml picks
5243 // single-quoted for scalars containing commas:
5244 CHECK(tostr(tree) ==
5245 "block map:" "\n"
5246 " block key: block val" "\n"
5247 "block seq:" "\n"
5248 " - block val 1" "\n"
5249 " - block val 2" "\n"
5250 " - quoted" "\n"
5251 "flow map, singleline:" "\n"
5252 " flow key: flow val" "\n"
5253 "flow seq, singleline:" "\n"
5254 " - flow val" "\n"
5255 " - flow val" "\n"
5256 "flow map, multiline:" "\n"
5257 " flow key: flow val" "\n"
5258 "flow seq, multiline:" "\n"
5259 " - flow val" "\n"
5260 " - flow val" "\n"
5261 "");
5262 // you can set the style based on type conditions:
5263 //
5264 // eg, set a single key to single-quoted
5265 tree["block map"].set_style_conditionally(/*type_mask*/ryml::KEY,
5266 /*remflags*/ryml::KEY_STYLE,
5267 /*addflags*/ryml::KEY_SQUO,
5268 /*recurse*/false);
5269 CHECK(tostr(tree) ==
5270 "'block map':" "\n"
5271 " block key: block val" "\n"
5272 "block seq:" "\n"
5273 " - block val 1" "\n"
5274 " - block val 2" "\n"
5275 " - quoted" "\n"
5276 "flow map, singleline:" "\n"
5277 " flow key: flow val" "\n"
5278 "flow seq, singleline:" "\n"
5279 " - flow val" "\n"
5280 " - flow val" "\n"
5281 "flow map, multiline:" "\n"
5282 " flow key: flow val" "\n"
5283 "flow seq, multiline:" "\n"
5284 " - flow val" "\n"
5285 " - flow val" "\n"
5286 "");
5287 // change all keys to single-quoted:
5288 tree.rootref().set_style_conditionally(/*type_mask*/ryml::KEY,
5289 /*remflags*/ryml::KEY_STYLE,
5290 /*addflags*/ryml::KEY_SQUO,
5291 /*recurse*/true);
5292 // change all vals to double-quoted
5293 tree.rootref().set_style_conditionally(/*type_mask*/ryml::VAL,
5294 /*remflags*/ryml::VAL_STYLE,
5295 /*addflags*/ryml::VAL_DQUO,
5296 /*recurse*/true);
5297 // change all seqs to flow
5298 tree.rootref().set_style_conditionally(/*type_mask*/ryml::SEQ,
5299 /*remflags*/ryml::CONTAINER_STYLE,
5300 /*addflags*/ryml::FLOW_SL,
5301 /*recurse*/true);
5302 // change all maps to flow
5303 tree.rootref().set_style_conditionally(/*type_mask*/ryml::MAP,
5304 /*remflags*/ryml::CONTAINER_STYLE,
5305 /*addflags*/ryml::BLOCK,
5306 /*recurse*/true);
5307 // done!
5308 CHECK(tostr(tree) == ""
5309 "'block map':" "\n"
5310 " 'block key': \"block val\"" "\n"
5311 "'block seq': [\"block val 1\",\"block val 2\",\"quoted\"]" "\n"
5312 "'flow map, singleline':" "\n"
5313 " 'flow key': \"flow val\"" "\n"
5314 "'flow seq, singleline': [\"flow val\",\"flow val\"]" "\n"
5315 "'flow map, multiline':" "\n"
5316 " 'flow key': \"flow val\"" "\n"
5317 "'flow seq, multiline': [\"flow val\",\"flow val\"]" "\n"
5318 "");
5319 // you can also set a conditional style in a single node (or its branch if recurse is true):
5320 tree["flow seq, singleline"].set_style_conditionally(/*type_mask*/ryml::SEQ,
5321 /*remflags*/ryml::CONTAINER_STYLE,
5322 /*addflags*/ryml::BLOCK,
5323 /*recurse*/false);
5324 CHECK(tostr(tree) == ""
5325 "'block map':" "\n"
5326 " 'block key': \"block val\"" "\n"
5327 "'block seq': [\"block val 1\",\"block val 2\",\"quoted\"]" "\n"
5328 "'flow map, singleline':" "\n"
5329 " 'flow key': \"flow val\"" "\n"
5330 "'flow seq, singleline':" "\n"
5331 " - \"flow val\"" "\n"
5332 " - \"flow val\"" "\n"
5333 "'flow map, multiline':" "\n"
5334 " 'flow key': \"flow val\"" "\n"
5335 "'flow seq, multiline': [\"flow val\",\"flow val\"]" "\n"
5336 "");
5337 /// see also:
5338 /// - @ref ryml::scalar_style_choose_block()
5339 /// - @ref ryml::scalar_style_choose_flow()
5340 /// - @ref ryml::scalar_style_choose_json()
5341 /// - @ref ryml::scalar_style_query_squo()
5342 /// - @ref ryml::scalar_style_query_plain_flow()
5343 /// - @ref ryml::scalar_style_query_plain_block()
5344}
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 5350 of file quickstart.cpp.

5351{
5352 // we will be using this helper throughout this function
5353 auto tostr = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5354 return ryml::emitrs_yaml<std::string>(n, opts);
5355 };
5356 auto tostr_json = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5357 return ryml::emitrs_json<std::string>(n, opts);
5358 };
5359 const ryml::EmitOptions emit_defaults = ryml::EmitOptions{};
5360 // let's parse this, which is in FLOW_ML1 (flow multiline, 1 value per line):
5361 ryml::csubstr yaml = ""
5362 "{" "\n"
5363 " map: {" "\n"
5364 " seq: [" "\n"
5365 " 0," "\n"
5366 " 1," "\n"
5367 " 2," "\n"
5368 " 3," "\n"
5369 " [40,41]" "\n"
5370 " ]" "\n"
5371 " }" "\n"
5372 "}" "\n"
5373 "";
5374 // note that the parser defaults to detecting multiline flow
5375 // (FLOW_ML1) containers:
5376 {
5377 const ryml::Tree tree = ryml::parse_in_arena(yaml);
5378 CHECK(tree["map"].is_flow_ml1()); // etc
5379 CHECK(tree["map"]["seq"].is_flow_ml1()); // etc
5380 CHECK(tree["map"]["seq"][4].is_flow_sl()); // etc
5381 // emitted yaml is exactly equal to parsed yaml:
5382 CHECK(tostr(tree, emit_defaults) == yaml);
5383 // json looks similar (except for the double quotes):
5384 CHECK(tostr_json(tree, emit_defaults) ==
5385 "{" "\n"
5386 " \"map\": {" "\n"
5387 " \"seq\": [" "\n"
5388 " 0," "\n"
5389 " 1," "\n"
5390 " 2," "\n"
5391 " 3," "\n"
5392 " [40,41]" "\n"
5393 " ]" "\n"
5394 " }" "\n"
5395 "}" "\n"
5396 "");
5397 }
5398 // if you prefer to shorten the emitted yaml, you can set the
5399 // parser to disable flow multiline detection. It will then pick
5400 // singleline flow (FLOW_SL) for all flow containers:
5401 {
5403 .detect_flow_ml(false);
5404 const ryml::Tree tree = ryml::parse_in_arena(yaml, opts);
5405 CHECK(tree["map"].is_flow_sl()); // etc
5406 // notice how this is smaller now:
5407 CHECK(tostr(tree, emit_defaults) ==
5408 "{map: {seq: [0,1,2,3,[40,41]]}}");
5409 // and json as well
5410 CHECK(tostr_json(tree, emit_defaults) ==
5411 "{\"map\": {\"seq\": [0,1,2,3,[40,41]]}}");
5412 // you can also force spaces everywhere without adding
5413 // FLOW_SPC in individual containers:
5414 const ryml::EmitOptions with_spaces = ryml::EmitOptions{}
5415 .force_flow_spc(true);
5416 CHECK(tostr(tree, with_spaces) ==
5417 "{map: {seq: [0, 1, 2, 3, [40, 41]]}}");
5418 // and json as well
5419 CHECK(tostr_json(tree, with_spaces) ==
5420 "{\"map\": {\"seq\": [0, 1, 2, 3, [40, 41]]}}");
5421 }
5422 // or you can still have the default detection of flow_ml, but set
5423 // it to pick FLOW_MLN (multiline, n values per line), instead of
5424 // the default FLOW_ML1 (multiline, 1 values per line)
5425 {
5428 const ryml::Tree tree = ryml::parse_in_arena(yaml, opts);
5429 CHECK(tree["map"].is_flow_mln());
5430 CHECK(tree["map"]["seq"][4].is_flow_sl()); // [40,41] is FLOW_SL
5431 CHECK(tostr(tree, emit_defaults) ==
5432 "{" "\n"
5433 " map: {" "\n"
5434 " seq: [" "\n"
5435 " 0,1,2,3,[40,41]" "\n"
5436 " ]" "\n"
5437 " }" "\n"
5438 "}" "\n");
5439 CHECK(tostr_json(tree, emit_defaults) ==
5440 "{" "\n"
5441 " \"map\": {" "\n"
5442 " \"seq\": [" "\n"
5443 " 0,1,2,3,[40,41]" "\n"
5444 " ]" "\n"
5445 " }" "\n"
5446 "}" "\n");
5447 // now with spaces:
5448 const ryml::EmitOptions with_spaces = ryml::EmitOptions{}
5449 .force_flow_spc(true);
5450 CHECK(tostr(tree, with_spaces) ==
5451 "{" "\n"
5452 " map: {" "\n"
5453 " seq: [" "\n"
5454 " 0, 1, 2, 3, [40, 41]" "\n"
5455 " ]" "\n"
5456 " }" "\n"
5457 "}" "\n");
5458 CHECK(tostr_json(tree, with_spaces) ==
5459 "{" "\n"
5460 " \"map\": {" "\n"
5461 " \"seq\": [" "\n"
5462 " 0, 1, 2, 3, [40, 41]" "\n"
5463 " ]" "\n"
5464 " }" "\n"
5465 "}" "\n");
5466 }
5467 // you can also disable indentation of both FLOW_ML1 and FLOW_MLN
5468 // (see more details in @ref sample_style_flow_ml_indent())
5469 {
5470 const ryml::EmitOptions noindent = ryml::EmitOptions{}
5471 .indent_flow_ml(false);
5472 const ryml::Tree tree = ryml::parse_in_arena(yaml);
5473 CHECK(tree["map"].is_flow_ml1());
5474 CHECK(tree["map"]["seq"][4].is_flow_sl()); // [40,41] is FLOW_SL
5475 CHECK(tostr(tree, noindent) == ""
5476 "{" "\n"
5477 "map: {" "\n"
5478 "seq: [" "\n"
5479 "0," "\n"
5480 "1," "\n"
5481 "2," "\n"
5482 "3," "\n"
5483 "[40,41]" "\n"
5484 "]" "\n"
5485 "}" "\n"
5486 "}" "\n"
5487 "");
5488 CHECK(tostr_json(tree, noindent) == ""
5489 "{" "\n"
5490 "\"map\": {" "\n"
5491 "\"seq\": [" "\n"
5492 "0," "\n"
5493 "1," "\n"
5494 "2," "\n"
5495 "3," "\n"
5496 "[40,41]" "\n"
5497 "]" "\n"
5498 "}" "\n"
5499 "}" "\n"
5500 "");
5501 }
5502 // finally, you can control the number of columns in FLOW_MLN:
5503 {
5504 // let's pick a different example to make this clearer
5505 ryml::csubstr yaml2 = ""
5506 "[" "\n"
5507 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9," "\n"
5508 " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, " "\n"
5509 " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, " "\n"
5510 " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, " "\n"
5511 " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, " "\n"
5512 " 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, " "\n"
5513 " 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, " "\n"
5514 " 70, 71, 72, 73, 74, 75, 76, 77, 78, 79 " "\n"
5515 "]";
5516 // Let's force the parser to pick FLOW_MLN instead of
5517 // FLOW_ML1. We're doing that because wrapping is only done in
5518 // FLOW_MLN and -- as their names imply -- FLOW_SL is
5519 // single-line, and FLOW_ML1 is 1 value per line.
5522 const ryml::Tree tree = ryml::parse_in_arena(yaml2, opts);
5523 CHECK(tree.rootref().type().is_flow_mln());
5524 // default max columns is 80:
5525 CHECK(tostr(tree, emit_defaults) == ""
5526 "[\n"
5527 " 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"
5528 " 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"
5529 " 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"
5530 "]\n"
5531 "");
5532 CHECK(tostr_json(tree, emit_defaults) == ""
5533 "[\n"
5534 " 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"
5535 " 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"
5536 " 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"
5537 "]\n"
5538 "");
5539 // let's try setting max columns to 40:
5540 const ryml::EmitOptions maxcols40 = ryml::EmitOptions{}
5541 .max_cols(40);
5542 CHECK(tostr(tree, maxcols40) == ""
5543 "[\n"
5544 " 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n"
5545 " 16,17,18,19,20,21,22,23,24,25,26,27,28,\n"
5546 " 29,30,31,32,33,34,35,36,37,38,39,40,41,\n"
5547 " 42,43,44,45,46,47,48,49,50,51,52,53,54,\n"
5548 " 55,56,57,58,59,60,61,62,63,64,65,66,67,\n"
5549 " 68,69,70,71,72,73,74,75,76,77,78,79\n"
5550 "]\n"
5551 "");
5552 CHECK(tostr_json(tree, maxcols40) == ""
5553 "[\n"
5554 " 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n"
5555 " 16,17,18,19,20,21,22,23,24,25,26,27,28,\n"
5556 " 29,30,31,32,33,34,35,36,37,38,39,40,41,\n"
5557 " 42,43,44,45,46,47,48,49,50,51,52,53,54,\n"
5558 " 55,56,57,58,59,60,61,62,63,64,65,66,67,\n"
5559 " 68,69,70,71,72,73,74,75,76,77,78,79\n"
5560 "]\n"
5561 "");
5562 // Note that you can globally force spaces everywhere through
5563 // the emit options:
5564 const ryml::EmitOptions with_spaces = ryml::EmitOptions{}
5565 .force_flow_spc(true);
5566 CHECK(tostr(tree, with_spaces) == ""
5567 "[\n"
5568 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5569 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5570 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5571 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79\n"
5572 "]\n"
5573 "");
5574 CHECK(tostr_json(tree, with_spaces) == ""
5575 "[\n"
5576 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5577 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5578 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5579 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79\n"
5580 "]\n"
5581 "");
5582 // and you can combine spaces with max columns:
5583 const ryml::EmitOptions maxcols40_spc = ryml::EmitOptions{}
5584 .max_cols(40)
5585 .force_flow_spc(true);
5586 CHECK(tostr(tree, maxcols40_spc) == ""
5587 "[\n"
5588 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n"
5589 " 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5590 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n"
5591 " 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5592 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n"
5593 " 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5594 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,\n"
5595 " 72, 73, 74, 75, 76, 77, 78, 79\n"
5596 "]\n"
5597 "");
5598 CHECK(tostr_json(tree, maxcols40_spc) == ""
5599 "[\n"
5600 " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n"
5601 " 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n"
5602 " 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n"
5603 " 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n"
5604 " 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\n"
5605 " 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n"
5606 " 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,\n"
5607 " 72, 73, 74, 75, 76, 77, 78, 79\n"
5608 "]\n"
5609 "");
5610 // and you can combine spaces with max columns with no indentation:
5611 const ryml::EmitOptions maxcols40_spc_noindent = ryml::EmitOptions{}
5612 .max_cols(40)
5613 .force_flow_spc(true)
5614 .indent_flow_ml(false);
5615 CHECK(tostr(tree, maxcols40_spc_noindent) == ""
5616 "[\n"
5617 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n"
5618 "13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n"
5619 "23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n"
5620 "33, 34, 35, 36, 37, 38, 39, 40, 41, 42,\n"
5621 "43, 44, 45, 46, 47, 48, 49, 50, 51, 52,\n"
5622 "53, 54, 55, 56, 57, 58, 59, 60, 61, 62,\n"
5623 "63, 64, 65, 66, 67, 68, 69, 70, 71, 72,\n"
5624 "73, 74, 75, 76, 77, 78, 79\n"
5625 "]\n"
5626 "");
5627 CHECK(tostr_json(tree, maxcols40_spc_noindent) == ""
5628 "[\n"
5629 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n"
5630 "13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n"
5631 "23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n"
5632 "33, 34, 35, 36, 37, 38, 39, 40, 41, 42,\n"
5633 "43, 44, 45, 46, 47, 48, 49, 50, 51, 52,\n"
5634 "53, 54, 55, 56, 57, 58, 59, 60, 61, 62,\n"
5635 "63, 64, 65, 66, 67, 68, 69, 70, 71, 72,\n"
5636 "73, 74, 75, 76, 77, 78, 79\n"
5637 "]\n"
5638 "");
5639 }
5640 // Note that FLOW_SPC is /not/ detected by the parser, and that
5641 // depending on the parse options, either FLOW_ML1 or FLOW_MLN
5642 // will be used for /all/ multiline flow containers.
5643}
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 5649 of file quickstart.cpp.

5650{
5651 // we will be using this helper throughout this function
5652 auto tostr = [](ryml::ConstNodeRef n, ryml::EmitOptions opts) {
5653 return ryml::emitrs_yaml<std::string>(n, opts);
5654 };
5655 ryml::csubstr yaml = "{map: {seq: [0, 1, 2, 3, [40, 41]]}}";
5656 ryml::Tree tree = ryml::parse_in_arena(yaml);
5657 ryml::EmitOptions defaults = {};
5659 CHECK(tostr(tree, defaults) == "{map: {seq: [0,1,2,3,[40,41]]}}");
5660 // let's now set the style to FLOW_ML1 (it was FLOW_SL)
5663 tree["map"]["seq"].set_container_style(ryml::FLOW_ML1);
5664 tree["map"]["seq"][4].set_container_style(ryml::FLOW_ML1);
5665 // by default FLOW_ML1 prints one value per line, indented:
5666 CHECK(tostr(tree, defaults) ==
5667 "{" "\n"
5668 " map: {" "\n"
5669 " seq: [" "\n"
5670 " 0," "\n"
5671 " 1," "\n"
5672 " 2," "\n"
5673 " 3," "\n"
5674 " [" "\n"
5675 " 40," "\n"
5676 " 41" "\n"
5677 " ]" "\n"
5678 " ]" "\n"
5679 " }" "\n"
5680 "}" "\n"
5681 "");
5682 // if we use the noindent options, then each value is put at the
5683 // beginning of the line
5684 CHECK(tostr(tree, noindent) ==
5685 "{" "\n"
5686 "map: {" "\n"
5687 "seq: [" "\n"
5688 "0," "\n"
5689 "1," "\n"
5690 "2," "\n"
5691 "3," "\n"
5692 "[" "\n"
5693 "40," "\n"
5694 "41" "\n"
5695 "]" "\n"
5696 "]" "\n"
5697 "}" "\n"
5698 "}" "\n"
5699 "");
5700 // Note that the noindent option will safely respect any prior
5701 // indent level from enclosing block containers! For example:
5703 CHECK(tostr(tree, noindent) == ""// notice it is indented at the map level
5704 "map: {" "\n"
5705 " seq: [" "\n"
5706 " 0," "\n"
5707 " 1," "\n"
5708 " 2," "\n"
5709 " 3," "\n"
5710 " [" "\n"
5711 " 40," "\n"
5712 " 41" "\n"
5713 " ]" "\n"
5714 " ]" "\n"
5715 " }" "\n"
5716 "");
5717 // Let's set it one BLOCK level further:
5718 tree["map"].set_container_style(ryml::BLOCK);
5719 CHECK(tostr(tree, noindent) == // notice it is indented one more level
5720 "map:" "\n"
5721 " seq: [" "\n"
5722 " 0," "\n"
5723 " 1," "\n"
5724 " 2," "\n"
5725 " 3," "\n"
5726 " [" "\n"
5727 " 40," "\n"
5728 " 41" "\n"
5729 " ]" "\n"
5730 " ]" "\n"
5731 "");
5732}
void set_container_style(id_type node, type_bits style)
Definition tree.hpp:658

Referenced by main().