A lightweight header-only C++ library to bring colors to your Windows console with a very-easy-to-use API that frees you from the burden of setting and resetting screen colors every time you make a call.
Put color.hpp
in the folder where you include headers.
For Windows. C++11 support required. C++14 or above recommended.
#include "../include/color.hpp"
#include <iostream>
int main()
{
std::cout << dye::aqua("Hello, World!") << std::endl;
return 0;
}
You are seeing Hello, World!
in aqua.
Try saying Hello, World yourself.
No need to reset : most solutions on the market work like manipulators, which constantly require you to reset the screen color after you set it. While this traditional approach is also offered in this library in the hue
namespace
cout << "When in doubt, wear " << hue::red << "red" << hue::reset << "." << endl;
it can be boring to do so. Why not just dye
the object
cout << "When in doubt, wear " << dye::red("red") << "." << endl;
Object-oriented : you may dye
an object and save it for later (re)use
auto green = dye::green("green");
cout << "I saw "<< green << " trees, " << green << " bushes." << endl;
dye
anything : int
double
char
std::string
...
cout << "Take the " << dye::blue("Blue") << " Line and then "
<< "catch Bus " << dye::yellow(42 + 7 % 8) << "."<< endl;
In fact, you can dye
any object for which operator<<
is properly defined. Suppose we have
struct DoubleVector;
ostream & operator<<(ostream &, const DoubleVector &);
we are free to dye
cout << dye::purple(DoubleVector{3.14, 2.72}) << endl;
+
dyed objects, even colors differ :
cout << dye::light_red('A') + dye::light_blue('B') + dye::light_green('C') << endl;
Extra support for strings : be it std::string
or C-style strings, dyed or undyed, you can mix them up without caring about their types.
const char ca[] = "ca";
string str = "str";
cout << "[ " + dye::aqua(ca) + " | " + dye::aqua(str) + " ]" << endl;
Convenient and extensible API : say colorize
an object according to the parameter, or quickly invert
the color
double a = 88.88;
cout << dye::colorize(a, a >= 0 ? "red" : "green").invert() << endl;
Try the above cases yourself.
With Color Console, we implement an auto marker which highlights keywords given in a watch list and colorizes numbers as well. The key function is
using namespace std;
auto mark(const string & str, string color)
{
istringstream iss(str);
auto marked = dye::vanilla("");
for (string line; getline(iss, line); marked += "\n") {
istringstream lineiss(line);
for (string text; lineiss >> text; marked += " ") {
string pre, word, post;
// split a text into 3 parts: word in middle, and punctuations around it
separate(text, pre, word, post);
marked += pre;
if (is_keyword(word))
marked += dye::colorize(word, color).invert();
else if (is_number(word))
marked += dye::colorize(word, color);
else
marked += word;
marked += post;
}
}
return marked;
}
To mark the introductory paragraph of a tech news
cout << mark(tech_news, "light_red") << endl;
You will see
As another example in which we mark both keywords and numbers
cout << mark(stock_news, "yellow") << endl;
We are having
For the details, see the full implementation.
Color Console offers two sets of solutions which are put separately in two namespaces
dye
( :star:highly recommended ) hue
There are 16 single colors and thus 256 combinations (text + background) supported by Windows console.
Know the color tags and dye
your console (or change its hue
) immediately!
Single / Text
black
blue
green
aqua
red
purple
yellow
white
grey
light_blue
light_green
light_aqua
light_red
light_purple
light_yellow
bright_white
Background
on_[single]
e.g. on_light_aqua
Compound
[single]_on_[single]
e.g. light_red_on_bright_white
Special
vanilla
do nothing i.e. stay in current console colordye
NamespaceAn object-oriented solution.
dye::color_tag(object)
generates a dyed object ready for colorized output
auto a = dye::on_yellow(42);
cout << a << endl;
You may use +
or +=
to make a chain of dyed objects. Colors may differ, so long as the types of the original objects stay the same.
using vec = DoubleVector;
auto b = dye::red(vec{1, 2, 3});
b = b + dye::blue(vec{4, 5, 6});
b += dye::green(vec{7, 8, 9});
cout << b << endl;
Rules for strings are even more flexible. You may +
or +=
any compatible strings, even those undyed ones.
cout << dye::on_white(string("strings")) + " are " +
dye::on_white("more") + string(" flexible") << endl;
dye::colorize(object, color_tag)
dyes object
with color_tag
cout << dye::colorize("grape", "purple") << endl;
dye::invert(dyed)
generates a new object in inverted color. dyed.invert()
does that in place.
cout << dye::invert(dye::red("red")) << endl;
auto contrast = dye::vanilla("contrast");
cout << contrast.invert() << endl;
Try the above cases yourself.
hue
NamespaceA console-oriented, manipulator-like, traditional solution.
cout << hue::color_tag
to set the text color to color_tag
cout << hue::reset
to reset the console color (to white text and black background)
#include "../include/color.hpp"
#include <iostream>
int main()
{
std::cout << hue::light_red << hue::on_bright_white
<< "Hello, World" << hue::reset << std::endl;
return 0;
}
Try saying Hello, World in the traditional manner.
Note: Do remember to reset
, otherwise you're causing troubles to late-users of the console.
+
operations are supported between dyed objects, especially for temporaries. Since more rvalues than lvalues are expected in use, we adopt a pass-by-value-and-move pattern.dye::red
and the like are in fact template factory functions that spit out dyed objects. Function template argument deduction is made use of to free users from having to specify the types explicitly (e.g. dye::red<std::string>("hello")
).dye::item<T>
to hold a single object, and a container dye::colorful<item<T>>
to hold item
(s). item
is intermediate and kept internally. Users are always using colorful
, of one or many item
(s).bar<T>
) is employed so that even function template argument deduction concludes it sees a const char *
the dyed object generated would be based on std::string
.