Skip to content

Commit

Permalink
Support changing color mode at runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-matsui committed May 26, 2022
1 parent e8f922a commit 9086b11
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1626,10 +1626,53 @@ std::cerr << toml::format_error("[error] value should be positive",
hints, /*colorize = */ true) << std::endl;
```
Note: It colorize `[error]` in red. That means that it detects `[error]` prefix
Note: It colorizes `[error]` in red. That means that it detects `[error]` prefix
at the front of the error message. If there is no `[error]` prefix,
`format_error` adds it to the error message.
Compared to the `TOML11_COLORIZE_ERROR_MESSAGE` macro that enables colorization
statically, toml11 provides `toml::color::enable` & `toml::color::disable`
functions to dynamically change the color mode. This feature overwrites
`TOML11_COLORIZE_ERROR_MESSAGE` and the `colorize` argument of
`toml::format_error` when you call `enable`.
Note: If either `TOML11_COLORIZE_ERROR_MESSAGE` is defined or the `colorize`
argument is used, it takes precedence, meaning that `disable` won't work.
Accordingly, we highly recommend using only one of them.
```cpp
toml::color::enable(); // enable colorization
toml::color::disable(); // disable colorization
```
If you use user-defined error message, you can manage the setting as follows:
```cpp
toml::color::enable();
std::cerr << toml::format_error("[error] value should be positive",
data.at("num"), "positive number required",
hints) << std::endl; // colorized
toml::color::disable();
std::cerr << toml::format_error("[error] value should be positive",
data.at("num"), "positive number required",
hints) << std::endl; // NOT colorized
```
Or you may use toml11 in your application like:
```cpp
std::vector<std::string> args(argv + 1, argv + argc);
auto result = std::find(args.begin(), args.end(), "--color");
if (result != args.end()) {
toml::color::enable();
} else {
toml::color::disable();
}
// use toml11 ...
```
## Opting out of the default `[error]` prefix
toml11 prints error messages with the `[error]` prefix by default.
Expand Down
37 changes: 37 additions & 0 deletions toml/color.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,36 @@ namespace color_ansi
{
namespace detail
{

inline int colorize_index()
{
static const int index = std::ios_base::xalloc();
return index;
}

// Control color mode globally
class color_mode {
public:
inline void enable() {
should_color_ = true;
}
inline void disable() {
should_color_ = false;
}

inline bool should_color() const {
return should_color_;
}

static color_mode& status() {
static color_mode status_;
return status_;
}

private:
bool should_color_ = false;
};

} // detail

inline std::ostream& colorize(std::ostream& os)
Expand Down Expand Up @@ -55,6 +80,18 @@ inline std::ostream& cyan (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[36m";} return os;}
inline std::ostream& white (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[37m";} return os;}

inline void enable() {
return detail::color_mode::status().enable();
}
inline void disable() {
return detail::color_mode::status().disable();
}

inline bool should_color() {
return detail::color_mode::status().should_color();
}

} // color_ansi

// ANSI escape sequence is the only and default colorization method currently
Expand Down
2 changes: 1 addition & 1 deletion toml/source_location.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ inline std::string format_underline(const std::string& message,

std::ostringstream retval;

if(colorize)
if(color::should_color() || colorize)
{
retval << color::colorize; // turn on ANSI color
}
Expand Down

0 comments on commit 9086b11

Please sign in to comment.