https://mooseframework.inl.gov
JsonInputFileFormatter.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
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 nlohmann::json & root)
19 {
20  _stream.clear();
21  _stream.str("");
22  for (auto && el : root["blocks"].items())
23  addBlock(el.key(), el.value(), 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  _stream << std::flush;
69 }
70 
71 void
72 JsonInputFileFormatter::addBlock(const std::string & name,
73  const nlohmann::json & block,
74  bool toplevel)
75 {
76  addLine("");
77  if (toplevel)
78  addLine("[" + name + "]");
79  else
80  addLine("[./" + name + "]");
81 
82  _level++;
83  std::string desc = block.contains("description") ? nlohmann::to_string(block["description"]) : "";
84  if (!desc.empty())
85  addLine("", 0, desc);
86 
87  if (block.contains("parameters"))
88  addParameters(block["parameters"]);
89 
90  if (block.contains("actions"))
91  {
92  // there could be duplicate parameters across actions, last one wins
93  nlohmann::json all_params;
94  auto & actions = block["actions"];
95  for (auto && el : actions.items())
96  {
97  auto & params = el.value()["parameters"];
98  for (auto && param_el : params.items())
99  all_params[param_el.key()] = param_el.value();
100  }
101  addParameters(all_params);
102  }
103 
104  if (block.contains("star"))
105  addBlock("*", block["star"]);
106 
107  addTypes("subblock_types", block);
108  addTypes("types", block);
109 
110  if (block.contains("subblocks"))
111  {
112  auto & subblocks = block["subblocks"];
113  if (!subblocks.is_null())
114  for (auto && el : subblocks.items())
115  addBlock(el.key(), el.value());
116  }
117 
118  _level--;
119  if (toplevel)
120  addLine("[]");
121  else
122  addLine("[../]");
123 }
124 
125 void
126 JsonInputFileFormatter::addTypes(const std::string & key, const nlohmann::json & block)
127 {
128  if (!block.contains(key))
129  return;
130  auto & types = block[key];
131  if (types.is_null())
132  return;
133 
134  addLine("");
135  addLine("[./<types>]");
136  _level++;
137  for (auto && el : types.items())
138  addBlock("<" + el.key() + ">", el.value());
139  _level--;
140  addLine("[../]");
141 }
142 
143 void
144 JsonInputFileFormatter::addParameters(const nlohmann::json & params)
145 {
146  size_t max_name = 0;
147  for (auto & el : params.items())
148  if (el.key().size() > max_name)
149  max_name = el.key().size();
150 
151  size_t max_len = 0;
152  std::map<std::string, std::string> lines;
153  for (auto && el : params.items())
154  {
155  auto & name = el.key();
156  auto & param = el.value();
157  auto def =
158  param.contains("default") ? MooseUtils::trim(nlohmann::to_string(param["default"])) : "";
159  if (!def.empty())
160  def = def.substr(1, def.size() - 2);
161  if (def.find(' ') != std::string::npos)
162  def = "'" + def + "'";
163  std::string indent(max_name - name.size(), ' ');
164  std::string required;
165  if (param["required"])
166  required = "(required)";
167  if (def.size() == 0 && required.size() == 0)
168  def = "(no_default)";
169  std::string l = name + indent + " = " + def + required;
170  if (l.size() > max_len)
171  max_len = l.size();
172  lines[name] = l;
173  }
174  for (auto & el : params.items())
175  {
176  auto & name = el.key();
177  auto & param = el.value();
178  auto & l = lines[name];
179  auto desc = nlohmann::to_string(param["description"]);
180  addLine(l, max_len, desc);
181 
182  const auto doc_unit = nlohmann::to_string(param["doc_unit"]);
183  if (!doc_unit.empty())
184  addLine("", max_len + 1,
185  "Unit: " + doc_unit); // a +1 to account for an empty line
186 
187  const auto group = nlohmann::to_string(param["group_name"]);
188  if (!group.empty())
189  addLine("", max_len + 1,
190  "Group: " + group); // a +1 to account for an empty line
191  }
192 }
std::string name(const ElemQuality q)
std::string indent(unsigned int spaces)
Create empty string for indenting.
Definition: ConsoleUtils.C:41
void addBlock(const std::string &name, const nlohmann::json &block, bool top=false)
Adds a new block to the output.
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 ...
void addTypes(const std::string &key, const nlohmann::json &block)
Add a dictionary of type blocks to the output.
std::string trim(const std::string &str, const std::string &white_space=" \\\)
Standard scripting language trim function.
void addLine(const std::string &line, size_t max_line_len=0, const std::string &comment="")
Adds a line to the output.
std::string toString(const nlohmann::json &root)
Returns a string representation of the tree in input file format.
void addParameters(const nlohmann::json &params)
Add a comment to the block.