#include "iomanip.hpp" #include #include #include #include using namespace sc::io; static std::ostream& gray(std::ostream& out, int val, int code) { if (val < 0 || val > 23) { throw std::invalid_argument("gray value out of range"); } if (should_color(out)) out << "\x1b[" << code << ";5;" << 232 + val << "m"; return out; } static std::ostream& rgb(std::ostream& out, int r, int g, int b, int code) { if (r < 0 || r > 5 || g < 0 || g > 5 || b < 0 || b > 5) { throw std::invalid_argument("rgb color component out of range"); } if (should_color(out)) out << "\x1b[" << code << ";5;" << (16 + 36 * r + 6 * g + b) << "m"; return out; } bool sc::io::should_color(const std::ostream& out) { return !getenv("NO_COLOR") && isatty_ostream(out); } bool sc::io::isatty_ostream(const std::ostream& out) { return (&out == &std::cout && isatty(STDOUT_FILENO)) || (&out == &std::cerr && isatty(STDERR_FILENO)); } std::ostream& sc::io::hide_cursor(std::ostream& out) { if (should_color(out)) out << "\x1b[?25l"; return out; } std::ostream& sc::io::show_cursor(std::ostream& out) { if (should_color(out)) out << "\x1b[?25h"; return out; } std::ostream& sc::io::reset(std::ostream& out) { if (should_color(out)) out << "\x1b[m"; return out; } std::ostream& sc::io::bold(std::ostream& out) { if (should_color(out)) out << "\x1b[1m"; return out; } std::ostream& sc::io::italic(std::ostream& out) { if (should_color(out)) out << "\x1b[3m"; return out; } std::ostream& sc::io::underline(std::ostream& out) { if (should_color(out)) out << "\x1b[4m"; return out; } std::ostream& sc::io::overline(std::ostream& out) { if (should_color(out)) out << "\x1b[53m"; return out; } std::ostream& sc::io::strikethru(std::ostream& out) { if (should_color(out)) out << "\x1b[9m"; return out; } std::ostream& sc::io::blinkslow(std::ostream& out) { if (should_color(out)) out << "\x1b[5m"; return out; } std::ostream& sc::io::blinkfast(std::ostream& out) { if (should_color(out)) out << "\x1b[6m"; return out; } std::ostream& sc::io::reverse(std::ostream& out) { if (should_color(out)) out << "\x1b[7m"; return out; } std::ostream& sc::io::blackf(std::ostream& out) { if (should_color(out)) out << "\x1b[30m"; return out; } std::ostream& sc::io::redf(std::ostream& out) { if (should_color(out)) out << "\x1b[31m"; return out; } std::ostream& sc::io::greenf(std::ostream& out) { if (should_color(out)) out << "\x1b[32m"; return out; } std::ostream& sc::io::yellowf(std::ostream& out) { if (should_color(out)) out << "\x1b[33m"; return out; } std::ostream& sc::io::bluef(std::ostream& out) { if (should_color(out)) out << "\x1b[34m"; return out; } std::ostream& sc::io::magentaf(std::ostream& out) { if (should_color(out)) out << "\x1b[35m"; return out; } std::ostream& sc::io::cyanf(std::ostream& out) { if (should_color(out)) out << "\x1b[36m"; return out; } std::ostream& sc::io::whitef(std::ostream& out) { if (should_color(out)) out << "\x1b[37m"; return out; } std::ostream& sc::io::defaultf(std::ostream& out) { if (should_color(out)) out << "\x1b[39m"; return out; } std::ostream& sc::io::blackb(std::ostream& out) { if (should_color(out)) out << "\x1b[40m"; return out; } std::ostream& sc::io::redb(std::ostream& out) { if (should_color(out)) out << "\x1b[41m"; return out; } std::ostream& sc::io::greenb(std::ostream& out) { if (should_color(out)) out << "\x1b[42m"; return out; } std::ostream& sc::io::yellowb(std::ostream& out) { if (should_color(out)) out << "\x1b[43m"; return out; } std::ostream& sc::io::blueb(std::ostream& out) { if (should_color(out)) out << "\x1b[44m"; return out; } std::ostream& sc::io::magentab(std::ostream& out) { if (should_color(out)) out << "\x1b[45m"; return out; } std::ostream& sc::io::cyanb(std::ostream& out) { if (should_color(out)) out << "\x1b[46m"; return out; } std::ostream& sc::io::whiteb(std::ostream& out) { if (should_color(out)) out << "\x1b[47m"; return out; } std::ostream& sc::io::defaultb(std::ostream& out) { if (should_color(out)) out << "\x1b[49m"; return out; } sc::io::grayf::grayf(int val) : _val {val} {} std::ostream& sc::io::operator<<(std::ostream &out, const grayf& obj) { return gray(out, obj._val, 38); } sc::io::grayb::grayb(int val) : _val {val} {} std::ostream& sc::io::operator<<(std::ostream &out, const grayb& obj) { return gray(out, obj._val, 48); } sc::io::rgbf::rgbf(int r, int g, int b) : _r {r}, _g {g}, _b {b} {} std::ostream& sc::io::operator<<(std::ostream &out, const rgbf& obj) { return rgb(out, obj._r, obj._g, obj._b, 38); } sc::io::rgbb::rgbb(int r, int g, int b) : _r {r}, _g {g}, _b {b} {} std::ostream& sc::io::operator<<(std::ostream &out, const rgbb& obj) { return rgb(out, obj._r, obj._g, obj._b, 48); } sc::io::trgb::trgb(double r, double g, double b) : _r {r}, _g {g}, _b {b} {} sc::io::trgb::operator rgbf() { rgbf result { static_cast(floor(_r * 5)), static_cast(floor(_g * 5)), static_cast(floor(_b * 5)) }; return result; }