cmDocumentationFormatterText.cxx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmDocumentationFormatterText.h"
  14. #include "cmDocumentationSection.h"
  15. cmDocumentationFormatterText::cmDocumentationFormatterText()
  16. :cmDocumentationFormatter()
  17. ,TextWidth(77)
  18. ,TextIndent("")
  19. {
  20. }
  21. void cmDocumentationFormatterText
  22. ::PrintSection(std::ostream& os,
  23. const cmDocumentationSection &section,
  24. const char* name)
  25. {
  26. if(name)
  27. {
  28. os <<
  29. "---------------------------------------"
  30. "---------------------------------------\n";
  31. os << name << "\n\n";
  32. }
  33. const std::vector<cmDocumentationEntry> &entries =
  34. section.GetEntries();
  35. for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
  36. op != entries.end(); ++op)
  37. {
  38. if(op->Name.size())
  39. {
  40. os << " " << op->Name << "\n";
  41. this->TextIndent = " ";
  42. this->PrintFormatted(os, op->Brief.c_str());
  43. if(op->Full.size())
  44. {
  45. os << "\n";
  46. this->PrintFormatted(os, op->Full.c_str());
  47. }
  48. }
  49. else
  50. {
  51. this->TextIndent = "";
  52. this->PrintFormatted(os, op->Brief.c_str());
  53. }
  54. os << "\n";
  55. }
  56. }
  57. void cmDocumentationFormatterText::PrintPreformatted(std::ostream& os,
  58. const char* text)
  59. {
  60. bool newline = true;
  61. for(const char* ptr = text; *ptr; ++ptr)
  62. {
  63. if(newline)
  64. {
  65. os << this->TextIndent;
  66. newline = false;
  67. }
  68. os << *ptr;
  69. if(*ptr == '\n')
  70. {
  71. newline = true;
  72. }
  73. }
  74. os << "\n";
  75. }
  76. void cmDocumentationFormatterText::PrintParagraph(std::ostream& os,
  77. const char* text)
  78. {
  79. os << this->TextIndent;
  80. this->PrintColumn(os, text);
  81. os << "\n";
  82. }
  83. void cmDocumentationFormatterText::SetIndent(const char* indent)
  84. {
  85. this->TextIndent = indent;
  86. }
  87. void cmDocumentationFormatterText::PrintColumn(std::ostream& os,
  88. const char* text)
  89. {
  90. // Print text arranged in an indented column of fixed witdh.
  91. const char* l = text;
  92. int column = 0;
  93. bool newSentence = false;
  94. bool firstLine = true;
  95. int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));
  96. // Loop until the end of the text.
  97. while(*l)
  98. {
  99. // Parse the next word.
  100. const char* r = l;
  101. while(*r && (*r != '\n') && (*r != ' ')) { ++r; }
  102. // Does it fit on this line?
  103. if(r-l < (width-column-(newSentence?1:0)))
  104. {
  105. // Word fits on this line.
  106. if(r > l)
  107. {
  108. if(column)
  109. {
  110. // Not first word on line. Separate from the previous word
  111. // by a space, or two if this is a new sentence.
  112. if(newSentence)
  113. {
  114. os << " ";
  115. column += 2;
  116. }
  117. else
  118. {
  119. os << " ";
  120. column += 1;
  121. }
  122. }
  123. else
  124. {
  125. // First word on line. Print indentation unless this is the
  126. // first line.
  127. os << (firstLine?"":this->TextIndent);
  128. }
  129. // Print the word.
  130. os.write(l, static_cast<long>(r-l));
  131. newSentence = (*(r-1) == '.');
  132. }
  133. if(*r == '\n')
  134. {
  135. // Text provided a newline. Start a new line.
  136. os << "\n";
  137. ++r;
  138. column = 0;
  139. firstLine = false;
  140. }
  141. else
  142. {
  143. // No provided newline. Continue this line.
  144. column += static_cast<long>(r-l);
  145. }
  146. }
  147. else
  148. {
  149. // Word does not fit on this line. Start a new line.
  150. os << "\n";
  151. firstLine = false;
  152. if(r > l)
  153. {
  154. os << this->TextIndent;
  155. os.write(l, static_cast<long>(r-l));
  156. column = static_cast<long>(r-l);
  157. newSentence = (*(r-1) == '.');
  158. }
  159. else
  160. {
  161. column = 0;
  162. }
  163. }
  164. // Move to beginning of next word. Skip over whitespace.
  165. l = r;
  166. while(*l && (*l == ' ')) { ++l; }
  167. }
  168. }