Mercurial > code
changeset 453:2d95f0c8fd1d
Add Format, convenient string formatter with escape sequences
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 02 Nov 2015 19:16:26 +0100 |
parents | 7781bb45e749 |
children | 781494d9c807 |
files | C++/modules/Format/Format.cpp C++/modules/Format/Format.h |
diffstat | 2 files changed, 201 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/C++/modules/Format/Format.cpp Mon Nov 02 19:16:26 2015 +0100 @@ -0,0 +1,90 @@ +/* + * Format.cpp -- convenient function for formatting text with escape sequences + * + * Copyright (c) 2015 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <array> +#include <sstream> +#include <unordered_map> + +#include "Format.h" + +namespace fmt { + +namespace { + +const std::array<unsigned char, 17> colorsTable{ + 0, // Default + 30, // Black + 31, // Red + 32, // Green + 33, // Yellow + 34, // Blue + 35, // Magenta + 36, // Cyan + 37, // Light gray + 90, // Dark gray + 91, // Light red + 92, // Light green + 93, // Light yellow + 94, // Light blue + 95, // Light cyan + 96, // White + 97 +}; + +const std::unordered_map<int, int> attributesTable{ + { Bold, 1 }, + { Dim, 2 }, + { Underline, 4 }, + { Blink, 5 }, + { Reverse, 7 }, + { Hidden, 8 } +}; + +} // !namespace + +std::string convert(std::string input, unsigned short flags) +{ + std::ostringstream oss; + +#if !defined(_WIN32) + // Attributes + for (const auto &pair : attributesTable) { + if (flags & pair.first) { + oss << "\033[" << pair.second << "m"; + } + } + + // Background + if (((flags >> 11) & 0x3f) != Default) { + oss << "\033[" << std::to_string(colorsTable[static_cast<unsigned char>((flags >> 11) & 0x3f)] + 10) << "m"; + } + + // Foreground + if (((flags >> 6) & 0x3f) != Default) { + oss << "\033[" << std::to_string(colorsTable[static_cast<unsigned char>((flags >> 6) & 0x3f)]) << "m"; + } + + oss << std::move(input) << "\033[0m"; +#else + oss << std::move(input); +#endif + + return oss.str(); +} + +} // !fmt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/C++/modules/Format/Format.h Mon Nov 02 19:16:26 2015 +0100 @@ -0,0 +1,111 @@ +/* + * Format.h -- convenient function for formatting text with escape sequences + * + * Copyright (c) 2015 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FORMAT_H_ +#define _FORMAT_H_ + +#include <string> + +/** + * Format namespace. + */ +namespace fmt { + +/** + * Enumeration of supported colors. + */ +enum Color { + Default = 0, + Black, + Red, + Green, + Yellow, + Blue, + Magenta, + Cyan, + LightGray, + DarkGray, + LightRed, + LightGreen, + LightYellow, + LightBlue, + LightMagenta, + LightCyan, + White +}; + +/** + * Enumeration of supported attributes. + */ +enum Attributes { + None = 0, + Bold = (1 << 0), //! [1m + Dim = (1 << 1), //! [2m + Underline = (1 << 2), //! [4m + Blink = (1 << 3), //! [5m + Reverse = (1 << 4), //! [7m + Hidden = (1 << 5) //! [8m +}; + +/** + * Create a mask for the foreground color. + * + * @param color the foreground color + * @return the correct mask + */ +constexpr unsigned short fg(unsigned short color) noexcept +{ + return color << 6; +} + +/** + * Create a mask for the background color. + * + * @param color the background color + * @return the correct mask + */ +constexpr unsigned short bg(unsigned short color) noexcept +{ + return color << 11; +} + +/** + * Return a formatted string with escape sequences. The string is terminated with reset sequence. + * + * Flags is defined as following: + * + * b b b b b f f f | f f a a a a a a + * + * Where: + * - b is the background color + * - g is the foreground color + * - a are attributes + * + * The attributes and colors are OR'ed together and to specify the background or foreground + * you must use the dedicated fg() and bg() functions. + * + * @param input the input string + * @param flags the flags + * @return the formatted string + * @example convert(fg(Red) | bg(White) | Bold | Underline); + */ +std::string convert(std::string input, unsigned short flags); + +} // !fmt + +#endif // !_FORMAT_H_