diff options
Diffstat (limited to 'Source/cmDocumentationFormatter.cxx')
-rw-r--r-- | Source/cmDocumentationFormatter.cxx | 268 |
1 files changed, 153 insertions, 115 deletions
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index 9f01949b9..001826318 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx @@ -1,17 +1,18 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmDocumentationFormatter.h" - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. +#include "cmDocumentationEntry.h" +#include "cmDocumentationSection.h" - 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 <ostream> +#include <string.h> +#include <string> +#include <vector> cmDocumentationFormatter::cmDocumentationFormatter() + : TextWidth(77) + , TextIndent("") { } @@ -22,135 +23,172 @@ cmDocumentationFormatter::~cmDocumentationFormatter() void cmDocumentationFormatter::PrintFormatted(std::ostream& os, const char* text) { - if(!text) - { + if (!text) { return; - } + } const char* ptr = text; - while(*ptr) - { + 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) - { + while (*ptr == ' ') { + for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) { preformatted.append(1, ch); - } - if(*ptr) - { + } + if (*ptr) { ++ptr; preformatted.append(1, '\n'); - } } - if(preformatted.length()) - { + } + 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) - { + for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) { paragraph.append(1, ch); - } - if(*ptr) - { + } + if (*ptr) { ++ptr; paragraph.append(1, '\n'); - } - if(paragraph.length()) - { + } + 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; } -//---------------------------------------------------------------------------- -std::string -cmDocumentationFormatter::ComputeSectionLinkPrefix(std::string const& name) +void cmDocumentationFormatter::PrintColumn(std::ostream& os, const char* text) { - // Map from section name to a prefix for links pointing within the - // section. For example, the commands section should have HTML - // links to each command with names like #command:ADD_EXECUTABLE. - if(name.find("Command") != name.npos) - { - return "command"; + // 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; } - else if(name.find("Propert") != name.npos) - { - if(name.find("Global") != name.npos) - { - return "prop_global"; - } - else if(name.find("Direct") != name.npos) - { - return "prop_dir"; - } - else if(name.find("Target") != name.npos) - { - return "prop_tgt"; + + // 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) == '.'); } - else if(name.find("Test") != name.npos) - { - return "prop_test"; + + 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 if(name.find("Source") != name.npos) - { - return "prop_sf"; + } 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; } - return "property"; - } - else if(name.find("Variable") != name.npos) - { - return "variable"; - } - else if(name.find("Polic") != name.npos) - { - return "policy"; - } - else if(name.find("Module") != name.npos) - { - return "module"; - } - else if(name.find("Name") != name.npos || - name.find("Introduction") != name.npos) - { - return "name"; - } - else if(name.find("Usage") != name.npos) - { - return "usage"; - } - else if(name.find("Description") != name.npos) - { - return "desc"; } - else if(name.find("Generators") != name.npos) - { - return "gen"; - } - else if(name.find("Options") != name.npos) - { - return "opt"; - } - else if(name.find("Copyright") != name.npos) - { - return "copy"; - } - else if(name.find("See Also") != name.npos) - { - return "see"; - } - else if(name.find("SingleItem") != name.npos) - { - return "single_item"; - } - else - { - std::cerr - << "WARNING: ComputeSectionLinkPrefix failed for \"" << name << "\"" - << std::endl; - return "other"; + + // Move to beginning of next word. Skip over whitespace. + l = r; + while (*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"; } |