# HG changeset patch # User František Kučera # Date 1655679356 -7200 # Node ID 2cc2d3f658f4cdc15e78f2d4624a6ee2d9603f09 # Parent 5dcff3c35462b5cbf08d07695bc69c4fd10806f3 configurable table style: rounded, sharp, sharp-double, horizontal-only, ascii diff -r 5dcff3c35462 -r 2cc2d3f658f4 bash-completion.sh --- a/bash-completion.sh Mon Jun 20 00:15:08 2022 +0200 +++ b/bash-completion.sh Mon Jun 20 00:55:56 2022 +0200 @@ -27,16 +27,34 @@ "false" ) + TABLE_STYLES=( + "rounded" + "sharp" + "sharp-double" + "horizontal-only" + "ascii" + ) + + COLOR_SCHEMES=( + "green-screen" + "monochrome" + "midnight" + ) + if [[ "$w1" == "--relation" && "x$w0" == "x" ]]; then COMPREPLY=("'.+'") elif [[ "$w1" == "--write-types" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0")) elif [[ "$w1" == "--write-relation-name" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0")) elif [[ "$w1" == "--write-record-count" ]]; then COMPREPLY=($(compgen -W "${BOOLEAN_VALUES[*]}" -- "$w0")) + elif [[ "$w1" == "--table-style" ]]; then COMPREPLY=($(compgen -W "${TABLE_STYLES[*]}" -- "$w0")) + elif [[ "$w1" == "--color-scheme" ]]; then COMPREPLY=($(compgen -W "${COLOR_SCHEMES[*]}" -- "$w0")) else OPTIONS=( "--relation" "--write-types" "--write-relation-name" "--write-record-count" + "--table-style" + "--color-scheme" ) COMPREPLY=($(compgen -W "${OPTIONS[*]}" -- "$w0")) fi diff -r 5dcff3c35462 -r 2cc2d3f658f4 src/CLIParser.h --- a/src/CLIParser.h Mon Jun 20 00:15:08 2022 +0200 +++ b/src/CLIParser.h Mon Jun 20 00:55:56 2022 +0200 @@ -57,6 +57,22 @@ else if (value == L"false") return false; else throw relpipe::cli::RelpipeCLIException(L"Unable to parse boolean value: " + value + L" (expecting true or false)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); } + + Configuration::ColorScheme parseColorScheme(const relpipe::reader::string_t& value) { + if (value == L"green-screen") return Configuration::ColorScheme::GreenScreen; + else if (value == L"monochrome") return Configuration::ColorScheme::Monochrome; + else if (value == L"midnight") return Configuration::ColorScheme::Midnight; + else throw relpipe::cli::RelpipeCLIException(L"Unable to parse ColorScheme value: " + value + L" (expecting green-screen, monochrome or midnight)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); + } + + Configuration::TableStyle parseTableStyle(const relpipe::reader::string_t& value) { + if (value == L"rounded") return Configuration::TableStyle::Rounded; + else if (value == L"sharp") return Configuration::TableStyle::Sharp; + else if (value == L"sharp-double") return Configuration::TableStyle::SharpDouble; + else if (value == L"horizontal-only") return Configuration::TableStyle::HorizontalOnly; + else if (value == L"ascii") return Configuration::TableStyle::Ascii; + else throw relpipe::cli::RelpipeCLIException(L"Unable to parse TableStyle value: " + value + L" (expecting rounded, sharp, ascii)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); + } public: @@ -64,10 +80,14 @@ static const relpipe::reader::string_t OPTION_WRITE_TYPES; static const relpipe::reader::string_t OPTION_WRITE_RELATION_NAME; static const relpipe::reader::string_t OPTION_WRITE_RECORD_COUNT; + static const relpipe::reader::string_t OPTION_COLOR_SCHEME; + static const relpipe::reader::string_t OPTION_TABLE_STYLE; Configuration parse(const std::vector& arguments) { Configuration c; RelationConfiguration currentRelation; + + // TODO: global configuration of writeTypes, writeRelationName, writeRecordCount for (int i = 0; i < arguments.size();) { relpipe::reader::string_t option = readNext(arguments, i); @@ -81,6 +101,10 @@ currentRelation.writeRelationName = parseBoolean(readNext(arguments, i)); } else if (option == OPTION_WRITE_RECORD_COUNT) { currentRelation.writeRecordCount = parseBoolean(readNext(arguments, i)); + } else if (option == OPTION_COLOR_SCHEME) { + c.colorScheme = parseColorScheme(readNext(arguments, i)); + } else if (option == OPTION_TABLE_STYLE) { + c.tableStyle = parseTableStyle(readNext(arguments, i)); } else throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); } @@ -97,6 +121,8 @@ const relpipe::reader::string_t CLIParser::OPTION_WRITE_TYPES = L"--write-types"; const relpipe::reader::string_t CLIParser::OPTION_WRITE_RELATION_NAME = L"--write-relation-name"; const relpipe::reader::string_t CLIParser::OPTION_WRITE_RECORD_COUNT = L"--write-record-count"; +const relpipe::reader::string_t CLIParser::OPTION_COLOR_SCHEME = L"--color-scheme"; +const relpipe::reader::string_t CLIParser::OPTION_TABLE_STYLE = L"--table-style"; } } diff -r 5dcff3c35462 -r 2cc2d3f658f4 src/Configuration.h --- a/src/Configuration.h Mon Jun 20 00:15:08 2022 +0200 +++ b/src/Configuration.h Mon Jun 20 00:55:56 2022 +0200 @@ -40,10 +40,28 @@ class Configuration { public: + + enum class ColorScheme { + GreenScreen, + Monochrome, + Midnight + }; + + enum class TableStyle { + Rounded, + Sharp, + SharpDouble, + HorizontalOnly, + Ascii + }; + + relpipe::reader::boolean_t writeTypes = true; relpipe::reader::boolean_t writeRecordCount = true; relpipe::reader::boolean_t writeRelationName = true; std::vector relationConfigurations; + ColorScheme colorScheme = ColorScheme::GreenScreen; + TableStyle tableStyle = TableStyle::Rounded; virtual ~Configuration() { } diff -r 5dcff3c35462 -r 2cc2d3f658f4 src/TabularPrefetchingHandler.h --- a/src/TabularPrefetchingHandler.h Mon Jun 20 00:15:08 2022 +0200 +++ b/src/TabularPrefetchingHandler.h Mon Jun 20 00:55:56 2022 +0200 @@ -28,6 +28,7 @@ #include #include #include +#include #include "Configuration.h" @@ -138,13 +139,7 @@ return width; } - void printHorizontalLine(const string_t &left, const string_t &middle, const string_t &right) { - const string_t bar = L"─"; - // TODO: support also ASCII nostalgia: - // border = border.replaceAll("─", "-"); - // border = border.replaceAll("│", "|"); - // border = border.replaceAll("[╭┬╮├┼┤╰┴╯]", "+"); - + void printHorizontalLine(const string_t& left, const string_t& middle, const string_t& right, const string_t& bar) { output << INDENT << ESC_BORDER; output << convertor.to_bytes(left); for (size_t c = 0; c < columnCount; c++) { @@ -168,25 +163,43 @@ paddings[i] = columnWidths[i] - minWidth; } - printHorizontalLine(L"╭", L"┬", L"╮"); + if (configuration.tableStyle == Configuration::TableStyle::Rounded) printHorizontalLine(L"╭", L"┬", L"╮", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::Sharp) printHorizontalLine(L"┌", L"┬", L"┐", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::SharpDouble) printHorizontalLine(L"╔", L"╦", L"╗", L"═"); + else if (configuration.tableStyle == Configuration::TableStyle::HorizontalOnly) printHorizontalLine(L"─", L"─", L"─", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::Ascii) printHorizontalLine(L"+", L"+", L"+", L"-"); + else throw RelpipeReaderException(L"Unsupported TableStyle: " + std::to_wstring((int) configuration.tableStyle)); + + std::string verticalSeparator; + if (configuration.tableStyle == Configuration::TableStyle::Rounded) verticalSeparator = "│"; + else if (configuration.tableStyle == Configuration::TableStyle::Sharp) verticalSeparator = "│"; + else if (configuration.tableStyle == Configuration::TableStyle::SharpDouble) verticalSeparator = "║"; + else if (configuration.tableStyle == Configuration::TableStyle::HorizontalOnly) verticalSeparator = " "; + else if (configuration.tableStyle == Configuration::TableStyle::Ascii) verticalSeparator = "|"; + else throw RelpipeReaderException(L"Unsupported TableStyle: " + std::to_wstring((int) configuration.tableStyle)); // Print column headers: - output << INDENT << ESC_BORDER << "│" << ESC_RESET; + output << INDENT << ESC_BORDER << verticalSeparator << ESC_RESET; for (size_t i = 0; i < columnCount; i++) { output << " " << convertor.to_bytes(formatValue(columnNames[i], ESC_HEADER)); for (integer_t p = 0; p < paddings[i]; p++) { output << " "; } if (getConfiguration(writeTypes)) output << " (" << convertor.to_bytes(columnTypeCodes[i]) << ")"; - output << ESC_BORDER << " │" << ESC_RESET; + output << ESC_BORDER << " " << verticalSeparator << ESC_RESET; } output << std::endl; - printHorizontalLine(L"├", L"┼", L"┤"); + if (configuration.tableStyle == Configuration::TableStyle::Rounded) printHorizontalLine(L"├", L"┼", L"┤", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::Sharp) printHorizontalLine(L"├", L"┼", L"┤", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::SharpDouble) printHorizontalLine(L"╠", L"╬", L"╣", L"═"); + else if (configuration.tableStyle == Configuration::TableStyle::HorizontalOnly) printHorizontalLine(L"─", L"─", L"─", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::Ascii) printHorizontalLine(L"+", L"+", L"+", L"-"); + else throw RelpipeReaderException(L"Unsupported TableStyle: " + std::to_wstring((int) configuration.tableStyle)); // Print particular rows: for (size_t i = 0; i < values.size(); i++) { integer_t columnIndex = i % columnCount; - if (columnIndex == 0) output << INDENT << ESC_BORDER << "│" << ESC_RESET; + if (columnIndex == 0) output << INDENT << ESC_BORDER << verticalSeparator << ESC_RESET; string_t stringValue = values[i]; integer_t padding = columnWidths[columnIndex] - computeWidth(stringValue); boolean_t alignRight = columnTypes[columnIndex] == TypeId::BOOLEAN || columnTypes[columnIndex] == TypeId::INTEGER; @@ -195,10 +208,15 @@ output << " " << convertor.to_bytes(formatValue(stringValue, ESC_VALUE)); if (!alignRight) for (integer_t p = 0; p < padding; p++) output << " "; - output << ESC_BORDER << " │" << ESC_RESET; + output << ESC_BORDER << " " << verticalSeparator << ESC_RESET; if (columnIndex == (columnCount - 1)) output << std::endl; } - printHorizontalLine(L"╰", L"┴", L"╯"); + if (configuration.tableStyle == Configuration::TableStyle::Rounded) printHorizontalLine(L"╰", L"┴", L"╯", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::Sharp) printHorizontalLine(L"└", L"┴", L"┘", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::SharpDouble) printHorizontalLine(L"╚", L"╩", L"╝", L"═"); + else if (configuration.tableStyle == Configuration::TableStyle::HorizontalOnly) printHorizontalLine(L"─", L"─", L"─", L"─"); + else if (configuration.tableStyle == Configuration::TableStyle::Ascii) printHorizontalLine(L"+", L"+", L"+", L"-"); + else throw RelpipeReaderException(L"Unsupported TableStyle: " + std::to_wstring((int) configuration.tableStyle)); if (getConfiguration(writeRecordCount)) { integer_t recordCount = values.size() / columnCount;