mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
textTable.hpp
Go to the documentation of this file.
1 /** \file textTable.hpp
2  * \brief declares and defines a simple text table manager
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup asciiutils
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
12 //
13 // This file is part of mxlib.
14 //
15 // mxlib is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // mxlib is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
27 //***********************************************************************//
28 
29 #ifndef textTable_hpp
30 #define textTable_hpp
31 
32 #include <string>
33 #include <sstream>
34 
35 #include "../mxlib.hpp"
36 
37 #include "stringUtils.hpp"
38 
39 /// The mxlib c++ namespace
40 namespace mx
41 {
42 namespace ioutils
43 {
44 
45 /** \addtogroup asciiutils
46  * @{
47  */
48 
49 ///An ascii table formatter
50 /** Manages a table of string content, including word-wrapping within cells.
51  * Contents are output to an ostream line by line with a table structure.
52  *
53  * \todo have ability to add whole row, with a variadic template to handle different types
54  * \todo allow non-wrapping (i.e. unlimited width) columns
55  * \todo headers and footers
56  * \todo add centering (h and v) and right and bottom justification
57  * \todo have a latex() setup function
58  * \todo add sort capability, with vector of column choices to sort first by column N, then M, etc.
59  */
60 struct textTable
61 {
62  std::vector<int> m_colWidths; ///< The widths of each column, not including the separator.
63 
64  ///The table cells.
65  /** Organized as rows.cells.lines, where a cell could be multiple lines.
66  */
67  std::vector<std::vector<std::vector<std::string>>> m_rows;
68 
69  std::string m_lineStart; ///< Text to print at the beginning of the line.
70 
71  std::string m_lineEnd; ///< Text to print at the end of the line.
72 
73  std::string m_colSep; ///< Text to print between each column.
74 
75  std::string m_rowSep; ///< Text to print between each row.
76 
77  ///Add one cell to the table, overwriting if it already exists.
78  void addCell( size_t row, ///< [in] the row of the cell.
79  size_t col, ///< [in] the column of the cell.
80  const std::string & cell ///< [in] the new contents of the cell, will be wrapped.
81  );
82 
83  void addCell( size_t row, ///< [in] the row of the cell.
84  size_t col, ///< [in] the column of the cell.
85  const char * cell ///< [in] the new contents of the cell, will be wrapped.
86  );
87 
88  ///Add one cell to the table, overwriting if it already exists.
89  template<typename typeT>
90  void addCell( size_t row, ///< [in] the row of the cell.
91  size_t col, ///< [in] the column of the cell.
92  const typeT & cell, ///< [in] the new contents of the cell, will be wrapped.
93  int precision=0
94  );
95 
96  ///Output the table to a stream
97  /** Prints the table to the stream, with separators, etc.
98  *
99  * \tparam iosT is a std::ostream-like type.
100  */
101  template<typename iosT>
102  void outPut( iosT & ios /**< [in] a std::ostream-like stream.*/ );
103 
104 };
105 
106 template<typename typeT>
107 void textTable::addCell(size_t row,
108  size_t col,
109  const typeT & cell,
110  int precision
111  )
112 {
113  addCell(row, col, convertToString<typeT>(cell, precision));
114 }
115 
116 template<typename iosT>
117 void textTable::outPut( iosT & ios )
118 {
119  std::string line;
120 
121  size_t width = 0;
122  for(size_t i=0;i<m_colWidths.size();++i) width += m_colWidths[i];
123  width += m_colWidths.size()*(m_colSep.length()-1); //+100;
124 
125  line.resize(width, ' ');
126 
127  for(size_t i=0; i< m_rows.size(); ++i)
128  {
129  size_t rowL = 0;
130  for(size_t j=0; j< m_colWidths.size(); ++j)
131  {
132  if( m_rows[i][j].size() > rowL ) rowL = m_rows[i][j].size();
133  }
134 
135  for(size_t k=0; k< rowL; ++k)
136  {
137  //line.insert( 0, line.length(), ' ');
138  line.clear();
139  line.resize(width, ' ');
140  //line.replace(0, width, width, ' ');
141 
142  size_t startPos = 0;
143  for(size_t j=0; j< m_colWidths.size(); ++j)
144  {
145  if(m_rows[i][j].size() > k) line.replace(startPos, m_rows[i][j][k].length(), m_rows[i][j][k]);
146  startPos += m_colWidths[j];
147 
148  if( j < m_colWidths.size()-1) line.replace(startPos, m_colSep.length(), m_colSep);
149  startPos += m_colSep.length();
150 
151  }
152 
153  ios << m_lineStart << line << m_lineEnd << "\n";
154  }
155 
156  if(m_rowSep.length() > 0) ios << m_rowSep << "\n";
157 
158  }
159 }
160 
161 extern template
162 void textTable::outPut<std::ostream>(std::ostream & ios);
163 
164 /// @}
165 
166 } //namespace ioutils
167 } //namespace mx
168 
169 #endif //textTable_hpp
void outPut(iosT &ios)
Output the table to a stream.
Definition: textTable.hpp:117
constexpr units::realT k()
Boltzmann Constant.
Definition: constants.hpp:71
The mxlib c++ namespace.
Definition: mxError.hpp:107
Utilities for working with strings.
An ascii table formatter.
Definition: textTable.hpp:61
std::string m_lineStart
Text to print at the beginning of the line.
Definition: textTable.hpp:69
std::vector< int > m_colWidths
The widths of each column, not including the separator.
Definition: textTable.hpp:62
std::string m_rowSep
Text to print between each row.
Definition: textTable.hpp:75
void addCell(size_t row, size_t col, const std::string &cell)
Add one cell to the table, overwriting if it already exists.
Definition: textTable.cpp:36
std::string m_lineEnd
Text to print at the end of the line.
Definition: textTable.hpp:71
std::string m_colSep
Text to print between each column.
Definition: textTable.hpp:73
std::vector< std::vector< std::vector< std::string > > > m_rows
The table cells.
Definition: textTable.hpp:67