Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:55

0001 
0002 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
0003 
0004 #include <algorithm>
0005 #include <ostream>
0006 #include <iomanip>
0007 
0008 namespace edm {
0009 
0010   namespace {
0011     void wrapAndPrintLine(std::ostream& os, std::string const& text, size_t indent, size_t suggestedWidth) {
0012       char oldFill = os.fill();
0013 
0014       size_t length = text.size();
0015 
0016       // The position in the text where we start printing the next line
0017       size_t startLine = 0U;
0018 
0019       // The position in the text where we start looking for the next blank space
0020       size_t startNextSearch = 0U;
0021 
0022       // Loop over spaces in the text
0023       while (true) {
0024         // If the rest of the text fits on the current line,
0025         // then print it and we are done
0026         if ((length - startLine) <= suggestedWidth) {
0027           os << std::setfill(' ') << std::setw(indent) << "";
0028           if (startLine == 0)
0029             os << text;
0030           else
0031             os << text.substr(startLine);
0032           os << "\n";
0033           break;
0034         }
0035 
0036         // Look for next space
0037         size_t pos = text.find_first_of(' ', startNextSearch);
0038 
0039         // No more spaces
0040         if (pos == std::string::npos) {
0041           // The rest of the comment cannot fit in the width or we
0042           // would have already printed it.  Break the line at the
0043           // end of the previous word if there is one and print the
0044           // first part.  Then print the rest whether it fits or not.
0045           if (startNextSearch != startLine) {
0046             os << std::setfill(' ') << std::setw(indent) << "";
0047             os << text.substr(startLine, startNextSearch - startLine);
0048             os << "\n";
0049             startLine = startNextSearch;
0050           }
0051           os << std::setfill(' ') << std::setw(indent) << "";
0052           os << text.substr(startLine);
0053           os << "\n";
0054           break;
0055         }
0056 
0057         if ((pos + 1U - startLine) > suggestedWidth) {
0058           // With this word the line is too long.  Print out to
0059           // the end of the previous word if there was one.
0060           // If there was not, then print to the end of this word
0061           // even though it exceeds the width.
0062           if (startNextSearch != startLine) {
0063             os << std::setfill(' ') << std::setw(indent) << "";
0064             os << text.substr(startLine, startNextSearch - startLine);
0065             os << "\n";
0066             startLine = startNextSearch;
0067           }
0068           if ((pos + 1U - startLine) > suggestedWidth) {
0069             os << std::setfill(' ') << std::setw(indent) << "";
0070             os << text.substr(startLine, pos + 1U - startLine);
0071             os << "\n";
0072             startLine = pos + 1U;
0073           }
0074         }
0075         startNextSearch = pos + 1U;
0076       }
0077       os.fill(oldFill);
0078     }
0079   }  // namespace
0080 
0081   // Print and wrap text to an output stream.
0082   // This function looks for new line chars in the text,
0083   // and calls wrapAndPrintLine() to output each line,
0084   // which wraps appropriately.  That function
0085   // inserts new lines to try to break the text to fit into
0086   // the suggested width.  At the beginning and after every
0087   // inserted newline this will print "indent" blank spaces.
0088   // The function will consider inserting a new line after
0089   // every blank space.  If the text to the next blank
0090   // space will exceed the "suggestedWidth" it inserts a
0091   // new line.  If the text between two blank spaces (a "word")
0092   // is longer than the suggested width, then it prints the whole
0093   // word anyway (exceeding the "suggestedWidth" for lines).
0094   // The output will look nice if the input has words separated
0095   // by a single blank space with no extra space in the input text,
0096   // otherwise the extra spaces and newlines get printed
0097   // making the output not nicely formatted ...
0098   void DocFormatHelper::wrapAndPrintText(std::ostream& os,
0099                                          std::string const& text,
0100                                          size_t indent,
0101                                          size_t suggestedWidth) {
0102     size_t pos = text.find_first_of('\n');
0103     if (pos == std::string::npos) {
0104       // no embedded newlines
0105       wrapAndPrintLine(os, text, indent, suggestedWidth);
0106     } else {
0107       // print the first line.
0108       wrapAndPrintLine(os, text.substr(0, pos), indent, suggestedWidth);
0109       // print all lines after the first.
0110       wrapAndPrintText(os, text.substr(pos + 1), indent, suggestedWidth);
0111     }
0112   }
0113 
0114   void DocFormatHelper::init() {
0115     section_ = std::string();
0116     pass_ = 0;
0117     column1_ = 0;
0118     column2_ = 0;
0119     column3_ = 0;
0120     counter_ = 0;
0121     parent_ = OTHER;
0122   }
0123 
0124   size_t DocFormatHelper::commentWidth() const {
0125     // Make the length of a comment at least 30 characters
0126     // per line, longer if there is more space available
0127     size_t width = 30U;
0128     if (lineWidth() > startColumn2() + 30U) {
0129       width = lineWidth() - startColumn2();
0130     }
0131     return width;
0132   }
0133 
0134   void DocFormatHelper::indent(std::ostream& os) const {
0135     char oldFill = os.fill();
0136     os << std::setfill(' ') << std::setw(indentation_) << "";
0137     os.fill(oldFill);
0138   }
0139 
0140   void DocFormatHelper::indent2(std::ostream& os) const {
0141     char oldFill = os.fill();
0142     os << std::setfill(' ') << std::setw(startColumn2_) << "";
0143     os.fill(oldFill);
0144   }
0145 
0146   void DocFormatHelper::addCategory(std::string const& pluginCategory, std::string const& section) {
0147     pluginCategoriesAlreadyPrinted_.emplace_back(pluginCategory, section);
0148   }
0149 
0150   std::string DocFormatHelper::sectionOfCategoryAlreadyPrinted(std::string const& pluginCategory) const {
0151     auto iter = std::find_if(
0152         pluginCategoriesAlreadyPrinted_.begin(),
0153         pluginCategoriesAlreadyPrinted_.end(),
0154         [&pluginCategory](std::pair<std::string, std::string> const& elem) { return elem.first == pluginCategory; });
0155     if (iter == pluginCategoriesAlreadyPrinted_.end()) {
0156       return std::string();
0157     }
0158     return iter->second;
0159   }
0160 
0161 }  // namespace edm