From 056b56c54d7b34111db7c2a52a93290d3797b49c Mon Sep 17 00:00:00 2001 From: jlmolinero Date: Wed, 15 Nov 2023 01:28:41 +0100 Subject: [PATCH] =?UTF-8?q?=C3=83=C2=A7Color=20functionality=20to=20the=20?= =?UTF-8?q?code.=20The=20user=20only=20need=20to=20add=20color=20substring?= =?UTF-8?q?=20to=20the=20text=20in=20cell,=20with=20a=20bash=20format.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Examples and guide: https://misc.flogisoft.com/bash/tip_colors_and_formatting --- ConsoleTable.cpp | 71 ++++++++++++++++++++++++++++++------------------ ConsoleTable.h | 31 ++++++++++++++++----- README.md | 25 +++++++++++++++-- main.cpp | 14 +++++----- 4 files changed, 98 insertions(+), 43 deletions(-) diff --git a/ConsoleTable.cpp b/ConsoleTable.cpp index b5aceb0..2027654 100644 --- a/ConsoleTable.cpp +++ b/ConsoleTable.cpp @@ -1,13 +1,12 @@ #include "ConsoleTable.h" -ConsoleTable::ConsoleTable(std::initializer_list headers) : headers{headers} { +ConsoleTable::ConsoleTable(const std::initializer_list headers) : headers{headers} { for (const auto &column : headers) { widths.push_back(column.length()); } } - void ConsoleTable::setPadding(unsigned int n) { padding = n; } @@ -15,25 +14,24 @@ void ConsoleTable::setPadding(unsigned int n) { void ConsoleTable::setStyle(unsigned int n) { switch (n) { - case 0 : - style = BasicStyle; - break; - case 1 : - style = LineStyle; - break; - case 2 : - style = DoubleLineStyle; - break; - case 3 : - style = InvisibleStyle; - break; - default : - style = BasicStyle; - break; + case 0 : + style = BasicStyle; + break; + case 1 : + style = LineStyle; + break; + case 2 : + style = DoubleLineStyle; + break; + case 3 : + style = InvisibleStyle; + break; + default : + style = BasicStyle; + break; } } - bool ConsoleTable::addRow(std::initializer_list row) { if (row.size() > widths.size()) { throw std::invalid_argument{"Appended row size must be same as header size"}; @@ -42,7 +40,7 @@ bool ConsoleTable::addRow(std::initializer_list row) { auto r = std::vector{row}; rows.push_back(r); for (unsigned int i = 0; i < r.size(); ++i) { - widths[i] = std::max(r[i].size(), widths[i]); + widths[i] = std::max(r[i].size() - searchColor(r[i]), widths[i]); } return true; } @@ -75,7 +73,6 @@ ConsoleTable &ConsoleTable::operator-=(const uint32_t rowIndex) { return *this; } - std::string ConsoleTable::getLine(RowType rowType) const { std::stringstream line; line << rowType.left; @@ -89,7 +86,7 @@ std::string ConsoleTable::getLine(RowType rowType) const { } -std::string ConsoleTable::getHeaders(Headers headers) const { +std::string ConsoleTable::getHeaders(const Headers &headers) const { std::stringstream line; line << style.vertical; for (unsigned int i = 0; i < headers.size(); ++i) { @@ -102,13 +99,13 @@ std::string ConsoleTable::getHeaders(Headers headers) const { } -std::string ConsoleTable::getRows(Rows rows) const { +std::string ConsoleTable::getRows(const Rows &rows) const { std::stringstream line; - for (auto &row : rows) { + for (const auto &row : rows) { line << style.vertical; for (unsigned int j = 0; j < row.size(); ++j) { std::string text = row[j]; - line << SPACE_CHARACTER * padding + text + SPACE_CHARACTER * (widths[j] - text.length()) + SPACE_CHARACTER * padding; + line << SPACE_CHARACTER * padding + text + SPACE_CHARACTER * (widths[j] - text.length() + searchColor(text)) + SPACE_CHARACTER * padding; line << style.vertical; } line << "\n"; @@ -135,7 +132,7 @@ bool ConsoleTable::sort(bool ascending) { return true; } -void ConsoleTable::updateRow(unsigned int row, unsigned int header, std::string data) { +void ConsoleTable::updateRow(unsigned int row, unsigned int header, const std::string &data) { if (row > rows.size() - 1) throw std::out_of_range{"Row index out of range."}; if (header > headers.size() - 1) @@ -144,13 +141,25 @@ void ConsoleTable::updateRow(unsigned int row, unsigned int header, std::string rows[row][header] = data; } -void ConsoleTable::updateHeader(unsigned int header, std::string text) { +void ConsoleTable::updateHeader(unsigned int header, const std::string &text) { if (header > headers.size()) throw std::out_of_range{"Header index out of range."}; headers[header] = text; } +size_t ConsoleTable::searchColor(const std::string &text) const{ + size_t pos = text.find(COLOR_INITIATOR_CHARACTER,0); + size_t counter = 0; + if (pos != std::string::npos){ + counter = countCharacters(counter, pos, text, COLOR_FINAL_CHARACTER); + size_t rpos = text.rfind("\e"); + if (rpos != std::string::npos && rpos > pos) + counter = countCharacters(counter, rpos, text, COLOR_FINAL_CHARACTER); + return counter; + } + return counter; +} std::string operator*(const std::string &other, int repeats) { std::string ret; @@ -159,3 +168,13 @@ std::string operator*(const std::string &other, int repeats) { ret.append(other); return ret; } + +size_t countCharacters(size_t counter, size_t pos,const std::string &text, char characterBreaker){ + counter++; + for(size_t i = pos; i < text.length(); i++){ + if(text[i] == characterBreaker) + break; + counter++; + } + return counter; +} diff --git a/ConsoleTable.h b/ConsoleTable.h index ddd3903..98b563d 100644 --- a/ConsoleTable.h +++ b/ConsoleTable.h @@ -6,7 +6,7 @@ #include #include #include - +#include class ConsoleTable { public: @@ -17,7 +17,7 @@ class ConsoleTable { /// Initialize a new ConsoleTable /// \param headers Stringlist of the tables headers - ConsoleTable(std::initializer_list headers); + ConsoleTable(const std::initializer_list headers); /// Sets the distance from the text to the cell border @@ -56,13 +56,13 @@ class ConsoleTable { /// \param row The index of the row that needs to be updated /// \param header The index of the column that needs to be updated /// \param data The new data that should be assigned to teh cell - void updateRow(unsigned int row, unsigned int header, std::string data); + void updateRow(unsigned int row, unsigned int header,const std::string &data); /// Update a header with new text /// \param header Index of the header that should be updated /// \param text The new teext of the new header - void updateHeader(unsigned int header, std::string text); + void updateHeader(unsigned int header,const std::string &text); /// Operator of the addRow() function @@ -130,6 +130,11 @@ class ConsoleTable { /// Space character constant const std::string SPACE_CHARACTER = " "; + /// Color initiator character constant + const std::string COLOR_INITIATOR_CHARACTER = "\e"; + + /// Color final character constant + const char COLOR_FINAL_CHARACTER = 'm'; /// The distance between the cell text and the cell border unsigned int padding = 1; @@ -144,13 +149,13 @@ class ConsoleTable { /// Returns a formatted header string /// \param headers The Headers-object that holds the header strings /// \return The formatted header string - std::string getHeaders(Headers headers) const; + std::string getHeaders(const Headers &headers) const; /// Returns a formmatted row string /// \param rows The Rows-object that holds all rows of the table /// \return A formatted string of all rows in the table - std::string getRows(Rows rows) const; + std::string getRows(const Rows &rows) const; /// Writes the entire table with all its contents in the output stream @@ -160,6 +165,11 @@ class ConsoleTable { /// \return Output stream with the formatted table string friend std::ostream &operator<<(std::ostream &out, const ConsoleTable &consoleTable); + /// Search color into the introduced text, return the number of + /// characters that you need to remove from the size. + /// \param text variable that contain text to analize + /// \return number of characters to remove from the size + size_t searchColor(const std::string &text) const; }; @@ -169,5 +179,12 @@ class ConsoleTable { /// \return The repeated string std::string operator*(const std::string &other, int repeats); +/// Count characters from position to characterBreaker and previous count +/// \param counter this variable is the previous count +/// \param pos is the position of the string that you need to start +/// \param text strint to analize +/// \param characterBreaker character to break the count +/// \return return the count of characters +size_t countCharacters(size_t counter, size_t pos,const std::string &text, char characterBreaker) ; -#endif //CONSOLETABLE_CONSOLETABLE_H \ No newline at end of file +#endif //CONSOLETABLE_CONSOLETABLE_H diff --git a/README.md b/README.md index a3add8e..20af48d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ConsoleTable is a library that allows you to organize your data in a table based [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -Sometimes, it can be very frustrating to display data in a console with proper alignment. +Sometimes, it can be very frustrating to display data in a console with proper alignment. To make this easier, ConsoleTable was created. It is a customizable text based table structure which is really convenient to use. It allows you to organize your data in a table structure where you can easily add, update and delete rows. Furthermore, it comes with sorting functionality as well as different layouts the user can choose from. @@ -37,7 +37,7 @@ The user can choose between a total of four different table layouts. `0` is the ```cpp table.setStyle(0); // Sets the default table style ``` -It's important to note that some styles might not be displayed correctly if your system doesn't support special characters. +It's important to note that some styles might not be displayed correctly if your system doesn't support special characters. The default style `0` as well as style `3` should work on all systems because only ASCII characters are used for the layout. To add new rows of data to the table use the `+=` operator followed by a list of `strings`. @@ -57,7 +57,7 @@ table.updateRow(3, 1, "NEW ENTRY"); // Update row 3, column 1 ``` The same thing applies for the headers. If you want to change the text of one of the header fields, simply provide the index of the field you like to update and call ```cpp -table.updateHeader(3, "NEW CAPTION"); // Update header field at index 3 +table.updateHeader(3, "NEW CAPTION"); // Update header field at index 3 ``` To output the table to the console, simply use the insertion operator followed by the `ConsoleTable` object. ```cpp @@ -74,5 +74,24 @@ To remove rows from the table use the `-=` operator followed by the index of the table -= 2; // Removes row at index 2 from the table ``` +## Adding color to the cell + +Following this guide: + +https://misc.flogisoft.com/bash/tip_colors_and_formatting + +You could add color to the cell, for example: + +```cpp +table += {"\e[33mGermany", "Berlin\e[0m", "82,800,000", "357,168 km2", "Euro"}; +table += {"\e[1;34mFrance\e[0m", "Paris", "67,201,000", "640,679 km2 ", "Euro"}; +table += {"South Korea", "Seoul", "51,446,201", "100,210 km2 ", "South Korean Won"}; +table += {"Australia", "Canberra", "24,877,800", "7,692,024 km2", "Australian Dollar"}; +table += {"China", "Beijing", "1,403,500,365", "9,596,961 km2", "Yuan"}; +table += {"Iceland", "Reykjavik", "348,580", "102,775 km2", "Icelandic Krona"}; +``` + +The result is that France text font is blue and the Germany until the end of Berlin is yellow. + ## Requirements This library requires C++11 to compile. diff --git a/main.cpp b/main.cpp index 97a4c35..f410fec 100644 --- a/main.cpp +++ b/main.cpp @@ -8,23 +8,23 @@ int main() { table.setPadding(2); table.setStyle(0); - table += {"Germany", "Berlin", "82,800,000", "357,168 km2", "Euro"}; - table += {"France", "Paris", "67,201,000", "640,679 km2 ", "Euro"}; + table += {"\e[33mGermany", "Berlin\e[0m", "82,800,000", "357,168 km2", "Euro"}; + table += {"\e[1;34mFrance\e[0m", "Paris", "67,201,000", "640,679 km2 ", "Euro"}; table += {"South Korea", "Seoul", "51,446,201", "100,210 km2 ", "South Korean Won"}; table += {"Australia", "Canberra", "24,877,800", "7,692,024 km2", "Australian Dollar"}; table += {"China", "Beijing", "1,403,500,365", "9,596,961 km2", "Yuan"}; table += {"Iceland", "Reykjavik", "348,580", "102,775 km2", "Icelandic Krona"}; - table += {"Netherlands", "Amsterdam", "17,200,671", "41,543 km2", "Euro"}; + table += {"Netherlands", "Amsterdam", "\e[1;33;105m17,200,671\e[0m", "41,543 km2", "Euro"}; table.updateRow(3, 1, "NEW ENTRY"); table.updateHeader(2, "NEW HEADER"); - table -= 2; - table -= 1; - table -= 0; +// table -= 2; +// table -= 3; +// table -= 2; table.sort(true); std::cout << table; return 0; -} \ No newline at end of file +}