}
}
-// Print a section in the desired style. The styles are separated into
-// several verbosity classes depending on the higher bits.
-//
-// If bit 7 (128) is set, comments are not printed.
-// If bit 6 (64) is set, default values after change are not printed.
-void
-ParameterHandler::print_parameters_section(
- std::ostream & out,
- const OutputStyle style,
- const unsigned int indent_level,
- const bool include_top_level_elements,
- const bool sort_alphabetical)
-{
- AssertThrow(out, ExcIO());
-
- // Create entries copy and sort it, if needed.
- // In this way we ensure that the class state is never
- // modified by this function.
- boost::property_tree::ptree sorted_entries;
- boost::property_tree::ptree *current_entries = entries.get();
-
- // Sort parameters alphabetically, if needed.
- if (sort_alphabetical)
- {
- sorted_entries = *entries;
- current_entries = &sorted_entries;
-
- // Dive recursively into the subsections,
- // starting from current level.
- recursively_sort_parameters(path_separator,
- subsection_path,
- sorted_entries);
- }
-
- const boost::property_tree::ptree ¤t_section =
- current_entries->get_child(get_current_path());
-
- unsigned int overall_indent_level = indent_level;
-
- switch (style)
- {
- case XML:
- {
- if (include_top_level_elements)
- {
- // call the writer function and exit as there is nothing
- // further to do down in this function
- //
- // XML has a requirement that there can only be one single
- // top-level entry, but a section has multiple entries and
- // sections. we work around this by creating a tree just for
- // this purpose with the single top-level node
- // "ParameterHandler" and assign the full path of down to
- // the current section under it
- boost::property_tree::ptree single_node_tree;
-
- // if there is no subsection selected, add the whole tree of
- // entries, otherwise add a root element and the selected
- // subsection under it
- if (subsection_path.size() == 0)
- {
- single_node_tree.add_child("ParameterHandler",
- *current_entries);
- }
- else
- {
- std::string path("ParameterHandler");
-
- single_node_tree.add_child(path,
- boost::property_tree::ptree());
-
- path += path_separator + get_current_path();
- single_node_tree.add_child(path, current_section);
- }
-
- write_xml(out, single_node_tree);
- }
- else
- Assert(false, ExcNotImplemented());
-
- break;
- }
- case Text:
- case ShortText:
- {
- // if there are top level elements to print, do it
- if (include_top_level_elements && (subsection_path.size() > 0))
- for (const auto &path : subsection_path)
- {
- out << std::setw(overall_indent_level * 2) << ""
- << "subsection " << demangle(path) << std::endl;
- overall_indent_level += 1;
- }
-
- // first find out the longest entry name to be able to align the
- // equal signs to do this loop over all nodes of the current
- // tree, select the parameter nodes (and discard sub-tree nodes)
- // and take the maximum of their lengths
- std::size_t longest_name = 0;
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- longest_name = std::max(longest_name, demangle(p.first).length());
-
- // likewise find the longest actual value string to make sure we
- // can align the default and documentation strings
- std::size_t longest_value = 0;
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- longest_value =
- std::max(longest_value,
- p.second.get<std::string>("value").length());
-
-
- // print entries one by one
- bool first_entry = true;
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- {
- const std::string value = p.second.get<std::string>("value");
-
- // if there is documentation, then add an empty line
- // (unless this is the first entry in a subsection), print
- // the documentation, and then the actual entry; break the
- // documentation into readable chunks such that the whole
- // thing is at most 78 characters wide
- if ((!(style & 128)) &&
- !p.second.get<std::string>("documentation").empty())
- {
- if (first_entry == false)
- out << std::endl;
- else
- first_entry = false;
-
- const std::vector<std::string> doc_lines =
- Utilities::break_text_into_lines(
- p.second.get<std::string>("documentation"),
- 78 - overall_indent_level * 2 - 2);
-
- for (const auto &doc_line : doc_lines)
- out << std::setw(overall_indent_level * 2) << ""
- << "# " << doc_line << std::endl;
- }
-
-
-
- // print name and value of this entry
- out << std::setw(overall_indent_level * 2) << ""
- << "set " << demangle(p.first)
- << std::setw(longest_name - demangle(p.first).length() + 1)
- << " "
- << "= " << value;
-
- // finally print the default value, but only if it differs
- // from the actual value
- if ((!(style & 64)) &&
- value != p.second.get<std::string>("default_value"))
- {
- out << std::setw(longest_value - value.length() + 1) << ' '
- << "# ";
- out << "default: "
- << p.second.get<std::string>("default_value");
- }
-
- out << std::endl;
- }
-
- break;
- }
-
- case LaTeX:
- {
- auto escape = [](const std::string &input) {
- return Patterns::internal::escape(input,
- Patterns::PatternBase::LaTeX);
- };
-
- // if there are any parameters in this section then print them
- // as an itemized list
- bool parameters_exist_here = false;
- for (const auto &p : current_section)
- if ((is_parameter_node(p.second) == true) ||
- (is_alias_node(p.second) == true))
- {
- parameters_exist_here = true;
- break;
- }
-
- if (parameters_exist_here)
- {
- out << "\\begin{itemize}" << std::endl;
-
- // print entries one by one
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- {
- const std::string value =
- p.second.get<std::string>("value");
-
- // print name
- out << "\\item {\\it Parameter name:} {\\tt "
- << escape(demangle(p.first)) << "}\n"
- << "\\phantomsection\\label{parameters:";
- for (const auto &path : subsection_path)
- out << mangle(path) << "/";
- out << p.first;
- out << "}\n\n" << std::endl;
-
- out << "\\index[prmindex]{" << escape(demangle(p.first))
- << "}\n";
- out << "\\index[prmindexfull]{";
- for (const auto &path : subsection_path)
- out << escape(path) << "!";
- out << escape(demangle(p.first)) << "}\n";
-
- // finally print value and default
- out << "{\\it Value:} " << escape(value) << "\n\n"
- << std::endl
- << "{\\it Default:} "
- << escape(p.second.get<std::string>("default_value"))
- << "\n\n"
- << std::endl;
-
- // if there is a documenting string, print it as well
- if (!p.second.get<std::string>("documentation").empty())
- out << "{\\it Description:} "
- << p.second.get<std::string>("documentation")
- << "\n\n"
- << std::endl;
-
- // also output possible values
- const unsigned int pattern_index =
- p.second.get<unsigned int>("pattern");
- const std::string desc_str =
- patterns[pattern_index]->description(
- Patterns::PatternBase::LaTeX);
- out << "{\\it Possible values:} " << desc_str << std::endl;
- }
- else if (is_alias_node(p.second) == true)
- {
- const std::string alias =
- p.second.get<std::string>("alias");
-
- // print name
- out << "\\item {\\it Parameter name:} {\\tt "
- << escape(demangle(p.first)) << "}\n"
- << "\\phantomsection\\label{parameters:";
- for (const auto &path : subsection_path)
- out << mangle(path) << "/";
- out << p.first;
- out << "}\n\n" << std::endl;
-
- out << "\\index[prmindex]{" << escape(demangle(p.first))
- << "}\n";
- out << "\\index[prmindexfull]{";
- for (const auto &path : subsection_path)
- out << escape(path) << "!";
- out << escape(demangle(p.first)) << "}\n";
-
- // finally print alias and indicate if it is deprecated
- out
- << "This parameter is an alias for the parameter ``\\texttt{"
- << escape(alias) << "}''."
- << (p.second.get<std::string>("deprecation_status") ==
- "true" ?
- " Its use is deprecated." :
- "")
- << "\n\n"
- << std::endl;
- }
- out << "\\end{itemize}" << std::endl;
- }
-
- break;
- }
-
- case Description:
- {
- // if there are top level elements to print, do it
- if (include_top_level_elements && (subsection_path.size() > 0))
- for (const auto &path : subsection_path)
- {
- out << std::setw(overall_indent_level * 2) << ""
- << "subsection " << demangle(path) << std::endl;
- overall_indent_level += 1;
- };
-
- // first find out the longest entry name to be able to align the
- // equal signs
- std::size_t longest_name = 0;
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- longest_name = std::max(longest_name, demangle(p.first).length());
-
- // print entries one by one
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- {
- // print name and value
- out << std::setw(overall_indent_level * 2) << ""
- << "set " << demangle(p.first)
- << std::setw(longest_name - demangle(p.first).length() + 1)
- << " "
- << " = ";
-
- // print possible values:
- const unsigned int pattern_index =
- p.second.get<unsigned int>("pattern");
- const std::string full_desc_str =
- patterns[pattern_index]->description(
- Patterns::PatternBase::Text);
- const std::vector<std::string> description_str =
- Utilities::break_text_into_lines(
- full_desc_str, 78 - overall_indent_level * 2 - 2, '|');
- if (description_str.size() > 1)
- {
- out << std::endl;
- for (const auto &description : description_str)
- out << std::setw(overall_indent_level * 2 + 6) << ""
- << description << std::endl;
- }
- else if (description_str.empty() == false)
- out << " " << description_str[0] << std::endl;
- else
- out << std::endl;
-
- // if there is a documenting string, print it as well
- if (p.second.get<std::string>("documentation").length() != 0)
- out << std::setw(overall_indent_level * 2 + longest_name + 10)
- << ""
- << "(" << p.second.get<std::string>("documentation")
- << ")" << std::endl;
- }
-
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
-
-
- // if there was text before and there are sections to come, put two
- // newlines between the last entry and the first subsection
- if (style != XML)
- {
- unsigned int n_parameters = 0;
- unsigned int n_sections = 0;
- for (const auto &p : current_section)
- if (is_parameter_node(p.second) == true)
- ++n_parameters;
- else if (is_alias_node(p.second) == false)
- ++n_sections;
-
- if ((style != Description) && (!(style & 128)) && (n_parameters != 0) &&
- (n_sections != 0))
- out << std::endl << std::endl;
-
- // now transverse subsections tree
- for (const auto &p : current_section)
- if ((is_parameter_node(p.second) == false) &&
- (is_alias_node(p.second) == false))
- {
- // first print the subsection header
- switch (style)
- {
- case Text:
- case Description:
- case ShortText:
- out << std::setw(overall_indent_level * 2) << ""
- << "subsection " << demangle(p.first) << std::endl;
- break;
- case LaTeX:
- {
- auto escape = [](const std::string &input) {
- return Patterns::internal::escape(
- input, Patterns::PatternBase::LaTeX);
- };
-
- out << std::endl
- << "\\subsection{Parameters in section \\tt ";
-
- // find the path to the current section so that we can
- // print it in the \subsection{...} heading
- for (const auto &path : subsection_path)
- out << escape(path) << "/";
- out << escape(demangle(p.first));
-
- out << "}" << std::endl;
- out << "\\label{parameters:";
- for (const auto &path : subsection_path)
- out << mangle(path) << "/";
- out << p.first << "}";
- out << std::endl;
-
- out << std::endl;
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
-
- // then the contents of the subsection
- enter_subsection(demangle(p.first));
- print_parameters_section(out, style, overall_indent_level + 1);
- leave_subsection();
- switch (style)
- {
- case Text:
- // write end of subsection. one blank line after each
- // subsection
- out << std::setw(overall_indent_level * 2) << ""
- << "end" << std::endl
- << std::endl;
-
- // if this is a toplevel subsection, then have two
- // newlines
- if (overall_indent_level == 0)
- out << std::endl;
-
- break;
- case Description:
- break;
- case ShortText:
- // write end of subsection.
- out << std::setw(overall_indent_level * 2) << ""
- << "end" << std::endl;
- break;
- case LaTeX:
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
- }
- }
-
- // close top level elements, if there are any
- switch (style)
- {
- case XML:
- case LaTeX:
- case Description:
- break;
- case Text:
- case ShortText:
- {
- if (include_top_level_elements && (subsection_path.size() > 0))
- for (unsigned int i = 0; i < subsection_path.size(); ++i)
- {
- overall_indent_level -= 1;
- out << std::setw(overall_indent_level * 2) << ""
- << "end" << std::endl;
- }
-
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
-}
-
void