diff options
Diffstat (limited to 'Source/cmDocumentationFormatter.cxx')
-rw-r--r-- | Source/cmDocumentationFormatter.cxx | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx new file mode 100644 index 0000000..6869e2f --- /dev/null +++ b/Source/cmDocumentationFormatter.cxx @@ -0,0 +1,230 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmDocumentationFormatter.h" + +#include "cmDocumentationSection.h" + +cmDocumentationFormatter::cmDocumentationFormatter(): + TextWidth(77), TextIndent("") +{ +} + +cmDocumentationFormatter::~cmDocumentationFormatter() +{ +} + +void cmDocumentationFormatter::PrintFormatted(std::ostream& os, + const char* text) +{ + if(!text) + { + return; + } + const char* ptr = text; + while(*ptr) + { + // Any ptrs starting in a space are treated as preformatted text. + std::string preformatted; + while(*ptr == ' ') + { + for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) + { + preformatted.append(1, ch); + } + if(*ptr) + { + ++ptr; + preformatted.append(1, '\n'); + } + } + if(!preformatted.empty()) + { + this->PrintPreformatted(os, preformatted.c_str()); + } + + // Other ptrs are treated as paragraphs. + std::string paragraph; + for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) + { + paragraph.append(1, ch); + } + if(*ptr) + { + ++ptr; + paragraph.append(1, '\n'); + } + if(!paragraph.empty()) + { + this->PrintParagraph(os, paragraph.c_str()); + } + } +} + +void cmDocumentationFormatter::PrintPreformatted(std::ostream& os, + const char* text) +{ + bool newline = true; + for(const char* ptr = text; *ptr; ++ptr) + { + if(newline && *ptr != '\n') + { + os << this->TextIndent; + newline = false; + } + os << *ptr; + if(*ptr == '\n') + { + newline = true; + } + } + os << "\n"; +} + +void cmDocumentationFormatter::PrintParagraph(std::ostream& os, + const char* text) +{ + os << this->TextIndent; + this->PrintColumn(os, text); + os << "\n"; +} + +void cmDocumentationFormatter::SetIndent(const char* indent) +{ + this->TextIndent = indent; +} + +void cmDocumentationFormatter::PrintColumn(std::ostream& os, + const char* text) +{ + // Print text arranged in an indented column of fixed witdh. + const char* l = text; + long column = 0; + bool newSentence = false; + bool firstLine = true; + int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent)); + + // Loop until the end of the text. + while(*l) + { + // Parse the next word. + const char* r = l; + while(*r && (*r != '\n') && (*r != ' ')) { ++r; } + + // Does it fit on this line? + if(r-l < (width-column-(newSentence?1:0))) + { + // Word fits on this line. + if(r > l) + { + if(column) + { + // Not first word on line. Separate from the previous word + // by a space, or two if this is a new sentence. + if(newSentence) + { + os << " "; + column += 2; + } + else + { + os << " "; + column += 1; + } + } + else + { + // First word on line. Print indentation unless this is the + // first line. + os << (firstLine?"":this->TextIndent); + } + + // Print the word. + os.write(l, static_cast<long>(r-l)); + newSentence = (*(r-1) == '.'); + } + + if(*r == '\n') + { + // Text provided a newline. Start a new line. + os << "\n"; + ++r; + column = 0; + firstLine = false; + } + else + { + // No provided newline. Continue this line. + column += static_cast<long>(r-l); + } + } + else + { + // Word does not fit on this line. Start a new line. + os << "\n"; + firstLine = false; + if(r > l) + { + os << this->TextIndent; + os.write(l, static_cast<long>(r-l)); + column = static_cast<long>(r-l); + newSentence = (*(r-1) == '.'); + } + else + { + column = 0; + } + } + + // Move to beginning of next word. Skip over whitespace. + l = r; + while(*l && (*l == ' ')) { ++l; } + } +} + +void cmDocumentationFormatter +::PrintSection(std::ostream& os, + cmDocumentationSection const& section) +{ + os << section.GetName() << "\n"; + + const std::vector<cmDocumentationEntry> &entries = + section.GetEntries(); + for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); + op != entries.end(); ++op) + { + if(!op->Name.empty()) + { + os << " " << op->Name; + this->TextIndent = " "; + int align = static_cast<int>(strlen(this->TextIndent))-4; + for(int i = static_cast<int>(op->Name.size()); i < align; ++i) + { + os << " "; + } + if (op->Name.size() > strlen(this->TextIndent)-4 ) + { + os << "\n"; + os.write(this->TextIndent, strlen(this->TextIndent)-2); + } + os << "= "; + this->PrintColumn(os, op->Brief.c_str()); + os << "\n"; + } + else + { + os << "\n"; + this->TextIndent = ""; + this->PrintFormatted(os, op->Brief.c_str()); + } + } + os << "\n"; +} |