File indexing completed on 2025-01-18 10:17:37
0001
0002
0003
0004
0005
0006 #include "JTablePrinter.h"
0007 #include "JANA/JLogger.h"
0008
0009 std::vector<std::string> JTablePrinter::SplitContents(std::string contents, size_t max_width) {
0010 auto split_by_newlines = SplitContentsByNewlines(contents);
0011 if (max_width == 0) return split_by_newlines;
0012
0013 std::vector<std::string> results;
0014 for (auto& s: split_by_newlines) {
0015 auto split_by_spaces = SplitContentsBySpaces(s, max_width);
0016 for (auto& ss : split_by_spaces) {
0017 results.push_back(ss);
0018 }
0019 }
0020 return results;
0021 }
0022
0023 std::vector<std::string> JTablePrinter::SplitContentsByNewlines(std::string contents) {
0024 std::vector<std::string> split_by_newlines;
0025 size_t contents_width = contents.size();
0026 size_t line_start = 0;
0027 size_t line_end = line_start;
0028 while (line_end < contents_width) {
0029 if (contents[line_end] == '\n') {
0030 split_by_newlines.push_back(contents.substr(line_start, line_end - line_start));
0031 line_start = line_end + 1;
0032 line_end = line_start;
0033 }
0034 line_end += 1;
0035 }
0036 split_by_newlines.push_back(contents.substr(line_start, contents_width - line_start));
0037 return split_by_newlines;
0038 }
0039
0040 std::vector<std::string> JTablePrinter::SplitContentsBySpaces(std::string contents, size_t max_width) {
0041
0042 std::vector<std::string> split_by_spaces;
0043 if (contents.size() <= max_width) {
0044 split_by_spaces.push_back(contents);
0045 return split_by_spaces;
0046 }
0047
0048 size_t split_start = 0;
0049 size_t split_end = 0;
0050 size_t contents_end = contents.size();
0051 for (size_t i = 0; i < contents_end; ++i) {
0052 if (contents[i] == ' ') {
0053
0054 split_end = i;
0055
0056 }
0057 if (i - split_start == max_width) {
0058
0059 if (split_end == split_start) {
0060 split_by_spaces.push_back(contents.substr(split_start, i - split_start));
0061
0062 split_start = i;
0063 split_end = i;
0064
0065 }
0066 else {
0067 split_by_spaces.push_back(contents.substr(split_start, split_end - split_start));
0068
0069 split_start = split_end + 1;
0070 split_end = split_start;
0071
0072 }
0073 }
0074 }
0075 split_end = contents_end;
0076
0077
0078 split_by_spaces.push_back(contents.substr(split_start, split_end - split_start));
0079
0080 return split_by_spaces;
0081 }
0082
0083 JTablePrinter::Column& JTablePrinter::AddColumn(std::string header, Justify justify, int desired_width) {
0084 columns.emplace_back();
0085 Column& col = columns.back();
0086 col.header = std::move(header);
0087 col.contents_width = col.header.size();
0088 col.justify = justify;
0089 col.desired_width = desired_width;
0090 col.use_desired_width = (desired_width != 0);
0091 return col;
0092 }
0093
0094
0095 void JTablePrinter::FormatLine(std::ostream& os, std::string contents, int max_width, Justify justify) const {
0096 auto cs = contents.size();
0097
0098 if (justify == Justify::Left) {
0099 os << std::left << std::setw(max_width) << contents;
0100 }
0101 else if (justify == Justify::Right) {
0102 os << std::right << std::setw(max_width) << contents;
0103 }
0104 else {
0105 int lpad = (max_width-cs)/2;
0106 int rpad = (max_width-cs) - lpad;
0107 for (int i=0; i<lpad; ++i) os << " ";
0108 os << contents;
0109 for (int i=0; i<rpad; ++i) os << " ";
0110 }
0111 }
0112 std::string JTablePrinter::Render() const {
0113 std::ostringstream ss;
0114 Render(ss);
0115 return ss.str();
0116 }
0117
0118 void JTablePrinter::Render(std::ostream& os) const {
0119
0120
0121 int table_width = 0;
0122 for (const Column& col : columns) {
0123 table_width += col.use_desired_width ? col.desired_width : col.contents_width;
0124 }
0125 table_width += (columns.size()-1)*cell_margin;
0126
0127
0128 if (top_rule == RuleStyle::Broken) {
0129 for (int i = 0; i<indent; ++i) os << " ";
0130 for (const auto& col : columns) {
0131 int underline_len = (col.use_desired_width)?col.desired_width:col.contents_width;
0132 for (int i=0; i<underline_len; ++i) os << "-";
0133 for (int i=0; i<cell_margin; ++i) os << " ";
0134 }
0135 os << std::endl;
0136 }
0137 else if (top_rule == RuleStyle::Across) {
0138 for (int i = 0; i<indent; ++i) os << " ";
0139 for (int i=0; i<table_width; ++i) os << "-";
0140 os << std::endl;
0141 }
0142
0143
0144 for (int i = 0; i<indent; ++i) os << " ";
0145 for (const auto& col : columns) {
0146
0147 FormatLine(os, col.header, col.use_desired_width ? col.desired_width : col.contents_width, Justify::Center);
0148 for (int i=0; i<cell_margin; ++i) os << " ";
0149 }
0150 os << std::endl;
0151
0152
0153 if (header_rule == RuleStyle::Across) {
0154 for (int i = 0; i<indent; ++i) os << " ";
0155 for (int i = 0; i<table_width; ++i) os << "-";
0156 os << std::endl;
0157 }
0158 else if (header_rule == RuleStyle::Broken) {
0159 for (int i = 0; i<indent; ++i) os << " ";
0160 for (const auto& col : columns) {
0161 int underline_len = (col.use_desired_width)?col.desired_width:col.contents_width;
0162 for (int i=0; i<underline_len; ++i) os << "-";
0163 for (int i=0; i<cell_margin; ++i) os << " ";
0164 }
0165 os << std::endl;
0166 }
0167
0168
0169 for (int row = 0; row < current_row; ++row) {
0170 std::vector<std::vector<std::string>> lines;
0171 size_t line_count = 1;
0172 for (const auto& col : columns) {
0173 auto split = SplitContents(col.values[row], col.desired_width);
0174 lines.push_back(split);
0175 if (split.size() > line_count) line_count = split.size();
0176 }
0177 if (vertical_padding) line_count += 1;
0178
0179 for (size_t line=0; line < line_count; ++line) {
0180 for (int i = 0; i<indent; ++i) os << " ";
0181
0182 size_t col_count = columns.size();
0183 for (size_t col = 0; col < col_count; ++col) {
0184 auto& column = columns[col];
0185 if (line < lines[col].size()) {
0186 FormatLine(os, lines[col][line], column.use_desired_width ? column.desired_width : column.contents_width, column.justify);
0187 }
0188 else {
0189 FormatLine(os, "", column.use_desired_width ? column.desired_width : column.contents_width, column.justify);
0190 }
0191 for (int i=0; i<cell_margin; ++i) os << " ";
0192 }
0193 os << std::endl;
0194
0195 }
0196 }
0197
0198
0199 if (bottom_rule == RuleStyle::Broken) {
0200 for (int i = 0; i<indent; ++i) os << " ";
0201 for (const auto& col : columns) {
0202 int underline_len = (col.use_desired_width)?col.desired_width:col.contents_width;
0203 for (int i=0; i<underline_len; ++i) os << "-";
0204 for (int i=0; i<cell_margin; ++i) os << " ";
0205 }
0206 os << std::endl;
0207 }
0208 else if (bottom_rule == RuleStyle::Across) {
0209 for (int i = 0; i<indent; ++i) os << " ";
0210 for (int i = 0; i<table_width; ++i) os << "-";
0211 os << std::endl;
0212 }
0213 }
0214
0215 std::ostream& operator<<(std::ostream& os, const JTablePrinter& t) {
0216 t.Render(os);
0217 return os;
0218 }
0219