Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

#include "FWCore/ParameterSet/interface/DocFormatHelper.h"

#include <algorithm>
#include <ostream>
#include <iomanip>

namespace edm {

  namespace {
    void wrapAndPrintLine(std::ostream& os, std::string const& text, size_t indent, size_t suggestedWidth) {
      char oldFill = os.fill();

      size_t length = text.size();

      // The position in the text where we start printing the next line
      size_t startLine = 0U;

      // The position in the text where we start looking for the next blank space
      size_t startNextSearch = 0U;

      // Loop over spaces in the text
      while (true) {
        // If the rest of the text fits on the current line,
        // then print it and we are done
        if ((length - startLine) <= suggestedWidth) {
          os << std::setfill(' ') << std::setw(indent) << "";
          if (startLine == 0)
            os << text;
          else
            os << text.substr(startLine);
          os << "\n";
          break;
        }

        // Look for next space
        size_t pos = text.find_first_of(' ', startNextSearch);

        // No more spaces
        if (pos == std::string::npos) {
          // The rest of the comment cannot fit in the width or we
          // would have already printed it.  Break the line at the
          // end of the previous word if there is one and print the
          // first part.  Then print the rest whether it fits or not.
          if (startNextSearch != startLine) {
            os << std::setfill(' ') << std::setw(indent) << "";
            os << text.substr(startLine, startNextSearch - startLine);
            os << "\n";
            startLine = startNextSearch;
          }
          os << std::setfill(' ') << std::setw(indent) << "";
          os << text.substr(startLine);
          os << "\n";
          break;
        }

        if ((pos + 1U - startLine) > suggestedWidth) {
          // With this word the line is too long.  Print out to
          // the end of the previous word if there was one.
          // If there was not, then print to the end of this word
          // even though it exceeds the width.
          if (startNextSearch != startLine) {
            os << std::setfill(' ') << std::setw(indent) << "";
            os << text.substr(startLine, startNextSearch - startLine);
            os << "\n";
            startLine = startNextSearch;
          }
          if ((pos + 1U - startLine) > suggestedWidth) {
            os << std::setfill(' ') << std::setw(indent) << "";
            os << text.substr(startLine, pos + 1U - startLine);
            os << "\n";
            startLine = pos + 1U;
          }
        }
        startNextSearch = pos + 1U;
      }
      os.fill(oldFill);
    }
  }  // namespace

  // Print and wrap text to an output stream.
  // This function looks for new line chars in the text,
  // and calls wrapAndPrintLine() to output each line,
  // which wraps appropriately.  That function
  // inserts new lines to try to break the text to fit into
  // the suggested width.  At the beginning and after every
  // inserted newline this will print "indent" blank spaces.
  // The function will consider inserting a new line after
  // every blank space.  If the text to the next blank
  // space will exceed the "suggestedWidth" it inserts a
  // new line.  If the text between two blank spaces (a "word")
  // is longer than the suggested width, then it prints the whole
  // word anyway (exceeding the "suggestedWidth" for lines).
  // The output will look nice if the input has words separated
  // by a single blank space with no extra space in the input text,
  // otherwise the extra spaces and newlines get printed
  // making the output not nicely formatted ...
  void DocFormatHelper::wrapAndPrintText(std::ostream& os,
                                         std::string const& text,
                                         size_t indent,
                                         size_t suggestedWidth) {
    size_t pos = text.find_first_of('\n');
    if (pos == std::string::npos) {
      // no embedded newlines
      wrapAndPrintLine(os, text, indent, suggestedWidth);
    } else {
      // print the first line.
      wrapAndPrintLine(os, text.substr(0, pos), indent, suggestedWidth);
      // print all lines after the first.
      wrapAndPrintText(os, text.substr(pos + 1), indent, suggestedWidth);
    }
  }

  void DocFormatHelper::init() {
    section_ = std::string();
    pass_ = 0;
    column1_ = 0;
    column2_ = 0;
    column3_ = 0;
    counter_ = 0;
    parent_ = OTHER;
  }

  size_t DocFormatHelper::commentWidth() const {
    // Make the length of a comment at least 30 characters
    // per line, longer if there is more space available
    size_t width = 30U;
    if (lineWidth() > startColumn2() + 30U) {
      width = lineWidth() - startColumn2();
    }
    return width;
  }

  void DocFormatHelper::indent(std::ostream& os) const {
    char oldFill = os.fill();
    os << std::setfill(' ') << std::setw(indentation_) << "";
    os.fill(oldFill);
  }

  void DocFormatHelper::indent2(std::ostream& os) const {
    char oldFill = os.fill();
    os << std::setfill(' ') << std::setw(startColumn2_) << "";
    os.fill(oldFill);
  }

  void DocFormatHelper::addCategory(std::string const& pluginCategory, std::string const& section) {
    pluginCategoriesAlreadyPrinted_.emplace_back(pluginCategory, section);
  }

  std::string DocFormatHelper::sectionOfCategoryAlreadyPrinted(std::string const& pluginCategory) const {
    auto iter = std::find_if(
        pluginCategoriesAlreadyPrinted_.begin(),
        pluginCategoriesAlreadyPrinted_.end(),
        [&pluginCategory](std::pair<std::string, std::string> const& elem) { return elem.first == pluginCategory; });
    if (iter == pluginCategoriesAlreadyPrinted_.end()) {
      return std::string();
    }
    return iter->second;
  }

}  // namespace edm