File indexing completed on 2025-01-18 10:01:40
0001
0002
0003
0004
0005
0006 #pragma once
0007 #include <string>
0008 #include <vector>
0009 #include <iostream>
0010 #include <iomanip>
0011 #include <sstream>
0012
0013 class JTablePrinter {
0014
0015 int current_column = 0;
0016 int current_row = 0;
0017
0018 public:
0019
0020 enum class Justify {Left, Center, Right};
0021 enum class RuleStyle {Across, Broken, None};
0022
0023 struct Column {
0024 std::string header;
0025 std::vector<std::string> values;
0026 Justify justify = Justify::Left;
0027 int desired_width;
0028 int contents_width;
0029 bool use_desired_width = false;
0030 };
0031
0032 std::string title;
0033 std::vector<Column> columns;
0034 RuleStyle top_rule = RuleStyle::Across;
0035 RuleStyle header_rule = RuleStyle::Broken;
0036 RuleStyle bottom_rule = RuleStyle::Across;
0037
0038 int indent = 2;
0039 int cell_margin = 2;
0040 bool vertical_padding = 0;
0041
0042 JTablePrinter::Column& AddColumn(std::string header, Justify justify=Justify::Left, int desired_width=0);
0043 void FormatLine(std::ostream& os, std::string contents, int max_width, Justify justify) const;
0044 void Render(std::ostream& os) const;
0045 std::string Render() const;
0046 static std::vector<std::string> SplitContents(std::string contents, size_t max_width);
0047 static std::vector<std::string> SplitContentsByNewlines(std::string contents);
0048 static std::vector<std::string> SplitContentsBySpaces(std::string contents, size_t max_width);
0049
0050 template <typename T> JTablePrinter& operator|(T);
0051
0052
0053 };
0054
0055 std::ostream& operator<<(std::ostream& os, const JTablePrinter& t);
0056
0057 template <typename T>
0058 JTablePrinter& JTablePrinter::operator|(T cell) {
0059 std::ostringstream ss;
0060 ss << cell;
0061 return (*this) | ss.str();
0062 }
0063
0064 template <>
0065 inline JTablePrinter& JTablePrinter::operator|(std::string cell) {
0066 auto len = cell.size();
0067 auto& col = columns[current_column];
0068 if ((size_t) col.contents_width < len) {
0069 col.contents_width = len;
0070 }
0071 if (len > (size_t) col.desired_width && col.desired_width != 0) {
0072 vertical_padding = true;
0073
0074 }
0075 col.values.push_back(cell);
0076 current_column += 1;
0077 if ((size_t) current_column >= columns.size()) {
0078 current_column = 0;
0079 current_row += 1;
0080 }
0081 return *this;
0082 }
0083