TabularStream.cc
Go to the documentation of this file.
1 #include <map>
2 #include <algorithm>
3 #include <iterator>
4 #include <utl/String.h>
5 #include <utl/TabularStream.h>
6 
7 using namespace utl;
8 using namespace std;
9 
10 
11 string
12 TableCell::GetEntry(const Justification just, const int totalSize,
13  const int leftSize, const char mid)
14  const
15 {
16  const int size = GetSize();
17  const int missing = totalSize - size;
18 
19  switch (just) {
20  case eFlushLeft:
21  return GetEntry(0, missing);
22  case eFlushRight:
23  return GetEntry(missing);
24  case eCenter:
25  {
26  const int half = missing/2;
27  return GetEntry(missing - half, half);
28  }
29  case eCharAligned:
30  {
31  const size_t pos = fEntry.str().find_first_of(mid);
32  const bool hasChar = (pos != string::npos);
33  if (hasChar) {
34  const int leftPad = leftSize - pos;
35  const int rightPad = totalSize - (leftPad + size);
36  return GetEntry(leftPad, rightPad);
37  } else {
38  const string& str = fEntry.str();
39  const bool isAlpha =
40  (str.find_first_not_of(" +-0123456789eE.") != string::npos);
41  if (isAlpha)
42  return GetEntry(eCenter, totalSize);
43  else {
44  const size_t posE = str.find_first_of("eE");
45  bool hasE = (posE != string::npos);
46  if (hasE)
47  return GetEntry(just, totalSize, leftSize, str.at(posE));
48  else {
49  const int leftPad = leftSize - size;
50  const int rightPad = totalSize - leftSize;
51  return GetEntry(leftPad, rightPad);
52  }
53  }
54  }
55  }
56  default:
57  return string("TableCell::GetEntry ERROR");
58  }
59 }
60 
61 
62 pair<int, int>
63 TableCell::GetSize(const char mid)
64  const
65 {
66  const int size = GetSize();
67  const size_t pos = fEntry.str().find_first_of(mid);
68  if (pos != string::npos)
69  return make_pair(size, pos);
70  else {
71  // is it a number?
72  const bool isAlpha =
73  (fEntry.str().find_first_not_of(" +-0123456789eE.") != string::npos);
74  if (isAlpha)
75  return make_pair(size, size/2);
76  else {
77  const size_t posE = fEntry.str().find_first_of("eE");
78  bool hasE = (posE != string::npos);
79  if (hasE)
80  return GetSize(fEntry.str().at(posE));
81  else
82  return make_pair(size, size);
83  }
84  }
85 }
86 
87 
88 string
90 {
91  if (fWidth < 0)
92  CalculateWidths();
93 
94  TableCell& c = fCells.back();
95  string res;
96  const string entry = c.GetEntry();
97  if (entry.size() && entry.at(0) == '\r') {
98  const char symbol = entry.at(1);
99  if (symbol != '-')
100  res = string(fWidth + fPrefix.size() + fPostfix.size(), symbol);
101  else {
102  for (unsigned int i = 0; i < fPrefix.size(); ++i)
103  res += (fPrefix.at(i) == '|') ? '+' : symbol;
104  res += string(fWidth, symbol);
105  for (unsigned int i = 0; i < fPostfix.size(); ++i)
106  res += (fPostfix.at(i) == '|') ? '+' : symbol;
107  }
108  } else
109  res = fPrefix +
110  (fJustification == TableCell::eCharAligned ?
111  fCells.back().GetEntry(fJustification, fWidth, fLeftWidth, fMidChar) :
112  fCells.back().GetEntry(fJustification, fWidth)) +
113  fPostfix;
114  fCells.pop_back();
115  return res;
116 }
117 
118 
119 void
121 {
122  fWidth = 0;
123  if (fJustification != TableCell::eCharAligned)
124  for (deque<TableCell>::const_iterator cIt = fCells.begin();
125  cIt != fCells.end(); ++cIt) {
126  const int size = cIt->GetSize();
127  if (size > fWidth)
128  fWidth = size;
129  }
130  else {
131  fLeftWidth = 0;
132  int rightWidth = 0;
133  for (deque<TableCell>::const_iterator cIt = fCells.begin();
134  cIt != fCells.end(); ++cIt) {
135  const pair<int, int> size = cIt->GetSize(fMidChar);
136  const int right = size.first - size.second;
137  if (right > rightWidth)
138  rightWidth = right;
139  if (size.second > fLeftWidth)
140  fLeftWidth = size.second;
141  }
142  fWidth = fLeftWidth + rightWidth;
143  }
144 }
145 
146 
147 void
148 TabularStream::MakeFormat(const string& format)
149 {
150  map<char, TableCell::Justification> justMap;
151  justMap['l'] = TableCell::eFlushLeft;
152  justMap['c'] = TableCell::eCenter;
153  justMap['r'] = TableCell::eFlushRight;
154  justMap['.'] = TableCell::eCharAligned;
155 
156  const int n = format.size();
157  string str;
158  string pstr;
159  for (int i = 0; i < n; ++i) {
160  const char c = format.at(i);
161  switch (c) {
162  case 'l':
163  case 'c':
164  case 'r':
165  case '.':
166  fColumns.push_back(TableColumn());
167  if (c == '.')
168  fColumns.back().SetJustification(justMap[c], c);
169  else
170  fColumns.back().SetJustification(justMap[c]);
171  fColumns.back().SetMargins(str);
172  pstr = str;
173  str = "";
174  break;
175  default:
176  str += c;
177  break;
178  }
179  }
180  fColumns.back().SetMargins(pstr, str);
181 }
182 
183 
184 string
186 {
187  ostringstream os;
188  const int nRows = fColumns.front().GetLength();
189  for (int i = 0; i < nRows; ++i) {
190  if (i)
191  os << '\n';
192  for (Columns::iterator cIt = fColumns.begin();
193  cIt != fColumns.end(); ++cIt)
194  os << cIt->Pop();
195  }
196 
197  return os.str();
198 }
Holds TabularStream cell entry.
Definition: TabularStream.h:18
std::string Pop()
int GetSize() const
Definition: TabularStream.h:42
std::string Str()
std::string GetEntry(const int left=0, const int right=0) const
Definition: TabularStream.h:36
void MakeFormat(const std::string &format)

, generated on Tue Sep 26 2023.