00001
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
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
00073 if (pos - start > width)
00074 {
00075
00076 if (end == std::string::npos)
00077 end = start + width;
00078
00079 pos = end;
00080 print = true;
00081 }
00082 else if (pos - start == width)
00083 {
00084
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
00163
00164
00165
00166
00167
00168 #endif _DEBUG