rapidyaml  0.16.0
parseandemitYAML,anddoitfast
YAML styles

Functions

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

Detailed Description

Function Documentation

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.

Referenced by main().

5102 {
5103  // we will be using these helpers throughout this function
5104  auto tostr = [](ryml::ConstNodeRef n) {
5105  return ryml::emitrs_yaml<std::string>(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 }
mark val scalar as plain scalar (unquoted, even when multiline)
Definition: node_type.hpp:156
mark key scalar as double quoted "
Definition: node_type.hpp:153
mark val scalar as single quoted '
Definition: node_type.hpp:152
mask of CONTAINER_STYLE_FLOW|CONTAINER_STYLE_BLOCK : all container style flags
Definition: node_type.hpp:182
mark val scalar as double quoted "
Definition: node_type.hpp:154
mark container with multi-line flow style, n elements per line, < wrapped (as set by EmitOptions::max...
Definition: node_type.hpp:90
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
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
A reference to a node in an existing yaml tree, offering a more convenient API than the index-based A...
Definition: node.hpp:1062
mark key scalar as multiline, block folded >
Definition: node_type.hpp:149
void clear_style(id_type node, bool recurse=false)
Definition: tree.cpp:1404
bool is_block() const RYML_NOEXCEPT
Forward to Tree::is_block().
Definition: node.hpp:242
#define CHECK(predicate)
a testing assertion, used only in this quickstart
Definition: quickstart.cpp:310
mark container with block style < - seqs as <
Definition: node_type.hpp:136
Holds a pointer to an existing tree, and a node id.
Definition: node.hpp:736
the scalar to the left of : in a map's member
Definition: node_type.hpp:33
mask of KEYQUO|KEY_PLAIN : all the key scalar styles for key (not container styles!) ...
Definition: node_type.hpp:176
EmitOptions & max_cols(id_type cols) noexcept
Set max columns for the emitted YAML in FLOW_MLN mode.
void set_key_style(type_bits style)
Definition: node.hpp:1268
mark container with spaces after comma when in flow mode. < Applies to both FLOW_SL and FLOW_MLN (but...
Definition: node_type.hpp:132
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
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
Definition: tree.cpp:56
A lightweight object containing options to be used when emitting.
void set_container_style(type_bits style)
Definition: node.hpp:1267
mark val scalar as multiline, block literal |
Definition: node_type.hpp:148
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition: node_type.hpp:35
mark key scalar as single quoted '
Definition: node_type.hpp:151
mark container with multi-line flow style, 1 element per line < - seqs as <
Definition: node_type.hpp:75
mask of VALQUO|VAL_PLAIN : all the val scalar styles for val (not container styles!) ...
Definition: node_type.hpp:177
void set_val_style(type_bits style)
Definition: node.hpp:1269
a seq: a parent of VAL/SEQ/MAP nodes
Definition: node_type.hpp:36
mark container with single-line flow style < - seqs as <
Definition: node_type.hpp:56
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 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.

Referenced by main().

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 }
bool indent_flow_ml() const noexcept
Indent the contents of FLOW_ML1 and FLOW_MLN containers.
ParserOptions & detect_flow_ml(bool enabled) noexcept
enable/disable detection of flow multiline container style.
bool is_flow_mln() const noexcept
Definition: node_type.hpp:325
mark container with multi-line flow style, n elements per line, < wrapped (as set by EmitOptions::max...
Definition: node_type.hpp:90
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
Options to give to the ParseEngine to control its behavior.
EmitOptions & force_flow_spc(bool enabled) noexcept
Force everywhere a space after comma in flow mode, overriding the FLOW_SPC status of individual conta...
#define CHECK(predicate)
a testing assertion, used only in this quickstart
Definition: quickstart.cpp:310
Holds a pointer to an existing tree, and a node id.
Definition: node.hpp:736
EmitOptions & max_cols(id_type cols) noexcept
Set max columns for the emitted YAML in FLOW_MLN mode.
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
Definition: tree.cpp:56
A lightweight object containing options to be used when emitting.
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
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.

Referenced by main().

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)
5746  tree["map"].set_container_style(ryml::FLOW_ML1);
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 }
bool indent_flow_ml() const noexcept
Indent the contents of FLOW_ML1 and FLOW_MLN containers.
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
Definition: quickstart.cpp:310
mark container with block style < - seqs as <
Definition: node_type.hpp:136
Holds a pointer to an existing tree, and a node id.
Definition: node.hpp:736
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
Definition: tree.cpp:56
A lightweight object containing options to be used when emitting.
void set_container_style(type_bits style)
Definition: node.hpp:1267
mark container with multi-line flow style, 1 element per line < - seqs as <
Definition: node_type.hpp:75
void set_container_style(id_type node, type_bits style)
Definition: tree.hpp:658