feat: add termcolor in carton.
- add termcolor and its testbench - add integer() in flag_enum and update its testbench according to the requirements in termcolor.
This commit is contained in:
@ -24,6 +24,7 @@ PRIVATE
|
|||||||
yycc/encoding/iconv.cpp
|
yycc/encoding/iconv.cpp
|
||||||
|
|
||||||
yycc/carton/pycodec.cpp
|
yycc/carton/pycodec.cpp
|
||||||
|
yycc/carton/termcolor.cpp
|
||||||
yycc/carton/wcwidth.cpp
|
yycc/carton/wcwidth.cpp
|
||||||
)
|
)
|
||||||
target_sources(YYCCommonplace
|
target_sources(YYCCommonplace
|
||||||
@ -68,6 +69,7 @@ FILES
|
|||||||
yycc/encoding/iconv.hpp
|
yycc/encoding/iconv.hpp
|
||||||
|
|
||||||
yycc/carton/pycodec.hpp
|
yycc/carton/pycodec.hpp
|
||||||
|
yycc/carton/termcolor.hpp
|
||||||
yycc/carton/wcwidth.hpp
|
yycc/carton/wcwidth.hpp
|
||||||
)
|
)
|
||||||
# Setup header infomations
|
# Setup header infomations
|
||||||
|
@ -11,77 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
namespace YYCC::ConsoleHelper {
|
namespace YYCC::ConsoleHelper {
|
||||||
|
|
||||||
/// @brief The head of ASCII escape code of black color.
|
|
||||||
#define YYCC_COLORHDR_BLACK "\033[30m"
|
|
||||||
/// @brief The head of ASCII escape code of red color.
|
|
||||||
#define YYCC_COLORHDR_RED "\033[31m"
|
|
||||||
/// @brief The head of ASCII escape code of green color.
|
|
||||||
#define YYCC_COLORHDR_GREEN "\033[32m"
|
|
||||||
/// @brief The head of ASCII escape code of yellow color.
|
|
||||||
#define YYCC_COLORHDR_YELLOW "\033[33m"
|
|
||||||
/// @brief The head of ASCII escape code of blue color.
|
|
||||||
#define YYCC_COLORHDR_BLUE "\033[34m"
|
|
||||||
/// @brief The head of ASCII escape code of magenta color.
|
|
||||||
#define YYCC_COLORHDR_MAGENTA "\033[35m"
|
|
||||||
/// @brief The head of ASCII escape code of cyan color.
|
|
||||||
#define YYCC_COLORHDR_CYAN "\033[36m"
|
|
||||||
/// @brief The head of ASCII escape code of white color.
|
|
||||||
#define YYCC_COLORHDR_WHITE "\033[37m"
|
|
||||||
|
|
||||||
/// @brief The head of ASCII escape code of light black color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_BLACK "\033[90m"
|
|
||||||
/// @brief The head of ASCII escape code of light red color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_RED "\033[91m"
|
|
||||||
/// @brief The head of ASCII escape code of light green color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_GREEN "\033[92m"
|
|
||||||
/// @brief The head of ASCII escape code of light yellow color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_YELLOW "\033[93m"
|
|
||||||
/// @brief The head of ASCII escape code of light blue color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_BLUE "\033[94m"
|
|
||||||
/// @brief The head of ASCII escape code of light magenta color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_MAGENTA "\033[95m"
|
|
||||||
/// @brief The head of ASCII escape code of light cyan color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_CYAN "\033[96m"
|
|
||||||
/// @brief The head of ASCII escape code of light white color.
|
|
||||||
#define YYCC_COLORHDR_LIGHT_WHITE "\033[97m"
|
|
||||||
|
|
||||||
/// @brief The tail of ASCII escape code of every color.
|
|
||||||
#define YYCC_COLORTAIL "\033[0m"
|
|
||||||
|
|
||||||
/// @brief The ASCII escape code pair of black color.
|
|
||||||
#define YYCC_COLOR_BLACK(T) "\033[30m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of red color.
|
|
||||||
#define YYCC_COLOR_RED(T) "\033[31m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of green color.
|
|
||||||
#define YYCC_COLOR_GREEN(T) "\033[32m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of yellow color.
|
|
||||||
#define YYCC_COLOR_YELLOW(T) "\033[33m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of blue color.
|
|
||||||
#define YYCC_COLOR_BLUE(T) "\033[34m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of magenta color.
|
|
||||||
#define YYCC_COLOR_MAGENTA(T) "\033[35m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of cyan color.
|
|
||||||
#define YYCC_COLOR_CYAN(T) "\033[36m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of white color.
|
|
||||||
#define YYCC_COLOR_WHITE(T) "\033[37m" T "\033[0m"
|
|
||||||
|
|
||||||
/// @brief The ASCII escape code pair of light black color.
|
|
||||||
#define YYCC_COLOR_LIGHT_BLACK(T) "\033[90m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light red color.
|
|
||||||
#define YYCC_COLOR_LIGHT_RED(T) "\033[91m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light green color.
|
|
||||||
#define YYCC_COLOR_LIGHT_GREEN(T) "\033[92m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light yellow color.
|
|
||||||
#define YYCC_COLOR_LIGHT_YELLOW(T) "\033[93m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light blue color.
|
|
||||||
#define YYCC_COLOR_LIGHT_BLUE(T) "\033[94m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light magenta color.
|
|
||||||
#define YYCC_COLOR_LIGHT_MAGENTA(T) "\033[95m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light cyan color.
|
|
||||||
#define YYCC_COLOR_LIGHT_CYAN(T) "\033[96m" T "\033[0m"
|
|
||||||
/// @brief The ASCII escape code pair of light white color.
|
|
||||||
#define YYCC_COLOR_LIGHT_WHITE(T) "\033[97m" T "\033[0m"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable console color support for Windows.
|
* @brief Enable console color support for Windows.
|
||||||
* @details This actually is enable virtual console feature for \c stdout and \c stderr.
|
* @details This actually is enable virtual console feature for \c stdout and \c stderr.
|
||||||
|
234
src/yycc/carton/termcolor.cpp
Normal file
234
src/yycc/carton/termcolor.cpp
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#include "termcolor.hpp"
|
||||||
|
#include "../flag_enum.hpp"
|
||||||
|
#include "../string/reinterpret.hpp"
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
|
#define FLAG_ENUM ::yycc::flag_enum
|
||||||
|
#define REINTERPRET ::yycc::string::reinterpret
|
||||||
|
|
||||||
|
using namespace std::literals::string_view_literals;
|
||||||
|
|
||||||
|
namespace yycc::carton::termcolor {
|
||||||
|
|
||||||
|
#pragma region Lowlevel Functions
|
||||||
|
|
||||||
|
const std::u8string_view foreground(Color color) {
|
||||||
|
switch (color) {
|
||||||
|
case Color::Default:
|
||||||
|
return u8""sv;
|
||||||
|
case Color::Black:
|
||||||
|
return u8"\033[30m"sv;
|
||||||
|
case Color::Red:
|
||||||
|
return u8"\033[31m"sv;
|
||||||
|
case Color::Green:
|
||||||
|
return u8"\033[32m"sv;
|
||||||
|
case Color::Yellow:
|
||||||
|
return u8"\033[33m"sv;
|
||||||
|
case Color::Blue:
|
||||||
|
return u8"\033[34m"sv;
|
||||||
|
case Color::Magenta:
|
||||||
|
return u8"\033[35m"sv;
|
||||||
|
case Color::Cyan:
|
||||||
|
return u8"\033[36m"sv;
|
||||||
|
case Color::White:
|
||||||
|
return u8"\033[37m"sv;
|
||||||
|
case Color::LightBlack:
|
||||||
|
return u8"\033[90m"sv;
|
||||||
|
case Color::LightRed:
|
||||||
|
return u8"\033[91m"sv;
|
||||||
|
case Color::LightGreen:
|
||||||
|
return u8"\033[92m"sv;
|
||||||
|
case Color::LightYellow:
|
||||||
|
return u8"\033[93m"sv;
|
||||||
|
case Color::LightBlue:
|
||||||
|
return u8"\033[94m"sv;
|
||||||
|
case Color::LightMagenta:
|
||||||
|
return u8"\033[95m"sv;
|
||||||
|
case Color::LightCyan:
|
||||||
|
return u8"\033[96m"sv;
|
||||||
|
case Color::LightWhite:
|
||||||
|
return u8"\033[97m"sv;
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("invalid color kind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::u8string_view background(Color color) {
|
||||||
|
switch (color) {
|
||||||
|
case Color::Default:
|
||||||
|
return u8""sv;
|
||||||
|
case Color::Black:
|
||||||
|
return u8"\033[40m"sv;
|
||||||
|
case Color::Red:
|
||||||
|
return u8"\033[41m"sv;
|
||||||
|
case Color::Green:
|
||||||
|
return u8"\033[42m"sv;
|
||||||
|
case Color::Yellow:
|
||||||
|
return u8"\033[43m"sv;
|
||||||
|
case Color::Blue:
|
||||||
|
return u8"\033[44m"sv;
|
||||||
|
case Color::Magenta:
|
||||||
|
return u8"\033[45m"sv;
|
||||||
|
case Color::Cyan:
|
||||||
|
return u8"\033[46m"sv;
|
||||||
|
case Color::White:
|
||||||
|
return u8"\033[47m"sv;
|
||||||
|
case Color::LightBlack:
|
||||||
|
return u8"\033[100m"sv;
|
||||||
|
case Color::LightRed:
|
||||||
|
return u8"\033[101m"sv;
|
||||||
|
case Color::LightGreen:
|
||||||
|
return u8"\033[102m"sv;
|
||||||
|
case Color::LightYellow:
|
||||||
|
return u8"\033[103m"sv;
|
||||||
|
case Color::LightBlue:
|
||||||
|
return u8"\033[104m"sv;
|
||||||
|
case Color::LightMagenta:
|
||||||
|
return u8"\033[105m"sv;
|
||||||
|
case Color::LightCyan:
|
||||||
|
return u8"\033[106m"sv;
|
||||||
|
case Color::LightWhite:
|
||||||
|
return u8"\033[107m"sv;
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("invalid color kind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::u8string_view style(Attribute attr) {
|
||||||
|
// Return for Default first because it can not pass following test
|
||||||
|
if (attr == Attribute::Default) {
|
||||||
|
return u8""sv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether it only has one flag
|
||||||
|
if (!std::has_single_bit(FLAG_ENUM::integer(attr))) {
|
||||||
|
throw std::invalid_argument("style() only accept single flag attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
switch (attr) {
|
||||||
|
case Attribute::Bold:
|
||||||
|
return u8"\033[1m"sv;
|
||||||
|
case Attribute::Dark:
|
||||||
|
return u8"\033[2m"sv;
|
||||||
|
case Attribute::Italic:
|
||||||
|
return u8"\033[3m"sv;
|
||||||
|
case Attribute::Underline:
|
||||||
|
return u8"\033[4m"sv;
|
||||||
|
case Attribute::Blink:
|
||||||
|
return u8"\033[5m"sv;
|
||||||
|
case Attribute::Reverse:
|
||||||
|
return u8"\033[6m"sv;
|
||||||
|
case Attribute::Concealed:
|
||||||
|
return u8"\033[7m"sv;
|
||||||
|
default:
|
||||||
|
throw std::invalid_argument("invalid attribute kind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @brief The possible maximum length of ANSI Escape Sequence used in this module.
|
||||||
|
* @details This const value is used for computing reserved size of final built string.
|
||||||
|
*/
|
||||||
|
static constexpr size_t ANSI_ESC_LEN = sizeof(u8"\033[000m") - 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @brief Count how many single flags combine given attributes.
|
||||||
|
* @details
|
||||||
|
* For function styles() involving multiple font style ANSI Escape Sequence,
|
||||||
|
* this function may be useful for computing desired size of final result,
|
||||||
|
* to reduce useless memory re-allocation.
|
||||||
|
* @param[in] attrs Attributes for counting.
|
||||||
|
* @return The count of single flag.
|
||||||
|
*/
|
||||||
|
static size_t count_attribute_flags(Attribute attrs) {
|
||||||
|
return static_cast<size_t>(std::popcount(FLAG_ENUM::integer(attrs)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @brief Append multiple font styles into given string.
|
||||||
|
* @details
|
||||||
|
* This function will decompose given font styles into single flag.
|
||||||
|
* And append its components one by one into given string.
|
||||||
|
* If there is enough reserved space in given string,
|
||||||
|
* there is no memory re-allocation happened.
|
||||||
|
* @remarks
|
||||||
|
* This function is served for styles() and colored().
|
||||||
|
* @param[in] s The string to be appended.
|
||||||
|
* @param[in] attrs The attributes for writting.
|
||||||
|
*/
|
||||||
|
static void append_styles(std::u8string& s, Attribute attrs) {
|
||||||
|
#define CHECK_ATTR(probe) \
|
||||||
|
if (FLAG_ENUM::has(attrs, probe)) s.append(termcolor::style(probe));
|
||||||
|
|
||||||
|
if (attrs != Attribute::Default) {
|
||||||
|
CHECK_ATTR(Attribute::Bold);
|
||||||
|
CHECK_ATTR(Attribute::Dark);
|
||||||
|
CHECK_ATTR(Attribute::Italic);
|
||||||
|
CHECK_ATTR(Attribute::Blink);
|
||||||
|
CHECK_ATTR(Attribute::Reverse);
|
||||||
|
CHECK_ATTR(Attribute::Concealed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CHECK_ATTR
|
||||||
|
}
|
||||||
|
|
||||||
|
std::u8string styles(Attribute attrs) {
|
||||||
|
// Prepare the result string
|
||||||
|
std::u8string rv;
|
||||||
|
rv.reserve(count_attribute_flags(attrs) * ANSI_ESC_LEN);
|
||||||
|
// Append styles and return
|
||||||
|
append_styles(rv, attrs);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::u8string_view reset() {
|
||||||
|
return u8"\033[0m"sv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Highlevel Functions
|
||||||
|
|
||||||
|
std::u8string colored(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
||||||
|
// Calculate the expected size of result string.
|
||||||
|
// final count = styles count + 1 (foreground) + 1 (background) + 1 (reset)
|
||||||
|
std::u8string rv;
|
||||||
|
size_t ansi_esc_count = count_attribute_flags(styles) + 3;
|
||||||
|
rv.reserve(ansi_esc_count * ANSI_ESC_LEN + words.size());
|
||||||
|
|
||||||
|
// Append data one by one
|
||||||
|
rv.append(termcolor::foreground(foreground));
|
||||||
|
rv.append(termcolor::background(background));
|
||||||
|
append_styles(rv, styles);
|
||||||
|
rv.append(words);
|
||||||
|
rv.append(termcolor::reset());
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cprint(const std::u8string_view& words, Color foreground, Color background, Attribute styles, std::ostream& dst) {
|
||||||
|
dst << REINTERPRET::as_ordinary_view(colored(words, foreground, background, styles));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecprint(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
||||||
|
cprint(words, foreground, background, styles, std::cerr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cprintln(const std::u8string_view& words, Color foreground, Color background, Attribute styles, std::ostream& dst) {
|
||||||
|
cprint(words, foreground, background, styles, dst);
|
||||||
|
dst << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecprintln(const std::u8string_view& words, Color foreground, Color background, Attribute styles) {
|
||||||
|
cprintln(words, foreground, background, styles, std::cerr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
} // namespace yycc::carton::termcolor
|
166
src/yycc/carton/termcolor.hpp
Normal file
166
src/yycc/carton/termcolor.hpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The namespace for terminal font color and style.
|
||||||
|
* @details
|
||||||
|
* This namespace provides functions to generate ANSI escape sequence for terminal font color and style.
|
||||||
|
* It also provides functions to add color and style for given string with ANSI Escape Sequence.
|
||||||
|
*
|
||||||
|
* This namespace is basically the immitation of the Python package with same name.
|
||||||
|
*/
|
||||||
|
namespace yycc::carton::termcolor {
|
||||||
|
|
||||||
|
#pragma region Lowlevel Functions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The color of font.
|
||||||
|
*/
|
||||||
|
enum class Color {
|
||||||
|
Black,
|
||||||
|
Red,
|
||||||
|
Green,
|
||||||
|
Yellow,
|
||||||
|
Blue,
|
||||||
|
Magenta,
|
||||||
|
Cyan,
|
||||||
|
White,
|
||||||
|
LightBlack,
|
||||||
|
LightRed,
|
||||||
|
LightGreen,
|
||||||
|
LightYellow,
|
||||||
|
LightBlue,
|
||||||
|
LightMagenta,
|
||||||
|
LightCyan,
|
||||||
|
LightWhite,
|
||||||
|
Default
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ANSI escape sequence for foreground color
|
||||||
|
* @param[in] color The color to generate sequence for
|
||||||
|
* @return Gotten ANSI escape sequence
|
||||||
|
*/
|
||||||
|
const std::u8string_view foreground(Color color);
|
||||||
|
/**
|
||||||
|
* @brief Get ANSI escape sequence for background color
|
||||||
|
* @param[in] color The color to generate sequence for
|
||||||
|
* @return Gotten ANSI escape sequence
|
||||||
|
*/
|
||||||
|
const std::u8string_view background(Color color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The attribute of font
|
||||||
|
* @remarks We define this enum as unsigned integral, so that we can use \c std::has_single_bit.
|
||||||
|
*/
|
||||||
|
enum class Attribute : uint32_t {
|
||||||
|
Default = 0,
|
||||||
|
Bold = 1 << 0,
|
||||||
|
Dark = 1 << 1,
|
||||||
|
Italic = 1 << 2,
|
||||||
|
Underline = 1 << 3,
|
||||||
|
Blink = 1 << 4,
|
||||||
|
Reverse = 1 << 5,
|
||||||
|
Concealed = 1 << 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ANSI escape sequence for text style
|
||||||
|
* @details
|
||||||
|
* Please note that this function only support single attribute flag.
|
||||||
|
* If you want to use multiple attributes, please use styles() instead.
|
||||||
|
*
|
||||||
|
* However, the difference between this function and styles() is that
|
||||||
|
* there is no memory allocation in this function.
|
||||||
|
* It may have better performance that styles().
|
||||||
|
* @param[in] attr Single attribute to generate sequence for
|
||||||
|
* @return Gotten ANSI escape sequence
|
||||||
|
* @throws std::invalid_argument if attribute is not a single flag
|
||||||
|
*/
|
||||||
|
const std::u8string_view style(Attribute attr);
|
||||||
|
/**
|
||||||
|
* @brief Generates ANSI escape sequence for multiple text styles
|
||||||
|
* @param[in] attrs Combination of attributes to generate sequences for
|
||||||
|
* @return Generated ANSI escape sequence
|
||||||
|
*/
|
||||||
|
std::u8string styles(Attribute attrs);
|
||||||
|
/**
|
||||||
|
* @brief Get ANSI escape sequence for reset style
|
||||||
|
* @return Gotten ANSI reset sequence
|
||||||
|
*/
|
||||||
|
const std::u8string_view reset();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Highlevel Functions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add color and style for given string with ANSI Escape Sequence.
|
||||||
|
* @param[in] words The words to be decorated.
|
||||||
|
* @param[in] foreground The foreground of words.
|
||||||
|
* @param[in] background The background of words.
|
||||||
|
* @param[in] styles The font style of words.
|
||||||
|
* @return Decorated words.
|
||||||
|
*/
|
||||||
|
std::u8string colored(const std::u8string_view& words,
|
||||||
|
Color foreground = Color::Default,
|
||||||
|
Color background = Color::Default,
|
||||||
|
Attribute styles = Attribute::Default);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print words into stream with given styles.
|
||||||
|
* @param[in] words The words to be printed.
|
||||||
|
* @param[in] foreground The foreground of words.
|
||||||
|
* @param[in] background The background of words.
|
||||||
|
* @param[in] styles The font style of words.
|
||||||
|
* @param[in] dst The stream written into. \c stdout in default.
|
||||||
|
*/
|
||||||
|
void cprint(const std::u8string_view& words = std::u8string_view(u8""),
|
||||||
|
Color foreground = Color::Default,
|
||||||
|
Color background = Color::Default,
|
||||||
|
Attribute styles = Attribute::Default,
|
||||||
|
std::ostream& dst = std::cout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print words into \c stderr with given styles.
|
||||||
|
* @param[in] words The words to be printed.
|
||||||
|
* @param[in] foreground The foreground of words.
|
||||||
|
* @param[in] background The background of words.
|
||||||
|
* @param[in] styles The font style of words.
|
||||||
|
*/
|
||||||
|
void ceprint(const std::u8string_view& words = std::u8string_view(u8""),
|
||||||
|
Color foreground = Color::Default,
|
||||||
|
Color background = Color::Default,
|
||||||
|
Attribute styles = Attribute::Default);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print words into stream with given styles and break line.
|
||||||
|
* @param[in] words The words to be printed.
|
||||||
|
* @param[in] foreground The foreground of words.
|
||||||
|
* @param[in] background The background of words.
|
||||||
|
* @param[in] styles The font style of words.
|
||||||
|
* @param[in] dst The stream written into. \c stdout in default.
|
||||||
|
*/
|
||||||
|
void cprintln(const std::u8string_view& words = std::u8string_view(u8""),
|
||||||
|
Color foreground = Color::Default,
|
||||||
|
Color background = Color::Default,
|
||||||
|
Attribute styles = Attribute::Default,
|
||||||
|
std::ostream& dst = std::cout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print words into \c stderr with given styles and break line.
|
||||||
|
* @param[in] words The words to be printed.
|
||||||
|
* @param[in] foreground The foreground of words.
|
||||||
|
* @param[in] background The background of words.
|
||||||
|
* @param[in] styles The font style of words.
|
||||||
|
*/
|
||||||
|
void ceprintln(const std::u8string_view& words = std::u8string_view(u8""),
|
||||||
|
Color foreground = Color::Default,
|
||||||
|
Color background = Color::Default,
|
||||||
|
Attribute styles = Attribute::Default);
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
} // namespace yycc::carton::termcolor
|
@ -191,4 +191,17 @@ namespace yycc::flag_enum {
|
|||||||
return static_cast<bool>(static_cast<ut>(e));
|
return static_cast<bool>(static_cast<ut>(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Cast given enum flags to its equvalent underlying integer value like performing <TT>static_cast<std::underlying_type_t<T>>(e)</TT>
|
||||||
|
* @tparam TEnum Enum type for processing.
|
||||||
|
* @param e The enum flags to be cast.
|
||||||
|
* @return The equvalent integer value of given enum flag.
|
||||||
|
*/
|
||||||
|
template<typename TEnum>
|
||||||
|
requires(std::is_enum_v<TEnum>)
|
||||||
|
constexpr std::underlying_type_t<TEnum> integer(TEnum e) {
|
||||||
|
using ut = std::underlying_type_t<TEnum>;
|
||||||
|
return static_cast<ut>(e);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace yycc::flag_enum
|
} // namespace yycc::flag_enum
|
||||||
|
@ -33,6 +33,7 @@ PRIVATE
|
|||||||
yycc/windows/winfct.cpp
|
yycc/windows/winfct.cpp
|
||||||
|
|
||||||
yycc/carton/pycodec.cpp
|
yycc/carton/pycodec.cpp
|
||||||
|
yycc/carton/termcolor.cpp
|
||||||
yycc/carton/wcwidth.cpp
|
yycc/carton/wcwidth.cpp
|
||||||
)
|
)
|
||||||
target_sources(YYCCTestbench
|
target_sources(YYCCTestbench
|
||||||
|
44
testbench/yycc/carton/termcolor.cpp
Normal file
44
testbench/yycc/carton/termcolor.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <yycc.hpp>
|
||||||
|
#include <yycc/carton/termcolor.hpp>
|
||||||
|
#include <yycc/flag_enum.hpp>
|
||||||
|
|
||||||
|
#define TERMCOLOR ::yycc::carton::termcolor
|
||||||
|
#define FLAG_ENUM ::yycc::flag_enum
|
||||||
|
|
||||||
|
using namespace std::literals::string_view_literals;
|
||||||
|
using Color = TERMCOLOR::Color;
|
||||||
|
using Attribute = TERMCOLOR::Attribute;
|
||||||
|
|
||||||
|
namespace yycctest::carton::termcolor {
|
||||||
|
|
||||||
|
TEST(CartonTermcolor, Lowlevel) {
|
||||||
|
EXPECT_EQ(TERMCOLOR::foreground(Color::Default), u8"");
|
||||||
|
EXPECT_EQ(TERMCOLOR::foreground(Color::Red), u8"\033[31m");
|
||||||
|
EXPECT_EQ(TERMCOLOR::foreground(Color::LightRed), u8"\033[91m");
|
||||||
|
|
||||||
|
EXPECT_EQ(TERMCOLOR::background(Color::Default), u8"");
|
||||||
|
EXPECT_EQ(TERMCOLOR::background(Color::Red), u8"\033[41m");
|
||||||
|
EXPECT_EQ(TERMCOLOR::background(Color::LightRed), u8"\033[101m");
|
||||||
|
|
||||||
|
EXPECT_EQ(TERMCOLOR::style(Attribute::Default), u8"");
|
||||||
|
EXPECT_EQ(TERMCOLOR::style(Attribute::Italic), u8"\033[3m");
|
||||||
|
EXPECT_EQ(TERMCOLOR::styles(FLAG_ENUM::merge(Attribute::Italic, Attribute::Bold)),
|
||||||
|
u8"\033[1m"
|
||||||
|
"\033[3m");
|
||||||
|
|
||||||
|
EXPECT_EQ(TERMCOLOR::reset(), u8"\033[0m"sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CartonTermcolor, Highlevel) {
|
||||||
|
EXPECT_EQ(TERMCOLOR::colored(u8"hello"sv), u8"hello\033[0m");
|
||||||
|
EXPECT_EQ(TERMCOLOR::colored(u8"hello"sv, Color::LightWhite, Color::Red, FLAG_ENUM::merge(Attribute::Italic, Attribute::Bold)),
|
||||||
|
u8"\033[97m"
|
||||||
|
"\033[41m"
|
||||||
|
"\033[1m"
|
||||||
|
"\033[3m"
|
||||||
|
"hello"
|
||||||
|
"\033[0m");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace yycctest::carton::termcolor
|
@ -1,6 +1,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <yycc.hpp>
|
#include <yycc.hpp>
|
||||||
#include <yycc/flag_enum.hpp>
|
#include <yycc/flag_enum.hpp>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
#include <yycc/rust/prelude.hpp>
|
#include <yycc/rust/prelude.hpp>
|
||||||
|
|
||||||
@ -74,4 +75,9 @@ namespace yycctest::flag_enum {
|
|||||||
EXPECT_TRUE(FLAG_ENUM::boolean(TestEnum::MergedBit247));
|
EXPECT_TRUE(FLAG_ENUM::boolean(TestEnum::MergedBit247));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FlagEnum, Integer) {
|
||||||
|
EXPECT_EQ(FLAG_ENUM::integer(TestEnum::Empty), UINT8_C(0));
|
||||||
|
EXPECT_EQ(FLAG_ENUM::integer(TestEnum::Bit1), UINT8_C(1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user