1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmDocumentationFormatter.h"
11 #include "cmDocumentationEntry.h"
12 #include "cmDocumentationSection.h"
14 cmDocumentationFormatter::cmDocumentationFormatter() = default;
16 cmDocumentationFormatter::~cmDocumentationFormatter() = default;
18 void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
24 const char* ptr = text;
26 // Any ptrs starting in a space are treated as preformatted text.
27 std::string preformatted;
29 for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) {
30 preformatted.append(1, ch);
34 preformatted.append(1, '\n');
37 if (!preformatted.empty()) {
38 this->PrintPreformatted(os, preformatted.c_str());
41 // Other ptrs are treated as paragraphs.
42 std::string paragraph;
43 for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) {
44 paragraph.append(1, ch);
48 paragraph.append(1, '\n');
50 if (!paragraph.empty()) {
51 this->PrintParagraph(os, paragraph.c_str());
56 void cmDocumentationFormatter::PrintPreformatted(std::ostream& os,
60 for (const char* ptr = text; *ptr; ++ptr) {
61 if (newline && *ptr != '\n') {
62 os << this->TextIndent;
73 void cmDocumentationFormatter::PrintParagraph(std::ostream& os,
76 os << this->TextIndent;
77 this->PrintColumn(os, text);
81 void cmDocumentationFormatter::SetIndent(const char* indent)
83 this->TextIndent = indent;
86 void cmDocumentationFormatter::PrintColumn(std::ostream& os, const char* text)
88 // Print text arranged in an indented column of fixed width.
91 bool newSentence = false;
92 bool firstLine = true;
93 int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));
95 // Loop until the end of the text.
97 // Parse the next word.
99 while (*r && (*r != '\n') && (*r != ' ')) {
103 // Does it fit on this line?
104 if (r - l < (width - column - (newSentence ? 1 : 0))) {
105 // Word fits on this line.
108 // Not first word on line. Separate from the previous word
109 // by a space, or two if this is a new sentence.
118 // First word on line. Print indentation unless this is the
120 os << (firstLine ? "" : this->TextIndent);
124 os.write(l, static_cast<long>(r - l));
125 newSentence = (*(r - 1) == '.');
129 // Text provided a newline. Start a new line.
135 // No provided newline. Continue this line.
136 column += static_cast<long>(r - l);
139 // Word does not fit on this line. Start a new line.
143 os << this->TextIndent;
144 os.write(l, static_cast<long>(r - l));
145 column = static_cast<long>(r - l);
146 newSentence = (*(r - 1) == '.');
152 // Move to beginning of next word. Skip over whitespace.
160 void cmDocumentationFormatter::PrintSection(
161 std::ostream& os, cmDocumentationSection const& section)
163 os << section.GetName() << "\n";
165 const std::vector<cmDocumentationEntry>& entries = section.GetEntries();
166 for (cmDocumentationEntry const& entry : entries) {
167 if (!entry.Name.empty()) {
168 os << std::setw(2) << std::left << entry.CustomNamePrefix << entry.Name;
169 this->TextIndent = " ";
170 int align = static_cast<int>(strlen(this->TextIndent)) - 4;
171 for (int i = static_cast<int>(entry.Name.size()); i < align; ++i) {
174 if (entry.Name.size() > strlen(this->TextIndent) - 4) {
176 os.write(this->TextIndent, strlen(this->TextIndent) - 2);
179 this->PrintColumn(os, entry.Brief.c_str());
183 this->TextIndent = "";
184 this->PrintFormatted(os, entry.Brief.c_str());