From b6626cad302b86db9fdb490b36f680c47efaea86 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 21 Apr 2025 22:16:37 +1200 Subject: [PATCH] Correct column widths --- src/tableprint.cpp | 154 +++++++++++++++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 48 deletions(-) diff --git a/src/tableprint.cpp b/src/tableprint.cpp index eb81f65..5cfa66a 100644 --- a/src/tableprint.cpp +++ b/src/tableprint.cpp @@ -16,7 +16,11 @@ enum kTextColors { kTextColor_Yellow, kTextColor_Blue, kTextColor_Magenta, - kTextColor_Cyan + kTextColor_Cyan, + kTextColor_White, + kTextColor_DarkGrey, + kTextColor_DarkYellow, + kTextColor_LightGrey }; struct coloredText { @@ -42,47 +46,100 @@ std::string get_color_code(kTextColors color) { case kTextColor_Blue: return "\033[1;34m"; case kTextColor_Magenta: return "\033[1;35m"; case kTextColor_Cyan: return "\033[1;36m"; + case kTextColor_White: return "\033[1;37m"; + case kTextColor_DarkGrey: return "\033[90m"; + case kTextColor_DarkYellow: return "\033[38;5;142m"; + case kTextColor_LightGrey: return "\033[38;5;250m"; default: return "\033[0m"; } } -// Helper function to process a cell with replacements -std::string process_cell(const std::string& cell) { - std::string result; +int get_codepoints(const std::string& str) { + int num_code_points = 0; + for (char byte: str) { + if((byte & 0xC0) != 0x80) { + num_code_points++; + } + } + return num_code_points; +} + +int get_visible_length(const std::string& str) { + int length = get_codepoints(str); + size_t pos = 0; - while (pos < cell.length()) { + while (pos < str.length()) { + for (const auto& [key, value] : kReplacements) { + if (str.compare(pos, key.length(), key) == 0) { + length = length - get_codepoints(key) + get_codepoints(value.text); + pos += key.length(); + break; + } + } + pos++; + } + return length; +} + +std::string process_cell(std::string str,std::string rowcolor) { + std::string result; + + size_t pos = 0; + while (pos < str.length()) { bool found_replacement = false; for (const auto& [key, value] : kReplacements) { - if (cell.compare(pos, key.length(), key) == 0) { - result += get_color_code(value.color) + value.text + "\033[0m"; + if (str.compare(pos, key.length(), key) == 0) { + found_replacement = true; + result += get_color_code(value.color) + value.text + rowcolor; pos += key.length(); - found_replacement = true; break; } } if (!found_replacement) { - result += cell[pos]; + result += str[pos]; pos++; } } return result; } -// Helper function to get visible length (ignoring color codes) -size_t get_visible_length(const std::string& str) { - size_t length = 0; - bool in_color_code = false; - for (size_t i = 0; i < str.length(); ++i) { - if (str[i] == '\033') { - while (i < str.length() && str[i] != 'm') { - i++; - } - } else { - length++; - } - } - return length; -} +// // Helper function to process a cell with replacements +// std::string process_cell(const std::string& cell) { +// std::string result; +// size_t pos = 0; +// while (pos < cell.length()) { +// bool found_replacement = false; +// for (const auto& [key, value] : kReplacements) { +// if (cell.compare(pos, key.length(), key) == 0) { +// result += get_color_code(value.color) + value.text + "\033[0m"; +// pos += key.length(); +// found_replacement = true; +// break; +// } +// } +// if (!found_replacement) { +// result += cell[pos]; +// pos++; +// } +// } +// return result; +// } + +// // Helper function to get visible length (ignoring color codes) +// size_t get_visible_length(const std::string& str) { +// size_t length = 0; +// bool in_color_code = false; +// for (size_t i = 0; i < str.length(); ++i) { +// if (str[i] == '\033') { +// while (i < str.length() && str[i] != 'm') { +// i++; +// } +// } else { +// length++; +// } +// } +// return length; +// } tableprint::tableprint(const std::string title) : title(title) { // Set locale for wide character support @@ -113,21 +170,19 @@ void tableprint::add_row(const std::vector& row) { void tableprint::print() { if (rows.empty()) return; - // First, process all cells and store the processed versions - std::vector> processed_rows; - for (const auto& row : rows) { - std::vector processed_row; - for (const auto& cell : row) { - processed_row.push_back(process_cell(cell)); - } - processed_rows.push_back(processed_row); + // Calculate column widths based on header text + std::vector col_widths(rows[0].size(), 0); + for (size_t i = 0; i < rows[0].size(); ++i) { + col_widths[i] = rows[0][i].length(); } - // Calculate column widths based on processed cells (ignoring color codes) - std::vector col_widths(rows[0].size(), 0); - for (const auto& row : processed_rows) { + // Adjust widths for any cells with replacements + for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) { + const auto& row = rows[row_idx]; for (size_t i = 0; i < row.size(); ++i) { - col_widths[i] = std::max(col_widths[i], get_visible_length(row[i])); + int l = get_visible_length(row[i]); + if (l > col_widths[i]) + col_widths[i] = l; } } @@ -186,9 +241,9 @@ void tableprint::print() { // Print header std::cout << "│"; std::cout << "\033[1;36m"; // Cyan color for header - for (size_t i = 0; i < processed_rows[0].size(); ++i) { - std::cout << " " << std::setw(col_widths[i]) << std::left << processed_rows[0][i] << " "; - if (i < processed_rows[0].size() - 1) { + for (size_t i = 0; i < rows[0].size(); ++i) { + std::cout << " " << std::setw(col_widths[i]) << std::left << rows[0][i] << " "; + if (i < rows[0].size() - 1) { std::cout << "\033[90m│\033[1;36m"; // Border color then back to cyan } else { std::cout << "\033[90m│"; // Just border color for last column @@ -207,21 +262,24 @@ void tableprint::print() { std::cout << "┤" << std::endl; // Print rows - for (size_t row_idx = 1; row_idx < processed_rows.size(); ++row_idx) { - const auto& row = processed_rows[row_idx]; + for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) { + const auto& row = rows[row_idx]; std::cout << "│"; for (size_t i = 0; i < row.size(); ++i) { // Set the appropriate color for the row - if (row_idx % 2 == 1) { - std::cout << " " << "\033[38;5;142m" << std::setw(col_widths[i]) << std::left << row[i] << "\033[90m" << " │"; - } else { - std::cout << " " << "\033[38;5;250m" << std::setw(col_widths[i]) << std::left << row[i] << "\033[90m" << " │"; - } + std::string rowcolor = (row_idx % 2 == 1) ? "\033[38;5;142m" : "\033[38;5;250m"; + + std::cout << rowcolor; + std::string processed_cell = process_cell(row[i],rowcolor); + int l = get_visible_length(row[i]); + for (int i = l+1 ; i < col_widths[i]; i++) + processed_cell += " "; + std::cout << processed_cell << "\033[90m" << " │"; } std::cout << std::endl; // Print row separator if not the last row - if (row_idx < processed_rows.size() - 1) { + if (row_idx < rows.size() - 1) { std::cout << "├"; for (size_t i = 0; i < rows[0].size(); ++i) { for (size_t j = 0; j < col_widths[i] + 2; ++j) { @@ -242,4 +300,4 @@ void tableprint::print() { if (i < rows[0].size() - 1) std::cout << "┴"; } std::cout << "┘" << "\033[0m" << std::endl; // Reset color -} \ No newline at end of file +}