www.mooseframework.org
JsonInputFileFormatter.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "JsonInputFileFormatter.h"
11 #include "MooseUtils.h"
12 
13 #include <vector>
14 
16 
17 std::string
18 JsonInputFileFormatter::toString(const moosecontrib::Json::Value & root)
19 {
20  _stream.clear();
21  _stream.str("");
22  for (auto && name : root["blocks"].getMemberNames())
23  addBlock(name, root["blocks"][name], true);
24  return _stream.str();
25 }
26 
27 void
28 JsonInputFileFormatter::addLine(const std::string & line,
29  size_t max_line_len,
30  const std::string & comment)
31 {
32  if (line.empty() && comment.empty())
33  {
34  _stream << "\n";
35  return;
36  }
37 
38  std::string indent(_level * _spaces, ' ');
39  auto doc = MooseUtils::trim(comment);
40  if (doc.empty()) // Not comment so just print out the line normally
41  {
42  _stream << indent << line << "\n";
43  return;
44  }
45 
46  // We have a comment so we need to break it up over multiple lines if necessary
47  // and make sure that they all start at the same spot.
48  _stream << indent << line;
49  std::vector<std::string> elements;
50 
51  // if the line is empty we can just start the comment right away
52  int extra = 1;
53  if (line.empty())
54  extra = 0;
55 
56  // be careful of really long lines.
57  int len = 100 - max_line_len - indent.size();
58  if (len < 0)
59  len = 20;
60 
61  MooseUtils::tokenize(doc, elements, len, " \t");
62  std::string first(max_line_len - line.size() + extra, ' ');
63  _stream << first << "# " << elements[0] << "\n";
64  std::string cindent(max_line_len + indent.size() + extra, ' ');
65  for (size_t i = 1; i < elements.size(); ++i)
66  _stream << cindent << "# " << elements[i] << "\n";
67 }
68 
69 void
70 JsonInputFileFormatter::addBlock(const std::string & name,
71  const moosecontrib::Json::Value & block,
72  bool toplevel)
73 {
74  addLine("");
75  if (toplevel)
76  addLine("[" + name + "]");
77  else
78  addLine("[./" + name + "]");
79 
80  _level++;
81  if (block.isMember("description") && !block["description"].asString().empty())
82  addLine("", 0, block["description"].asString());
83 
84  if (block.isMember("parameters"))
85  addParameters(block["parameters"]);
86 
87  if (block.isMember("actions"))
88  {
89  // there could be duplicate parameters across actions, last one wins
90  moosecontrib::Json::Value all_params;
91  auto & actions = block["actions"];
92  for (auto && name : actions.getMemberNames())
93  {
94  auto & params = actions[name]["parameters"];
95  for (auto && param_name : params.getMemberNames())
96  all_params[param_name] = params[param_name];
97  }
98  addParameters(all_params);
99  }
100 
101  if (block.isMember("star"))
102  addBlock("*", block["star"]);
103 
104  addTypes("subblock_types", block);
105  addTypes("types", block);
106 
107  if (block.isMember("subblocks"))
108  {
109  auto & subblocks = block["subblocks"];
110  if (!subblocks.isNull())
111  for (auto && name : subblocks.getMemberNames())
112  addBlock(name, subblocks[name]);
113  }
114 
115  _level--;
116  if (toplevel)
117  addLine("[]");
118  else
119  addLine("[../]");
120 }
121 
122 void
123 JsonInputFileFormatter::addTypes(const std::string & key, const moosecontrib::Json::Value & block)
124 {
125  if (!block.isMember(key))
126  return;
127  auto & types = block[key];
128  if (types.isNull())
129  return;
130 
131  addLine("");
132  addLine("[./<types>]");
133  _level++;
134  for (auto && name : types.getMemberNames())
135  addBlock("<" + name + ">", types[name]);
136  _level--;
137  addLine("[../]");
138 }
139 
140 void
141 JsonInputFileFormatter::addParameters(const moosecontrib::Json::Value & params)
142 {
143  size_t max_name = 0;
144  for (auto && name : params.getMemberNames())
145  if (name.size() > max_name)
146  max_name = name.size();
147 
148  size_t max_len = 0;
149  std::map<std::string, std::string> lines;
150  for (auto && name : params.getMemberNames())
151  {
152  auto & param = params[name];
153  auto def = MooseUtils::trim(param["default"].asString());
154  if (def.find(' ') != std::string::npos)
155  def = "'" + def + "'";
156  std::string indent(max_name - name.size(), ' ');
157  std::string required;
158  if (param["required"].asBool())
159  required = "(required)";
160  if (def.size() == 0 && required.size() == 0)
161  def = "(no_default)";
162  std::string l = name + indent + " = " + def + required;
163  if (l.size() > max_len)
164  max_len = l.size();
165  lines[name] = l;
166  }
167  for (auto && name : params.getMemberNames())
168  {
169  auto & param = params[name];
170  auto & l = lines[name];
171  auto desc = param["description"].asString();
172  addLine(l, max_len, desc);
173 
174  auto group = param["group_name"].asString();
175  if (!group.empty())
176  addLine("", max_len + 1, "Group: " + group); // a +1 to account for an empty line
177  }
178 }
std::string indent(unsigned int spaces)
Create empty string for indenting.
Definition: ConsoleUtils.C:30
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
Definition: MooseUtils.h:532
std::string toString(const moosecontrib::Json::Value &root)
Returns a string representation of the tree in input file format.
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
Definition: MooseUtils.C:113
void addLine(const std::string &line, size_t max_line_len=0, const std::string &comment="")
Adds a line to the output.
void addBlock(const std::string &name, const moosecontrib::Json::Value &block, bool top=false)
Adds a new block to the output.
void addParameters(const moosecontrib::Json::Value &params)
Add a comment to the block.
void addTypes(const std::string &key, const moosecontrib::Json::Value &block)
Add a dictionary of type blocks to the output.