Main Page | Class List | File List | Class Members | File Members

format_paragraph.cpp

Go to the documentation of this file.
00001 // format_paragraph.cpp
00002 
00003 #include "format_paragraph.h"
00004 #include "safe_assign.h"
00005 #include <locale>
00006 #include <iomanip>
00007 
00008 format_paragraph::format_paragraph(
00009   const char* str,
00010   int left_col,
00011   int right_col,
00012   bool indent_first_line)
00013 {
00014   safe_assign(m_text, str);
00015   m_left_col = left_col;
00016   m_right_col = right_col;
00017   m_indent_first_line = indent_first_line;
00018 }
00019 
00020 std::ostream& operator<< (std::ostream &os, const format_paragraph& fp)
00021 {
00022   if (
00023     fp.m_left_col > fp.m_right_col ||
00024     fp.m_left_col < 0 ||
00025     fp.m_right_col < 0 ||
00026     fp.m_text.empty()
00027   )
00028     return os;
00029   os << std::left << std::setw(0) << std::setfill(' ');
00030   std::locale loc = os.getloc();
00031   std::string::size_type width = fp.m_right_col - fp.m_left_col +1;
00032   std::string::size_type start, end;
00033   std::string::size_type pos = 0;
00034   bool first_line = true;
00035   while(pos < fp.m_text.size())
00036   {
00037     // Skip leading whitespace except linefeed
00038     while(pos <= fp.m_text.size())
00039     {
00040       if (pos < fp.m_text.size() &&
00041         std::isspace(fp.m_text[pos], loc) &&
00042         fp.m_text[pos] != '\n'
00043       )
00044         pos++;
00045       else
00046         break;
00047     }
00048     if (pos >= fp.m_text.size())
00049       break;
00050     start = pos;
00051     end = std::string::npos;
00052     bool print = false;
00053     while (!print)
00054     {
00055       bool is_space = false;
00056       bool is_linefeed = false;
00057       bool is_end = false;
00058       while(pos <= fp.m_text.size() && !is_space && !is_linefeed && !is_end)
00059       {
00060         if (pos < fp.m_text.size())
00061         {
00062           char c = fp.m_text[pos];
00063           is_space = std::isspace(c, loc);
00064           is_linefeed = (c == '\n');
00065           if (is_space || is_linefeed)
00066             break;
00067           pos++;
00068         }
00069         else
00070           is_end = true;
00071       }
00072       // white-space, linefeed or string end at pos here
00073       if (pos - start > width)
00074       {
00075         // print using last known end if available
00076         if (end == std::string::npos)
00077           end = start + width;
00078         // move pos back
00079         pos = end;
00080         print = true;
00081       }
00082       else if (pos - start == width)
00083       {
00084         // print until this position
00085         print = true;
00086         end = pos;
00087       }
00088       else if (is_linefeed)
00089       {
00090         end = pos;
00091         print = true;
00092         pos++;
00093       }
00094       else if (is_end)
00095       {
00096         end = pos;
00097         print = true;
00098       }
00099       else
00100       {
00101         end = pos;
00102         pos++;
00103       }
00104     }
00105     int indent = fp.m_left_col;
00106     if (first_line)
00107     {
00108       if (!fp.m_indent_first_line)
00109         indent = 0;
00110       first_line = false;
00111     }
00112     if (indent > 0)
00113       os << std::setw(indent) << " ";
00114     os << fp.m_text.substr(start, end - start) << std::endl;
00115   }
00116   return os;
00117 }
00118 
00119 #ifdef _DEBUG
00120 #include <iostream>
00121 void test_fp(const char* psz, int left, int right, bool indent_first_line)
00122 {
00123   std::cout << "left=" << left << ", right=" << right << ", indent=" << indent_first_line << std::endl;
00124   for (int i = 0; i <= right/10; ++i)
00125   {
00126     if (i > 0)
00127       std::cout << "        ";
00128     std::cout << std::right << std::setfill('0') << std::setw(2) << i;
00129   }
00130   std::cout << std::endl;
00131   int pos = 0;
00132   for (i = 0; i <= right; ++i)
00133   {
00134     std::cout << pos;
00135     pos++;
00136     if (pos > 9)
00137       pos = 0;
00138   }
00139   std::cout << std::endl;
00140   std::cout << format_paragraph(psz, left, right, indent_first_line);
00141   std::cout << "--" << std::endl;
00142 }
00143 
00144 void test_format_paragraph()
00145 {
00146   const char* pszText = "This is a test of format_paragraph, which may be successful or otherwise disappointing to see. "
00147     "Ending line here.\n"
00148     "And continuing with more text. "
00149     "Several lines ending here.\n\n"
00150     "Text again.";
00151   test_fp("Spaces here.\n This is  a test. ", 0, 15, true);
00152   test_fp("Spaces here.    This is  a test.", 0, 15, true);
00153   test_fp(pszText, 0, 15, true);
00154   test_fp(pszText, 2, 15, true);
00155   test_fp(pszText, 2, 16, true);
00156   test_fp(pszText, 2, 78, true);
00157   test_fp(pszText, 2, 78, false);
00158   
00159 }
00160 
00161 /*
00162 void main()
00163 {
00164   test_format_paragraph();
00165 }
00166 */
00167 
00168 #endif _DEBUG

Generated on Sun Jun 26 13:43:46 2005 for pingem by  doxygen 1.4.3