36 [](
unsigned char c) { return std::tolower(c); });
37 return "#" + sanitized;
48template <
typename ATTRIBUTE_T>
51 out <<
"<!ATTLIST " << ElementName <<
" " << attr.getName() <<
" CDATA ";
53 if (attr.hasDefaultValue()) {
54 out <<
"\"" << attr.getDefaultValue() <<
"\"";
64template <
typename ATTRIBUTE_T>
67 out <<
"| " << attr.getName() <<
" | " <<
utils::getTypeName(attr.getDefaultValue()) <<
" | " << attr.getUserDocumentation() <<
" | ";
68 if (attr.hasDefaultValue()) {
69 out <<
'`' << attr.getDefaultValue() <<
'`';
75 const auto &options = attr.getOptions();
76 if (options.empty()) {
79 out <<
'`' << options.front() <<
'`';
80 for (
auto iter = ++options.cbegin(); iter != options.cend(); ++iter) {
81 out <<
", " <<
'`' << *iter <<
'`';
90template <
typename ATTRIBUTE_T>
93 out << attr.getName() <<
"=\"";
94 if (attr.hasDefaultValue()) {
95 out << attr.getDefaultValue();
104template <
typename ATTRIBUTE_T>
108 if (attr.hasValidation()) {
111 auto first = attr.getOptions().begin();
112 out <<
'\'' << *first <<
'\'';
115 for (; first != attr.getOptions().
end(); ++first) {
116 out <<
" or '" << *first <<
'\'';
120 if (attr.hasDefaultValue()) {
121 out <<
"(default:'" << attr.getDefaultValue() <<
"')";
135 out <<
"<!DOCTYPE " << tag.getFullName() <<
" [\n";
137 out <<
"<!ELEMENT " << tag.getFullName() <<
" ";
139 if (not tag.getSubtags().empty()) {
144 for (
auto const &subtag : tag.getSubtags()) {
151 occurrenceChar =
"*";
153 occurrenceChar =
"?";
155 occurrenceChar =
"+";
157 out << (first ?
"" :
", ") << subtag->getFullName() << occurrenceChar;
166 for (
const auto &pair : tag.getDoubleAttributes()) {
167 printDTD(
out, pair.second, tag.getFullName());
170 for (
const auto &pair : tag.getIntAttributes()) {
171 printDTD(
out, pair.second, tag.getFullName());
174 for (
const auto &pair : tag.getStringAttributes()) {
175 printDTD(
out, pair.second, tag.getFullName());
178 for (
const auto &pair : tag.getBooleanAttributes()) {
179 printDTD(
out, pair.second, tag.getFullName());
182 for (
const auto &pair : tag.getEigenVectorXdAttributes()) {
183 printDTD(
out, pair.second, tag.getFullName());
186 if (not tag.getSubtags().empty()) {
187 for (
const auto &subtag : tag.getSubtags()) {
188 printDTD(
out, *subtag);
207 out <<
prefix <<
'<' << tag.getFullName();
208 for (
const auto &pair : tag.getDoubleAttributes()) {
210 printExample(
out, pair.second);
212 for (
const auto &pair : tag.getIntAttributes()) {
214 printExample(
out, pair.second);
216 for (
const auto &pair : tag.getStringAttributes()) {
218 printExample(
out, pair.second);
220 for (
const auto &pair : tag.getBooleanAttributes()) {
222 printExample(
out, pair.second);
224 for (
const auto &pair : tag.getEigenVectorXdAttributes()) {
226 printExample(
out, pair.second);
228 if (tag.getSubtags().empty()) {
234 constexpr int threshold{1};
235 if (level >= threshold) {
239 for (
const auto &subtag : tag.getSubtags()) {
240 const auto ns = subtag->getNamespace();
242 if (namespaces.
count(subtag->getNamespace()) > 0) {
247 printExample(
out, *subtag, level + 1) <<
'\n';
251 out <<
prefix <<
"</" << tag.getFullName() <<
'>';
263 out <<
std::string(level,
'#') <<
' ' << tag.getFullName() <<
"\n\n";
265 out << tag.getDocumentation() <<
"\n\n";
267 out <<
"**Example:** \n```xml\n";
268 printExample(
out, tag, 0) <<
"\n```\n\n";
270 if (!(tag.getDoubleAttributes().empty() &&
271 tag.getIntAttributes().empty() &&
272 tag.getStringAttributes().empty() &&
273 tag.getBooleanAttributes().empty() &&
274 tag.getEigenVectorXdAttributes().empty())) {
275 out <<
"| Attribute | Type | Description | Default | Options |\n";
276 out <<
"| --- | --- | --- | --- | --- |\n";
277 for (
const auto &pair : tag.getDoubleAttributes()) {
278 printMD(
out, pair.second) <<
'\n';
281 for (
const auto &pair : tag.getIntAttributes()) {
282 printMD(
out, pair.second) <<
'\n';
285 for (
const auto &pair : tag.getStringAttributes()) {
286 printMD(
out, pair.second) <<
'\n';
289 for (
const auto &pair : tag.getBooleanAttributes()) {
290 printMD(
out, pair.second) <<
'\n';
293 for (
const auto &pair : tag.getEigenVectorXdAttributes()) {
294 printMD(
out, pair.second) <<
'\n';
299 if (not tag.getSubtags().empty()) {
300 out <<
"**Valid Subtags:**\n\n";
304 for (
const auto &subtag : tag.getSubtags()) {
305 const auto heading = subtag->getFullName();
306 auto link = toGHLink(heading);
307 auto iter = occurrences.
find(heading);
308 if (iter != occurrences.
end()) {
312 occurrences.
emplace(heading, 1);
315 const auto ns = subtag->getNamespace();
317 out <<
"* [" << heading <<
"](" << link <<
") `" << subtag->getOccurrenceString(subtag->getOccurrence()) <<
"`\n";
319 auto &tags = groupedTags[ns];
320 tags.emplace_back(
"[" + subtag->getName() +
"](" + link +
") `" + subtag->getOccurrenceString(subtag->getOccurrence()) +
"`");
323 for (
const auto &kv : groupedTags) {
324 out <<
"* " << kv.first <<
"\n";
325 for (
const auto &link : kv.second) {
326 out <<
" * " << link <<
"\n";
332 for (
const auto &subtag : tag.getSubtags()) {
333 printMD(
out, *subtag, level + 1, occurrences) <<
'\n';
347 printMD(
out, tag, level, occurrences);
354 const int linewidth = 1000;
356 for (
int i = 0; i < indentation; i++) {
360 out << indent <<
"<!-- TAG " << tag.getFullName() <<
'\n';
361 if (not tag.getDocumentation().empty()) {
362 std::string indentedDoc = indent +
" " + tag.getDocumentation();
368 for (
const auto &pair : tag.getDoubleAttributes()) {
371 attrDoc << indent <<
" ATTR " << pair.first <<
": "
372 << pair.second.getUserDocumentation();
376 for (
const auto &pair : tag.getIntAttributes()) {
379 attrDoc << indent <<
" ATTR " << pair.first <<
": "
380 << pair.second.getUserDocumentation();
384 for (
const auto &pair : tag.getStringAttributes()) {
387 attrDoc << indent <<
" ATTR " << pair.first <<
": "
388 << pair.second.getUserDocumentation();
392 for (
const auto &pair : tag.getBooleanAttributes()) {
395 attrDoc << indent <<
" ATTR " << pair.first <<
": "
396 << pair.second.getUserDocumentation();
400 for (
const auto &pair : tag.getEigenVectorXdAttributes()) {
403 attrDoc << indent <<
" ATTR " << pair.first <<
": "
404 << pair.second.getUserDocumentation();
410 tagHead << indent <<
"<" << tag.getFullName();
413 for (
const std::string &namespaceName : tag.getNamespaces()) {
414 tagHead <<
" xmlns:" << namespaceName <<
"=\"precice." << namespaceName <<
"\"";
417 for (
const auto &pair : tag.getDoubleAttributes()) {
418 tagHead << indent <<
" ";
419 printDocumentation(tagHead, pair.second);
422 for (
const auto &pair : tag.getIntAttributes()) {
423 tagHead << indent <<
" ";
424 printDocumentation(tagHead, pair.second);
427 for (
const auto &pair : tag.getStringAttributes()) {
428 tagHead << indent <<
" ";
429 printDocumentation(tagHead, pair.second);
432 for (
const auto &pair : tag.getBooleanAttributes()) {
433 tagHead << indent <<
" ";
434 printDocumentation(tagHead, pair.second);
437 for (
const auto &pair : tag.getEigenVectorXdAttributes()) {
438 tagHead << indent <<
" ";
439 printDocumentation(tagHead, pair.second);
444 if (not tag.getSubtags().empty()) {
446 for (
const auto &subtag : tag.getSubtags()) {
447 printDocumentation(
out, *subtag, indentation + 3);
449 out << indent <<
"</" << tag.getFullName() <<
">\n\n";
Represents an XML tag to be configured automatically.
static std::string getOccurrenceString(Occurrence occurrence)
Occurrence
Types of occurrences of an XML tag.
std::string wrapText(const std::string &text, int linewidth, int indentation)
std::string getTypeName(const double &var)
contains the XML configuration parser.
void toMarkdown(std::ostream &out, const XMLTag &tag)
Prints the Markdown reference for the given tag.
void toDTD(std::ostream &out, const XMLTag &tag)
Prints the DTD reference for the given tag.
void toDocumentation(std::ostream &out, const XMLTag &tag)
Prints the XML reference for the given tag.
T regex_replace(T... args)