Browse Source

Squashed 'dist/termcolor/' content from commit 9a832a1

git-subtree-dir: dist/termcolor
git-subtree-split: 9a832a1756c67074331f257f3896656318440ba2
main
tastytea 1 year ago
commit
6c33fb4dce
  1. 3
      .gitignore
  2. 1
      .mailmap
  3. 156
      .travis.yml
  4. 55
      CMakeLists.txt
  5. 31
      LICENSE
  6. 236
      README.rst
  7. 4
      cmake/config.cmake.in
  8. BIN
      docs/_static/example.png
  9. 36
      docs/conf.py
  10. 11
      docs/index.rst
  11. 23
      examples/cmake-external/CMakeLists.txt
  12. 10
      examples/cmake-external/example.cpp
  13. 17
      examples/cmake-fetch/CMakeLists.txt
  14. 10
      examples/cmake-fetch/example.cpp
  15. 7
      examples/cmake-package/CMakeLists.txt
  16. 10
      examples/cmake-package/example.cpp
  17. 7
      examples/cmake-submodule/CMakeLists.txt
  18. 10
      examples/cmake-submodule/example.cpp
  19. 911
      include/termcolor/termcolor.hpp
  20. 151
      test/test.cpp

3
.gitignore vendored

@ -0,0 +1,3 @@
*.o
build/
docs/_build

1
.mailmap

@ -0,0 +1 @@
Ihor Kalnytskyi <ihor@kalnytskyi.com> <igor@kalnitsky.org>

156
.travis.yml

@ -0,0 +1,156 @@
language: cpp
script:
- eval "CXX=${COMPILER} CXXFLAGS=-std=c++11"
- cmake -DTERMCOLOR_TESTS=ON .
- cmake --build .
- ./test_termcolor
jobs:
include:
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages: g++-5
env: COMPILER="g++-5"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages: g++-6
env: COMPILER="g++-6"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages: g++-7
env: COMPILER="g++-7"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-3.8
packages: clang-3.8
env: COMPILER="clang++-3.8"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-3.9
packages: clang-3.9
env: COMPILER="clang++-3.9"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-4.0
packages: clang-4.0
env: COMPILER="clang++-4.0"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-5.0
packages: clang-5.0
env: COMPILER="clang++-5.0"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-6.0
packages: clang-6.0
env: COMPILER="clang++-6.0"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-7
packages: clang-7
env: COMPILER="clang++-7"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
packages: clang-8
env: COMPILER="clang++-8"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
packages: clang-9
env: COMPILER="clang++-9"
- os: osx
osx_image: xcode10
- os: osx
osx_image: xcode11
- os: windows
script:
- cmake -DTERMCOLOR_TESTS=ON .
- cmake --build .
- ./Debug/test_termcolor.exe
- os: windows
script:
- cmake -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DTERMCOLOR_TESTS=ON -G "MinGW Makefiles" .
- cmake --build .
- ./test_termcolor
- script:
- mkdir -p /tmp/termcolor && cd "$_"
- cmake $TRAVIS_BUILD_DIR
- sudo make install
- mkdir -p /tmp/example && cd "$_"
- cmake $TRAVIS_BUILD_DIR/examples/cmake-package
- make && ./example
name: cmake package
- script:
- sudo pip install cmake
- mkdir -p /tmp/example && cd "$_"
- /usr/local/bin/cmake $TRAVIS_BUILD_DIR/examples/cmake-fetch
- make && ./example
name: cmake fetch
- script:
- mkdir -p /tmp/example && cd "$_"
- cmake $TRAVIS_BUILD_DIR/examples/cmake-submodule
- make && ./example
name: cmake submodule
- script:
- mkdir -p /tmp/example && cd "$_"
- cmake $TRAVIS_BUILD_DIR/examples/cmake-external
- make && ./example
name: cmake external
notifications:
email: false

55
CMakeLists.txt

@ -0,0 +1,55 @@
cmake_minimum_required(VERSION 3.0)
project(termcolor)
#
# target
#
add_library(${PROJECT_NAME} INTERFACE)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_11)
#
# tests
#
option(TERMCOLOR_TESTS "Build termcolor tests." OFF)
if(TERMCOLOR_TESTS)
add_executable(test_${PROJECT_NAME} test/test.cpp)
target_link_libraries(
test_${PROJECT_NAME} ${PROJECT_NAME}::${PROJECT_NAME})
endif()
#
# install
#
include(CMakePackageConfigHelpers)
configure_package_config_file(
cmake/config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/generated/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME})
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/${PROJECT_NAME}-config.cmake
DESTINATION lib/cmake/${PROJECT_NAME})
install(
DIRECTORY include/
DESTINATION include)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}-targets
INCLUDES DESTINATION include)
install(
EXPORT ${PROJECT_NAME}-targets
NAMESPACE ${PROJECT_NAME}::
DESTINATION lib/cmake/${PROJECT_NAME})

31
LICENSE

@ -0,0 +1,31 @@
Copyright (c) 2013, Ihor Kalnytskyi.
All rights reserved.
Redistribution and use in source and binary forms of the software as well
as documentation, with or without modification, are permitted provided
that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

236
README.rst

@ -0,0 +1,236 @@
Termcolor
=========
.. image:: docs/_static/example.png
:alt: termcolor in action
:align: left
.. -*- inclusion-marker-for-sphinx-docs -*-
Termcolor_ is a header-only C++ library for printing colored messages to the
terminal. Written just for fun with a help of `the Force`_. Termcolor uses
`ANSI color formatting`_, so you can use it on every system that is used such
terminals (most \*nix systems, including Linux and Mac OS).
.. note::
On Windows, `Windows API`_ is used instead of escape codes but some
limitations are applied (not everything is supported). That's why it's
recommended to enter `virtual terminal processing`_ mode and set
``TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES`` macro to trick termcolor to use
ANSI color codes.
.. _virtual terminal processing: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
It's licensed under the BSD (3-clause) License. That basically means: do
whatever you want as long as copyright sticks around.
.. _Termcolor: https://github.com/ikalnytskyi/termcolor
.. _the Force: https://starwars.wikia.com/wiki/The_Force
.. _ANSI color formatting: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
.. _Windows API: https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute
Installation
------------
* Add ``termcolor.hpp`` (grab it from ``include/termcolor/termcolor.hpp``) to
the project and use stream manipulators from the ``termcolor`` namespace.
* You can also use vcpkg_ to install the library:
.. code:: sh
$ vcpkg install termcolor
.. _vcpkg: https://github.com/microsoft/vcpkg
* Or if you are on macOS, you can use Homebrew_ for that purpose:
.. code:: sh
$ brew install termcolor
.. _Homebrew: https://brew.sh/
* For up-to-date information about existing packages, refer to the the following
picture:
.. image:: https://repology.org/badge/vertical-allrepos/termcolor.svg
:target: https://repology.org/project/termcolor/versions
:alt: Packaging Status
How to use?
-----------
It's very easy to use. The idea is built upon C++ stream manipulators.
Typical «Hello World» application looks like this:
.. code:: c++
#include <iostream>
#include <termcolor/termcolor.hpp>
int main(int /*argc*/, char** /*argv*/)
{
std::cout << termcolor::red << "Hello, "; // 16 colors
std::cout << termcolor::color<100> << "Colorful "; // 256 colors
std::cout << termcolor::color<211, 54, 130> << "World!"; // true colors
std::cout << std::endl;
return 0;
}
The application above prints a string using different colors. There is one
caveat though. You must not forget to reset colors, otherwise they will be
applied to other prints as well.
.. code:: c++
std::cout << termcolor::red << "Hello, Colorful World!" << std::endl;
std::cout << "I'm RED too!" << std::endl;
Correct version of the code above should look like this:
.. code:: c++
std::cout << termcolor::red << "Hello, Colorful World!" << termcolor::reset << std::endl;
std::cout << termcolor::reset << "Here I'm!" << std::endl;
By default, Termcolor ignores any colors for non-tty streams (e.g.
``std::stringstream``), so the following snippet
.. code:: c++
std::stringstream ss;
ss << termcolor::red << "unicorn";
std::cout << ss.str();
will print «unicorn» using default color, not red. In order to change this
behaviour one can use ``termcolor::colorize`` manipulator that enforce colors
no matter what.
What manipulators are supported?
--------------------------------
The manipulators are divided into four groups:
* *foreground*, which changes text color;
* *background*, which changes text background color;
* *attributes*, which changes some text style (bold, underline, etc);
* *control*, which changes termcolor's behaviour.
Also, there are color manipulators for `16 colors`_, `256 colors`_ and
`true colors`_ palettes.
.. note::
While ``termcolor`` supports true color, it's required for the terminal
emulator you use to run your software to support true color too. So please
ensure it's supported before filing an issue.
.. _16 colors: https://en.wikipedia.org/wiki/Color_depth#4-bit_color
.. _256 colors: https://en.wikipedia.org/wiki/Color_depth#8-bit_color
.. _true colors: https://en.wikipedia.org/wiki/Color_depth#True_color_(24-bit)
Foreground manipulators
.......................
16 colors
`````````
#. ``termcolor::grey``
#. ``termcolor::red``
#. ``termcolor::green``
#. ``termcolor::yellow``
#. ``termcolor::blue``
#. ``termcolor::magenta``
#. ``termcolor::cyan``
#. ``termcolor::white``
#. ``termcolor::bright_grey``
#. ``termcolor::bright_red``
#. ``termcolor::bright_green``
#. ``termcolor::bright_yellow``
#. ``termcolor::bright_blue``
#. ``termcolor::bright_magenta``
#. ``termcolor::bright_cyan``
#. ``termcolor::bright_white``
256 colors
``````````
#. ``termcolor::color<256_COLOR_CODE>``
true colors
```````````
#. ``termcolor::color<RED, GREEN, BLUE>``
Background manipulators
.......................
16 colors
`````````
#. ``termcolor::on_grey``
#. ``termcolor::on_red``
#. ``termcolor::on_green``
#. ``termcolor::on_yellow``
#. ``termcolor::on_blue``
#. ``termcolor::on_magenta``
#. ``termcolor::on_cyan``
#. ``termcolor::on_white``
#. ``termcolor::on_bright_grey``
#. ``termcolor::on_bright_red``
#. ``termcolor::on_bright_green``
#. ``termcolor::on_bright_yellow``
#. ``termcolor::on_bright_blue``
#. ``termcolor::on_bright_magenta``
#. ``termcolor::on_bright_cyan``
#. ``termcolor::on_bright_white``
256 colors
``````````
#. ``termcolor::on_color<256_COLOR_CODE>``
true colors
```````````
#. ``termcolor::on_color<RED, GREEN, BLUE>``
Attribute manipulators
......................
(Windows API does not support these manipulators except for ``underline``)
#. ``termcolor::bold``
#. ``termcolor::dark``
#. ``termcolor::italic``
#. ``termcolor::underline``
#. ``termcolor::blink``
#. ``termcolor::reverse``
#. ``termcolor::concealed``
#. ``termcolor::crossed``
Control manipulators
....................
(Windows API does not support these manipulators)
#. ``termcolor::colorize``
#. ``termcolor::nocolorize``
Caveats
-------
#. On Windows, due to internal usage of ``<windows.h>``, global namespace could
be polluted with `min`/`max` macros. If such effect is desireable, please
consider using ``#define NOMINMAX`` before ``#include <termcolor.hpp>``.

4
cmake/config.cmake.in

@ -0,0 +1,4 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@CMAKE_PROJECT_NAME@-targets.cmake")
check_required_components("@CMAKE_PROJECT_NAME@")

BIN
docs/_static/example.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

36
docs/conf.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""
termcolor's documentation settings
"""
from __future__ import unicode_literals
import os
# project information
project = 'termcolor'
copyright = '2013, Ihor Kalnytskyi'
version = '0.1'
release = '0.1'
# sphinx settings
extensions = []
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
exclude_patterns = ['_build']
pygments_style = 'sphinx'
highlight_language = 'c++'
# html output settings
html_theme = 'default'
html_static_path = ['_static']
# Unfortunately, Sphinx doesn't support code highlighting for standard
# reStructuredText `code` directive. So let's register 'code' directive
# as alias for Sphinx's own implementation.
#
# https://github.com/sphinx-doc/sphinx/issues/2155
from docutils.parsers.rst import directives
from sphinx.directives.code import CodeBlock
directives.register_directive('code', CodeBlock)

11
docs/index.rst

@ -0,0 +1,11 @@
:orphan:
Welcome to Termcolor C++ library
================================
.. image:: _static/example.png
:alt: termcolor in action
:align: center
.. include:: ../README.rst
:start-after: -*- inclusion-marker-for-sphinx-docs -*-

23
examples/cmake-external/CMakeLists.txt vendored

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.0)
project(example)
include(ExternalProject)
ExternalProject_Add(termcolor_project
GIT_REPOSITORY git://github.com/ikalnytskyi/termcolor.git
GIT_TAG origin/master
# Termcolor is a header-only library which means we need to
# neither configure nor build nor install it. Thus, noop
# the hooks.
CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "")
ExternalProject_Get_Property(termcolor_project SOURCE_DIR)
set(CMAKE_CXX_STANDARD 11)
include_directories(${SOURCE_DIR}/include)
add_library(termcolor INTERFACE IMPORTED)
add_dependencies(termcolor termcolor_project)
add_executable(${CMAKE_PROJECT_NAME} example.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor)

10
examples/cmake-external/example.cpp vendored

@ -0,0 +1,10 @@
#include <iostream>
#include <termcolor/termcolor.hpp>
int main(int /* argc */, char** /* argv */) {
std::cout
<< termcolor::yellow << "Warm welcome to "
<< termcolor::blue << termcolor::underline << "TERMCOLOR"
<< termcolor::reset << std::endl;
return 0;
}

17
examples/cmake-fetch/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.11)
project(example)
include(FetchContent)
FetchContent_Declare(termcolor
GIT_REPOSITORY git://github.com/ikalnytskyi/termcolor.git
GIT_TAG origin/master)
FetchContent_GetProperties(termcolor)
if(NOT termcolor_POPULATED)
FetchContent_Populate(termcolor)
add_subdirectory(${termcolor_SOURCE_DIR} ${termcolor_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
add_executable(${CMAKE_PROJECT_NAME} example.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor)

10
examples/cmake-fetch/example.cpp

@ -0,0 +1,10 @@
#include <iostream>
#include <termcolor/termcolor.hpp>
int main(int /* argc */, char** /* argv */) {
std::cout
<< termcolor::yellow << "Warm welcome to "
<< termcolor::blue << termcolor::underline << "TERMCOLOR"
<< termcolor::reset << std::endl;
return 0;
}

7
examples/cmake-package/CMakeLists.txt

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.0)
project(example)
find_package(termcolor REQUIRED)
add_executable(${CMAKE_PROJECT_NAME} example.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor::termcolor)

10
examples/cmake-package/example.cpp

@ -0,0 +1,10 @@
#include <iostream>
#include <termcolor/termcolor.hpp>
int main(int /* argc */, char** /* argv */) {
std::cout
<< termcolor::yellow << "Warm welcome to "
<< termcolor::blue << termcolor::underline << "TERMCOLOR"
<< termcolor::reset << std::endl;
return 0;
}

7
examples/cmake-submodule/CMakeLists.txt

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.0)
project(example)
add_subdirectory(../.. ${CMAKE_CURRENT_BINARY_DIR}/termcolor EXCLUDE_FROM_ALL)
add_executable(${CMAKE_PROJECT_NAME} example.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor::termcolor)

10
examples/cmake-submodule/example.cpp

@ -0,0 +1,10 @@
#include <iostream>
#include <termcolor/termcolor.hpp>
int main(int /* argc */, char** /* argv */) {
std::cout
<< termcolor::yellow << "Warm welcome to "
<< termcolor::blue << termcolor::underline << "TERMCOLOR"
<< termcolor::reset << std::endl;
return 0;
}

911
include/termcolor/termcolor.hpp

@ -0,0 +1,911 @@
//!
//! termcolor
//! ~~~~~~~~~
//!
//! termcolor is a header-only c++ library for printing colored messages
//! to the terminal. Written just for fun with a help of the Force.
//!
//! :copyright: (c) 2013 by Ihor Kalnytskyi
//! :license: BSD, see LICENSE for details
//!
#ifndef TERMCOLOR_HPP_
#define TERMCOLOR_HPP_
#include <iostream>
#include <cstdio>
// Detect target's platform and set some macros in order to wrap platform
// specific code this library depends on.
#if defined(_WIN32) || defined(_WIN64)
# define TERMCOLOR_TARGET_WINDOWS
#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
# define TERMCOLOR_TARGET_POSIX
#endif
// If implementation has not been explicitly set, try to choose one based on
// target platform.
#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP)
# if defined(TERMCOLOR_TARGET_POSIX)
# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES
# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION
# elif defined(TERMCOLOR_TARGET_WINDOWS)
# define TERMCOLOR_USE_WINDOWS_API
# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION
# endif
#endif
// These headers provide isatty()/fileno() functions, which are used for
// testing whether a standard stream refers to the terminal.
#if defined(TERMCOLOR_TARGET_POSIX)
# include <unistd.h>
#elif defined(TERMCOLOR_TARGET_WINDOWS)
# include <io.h>
# include <windows.h>
#endif
namespace termcolor
{
// Forward declaration of the `_internal` namespace.
// All comments are below.
namespace _internal
{
inline int colorize_index();
inline FILE* get_standard_stream(const std::ostream& stream);
inline bool is_colorized(std::ostream& stream);
inline bool is_atty(const std::ostream& stream);
#if defined(TERMCOLOR_TARGET_WINDOWS)
inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
#endif
}
inline
std::ostream& colorize(std::ostream& stream)
{
stream.iword(_internal::colorize_index()) = 1L;
return stream;
}
inline
std::ostream& nocolorize(std::ostream& stream)
{
stream.iword(_internal::colorize_index()) = 0L;
return stream;
}
inline
std::ostream& reset(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[00m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1, -1);
#endif
}
return stream;
}
inline
std::ostream& bold(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[1m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& dark(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[2m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& italic(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[3m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& underline(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[4m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE);
#endif
}
return stream;
}
inline
std::ostream& blink(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[5m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& reverse(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[7m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& concealed(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[8m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& crossed(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[9m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t code> inline
std::ostream& color(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
char command[12];
std::snprintf(command, sizeof(command), "\033[38;5;%dm", code);
stream << command;
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t code> inline
std::ostream& on_color(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
char command[12];
std::snprintf(command, sizeof(command), "\033[48;5;%dm", code);
stream << command;
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t r, uint8_t g, uint8_t b> inline
std::ostream& color(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
char command[20];
std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b);
stream << command;
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
template <uint8_t r, uint8_t g, uint8_t b> inline
std::ostream& on_color(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
char command[20];
std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b);
stream << command;
#elif defined(TERMCOLOR_USE_WINDOWS_API)
#endif
}
return stream;
}
inline
std::ostream& grey(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[30m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
0 // grey (black)
);
#endif
}
return stream;
}
inline
std::ostream& red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[31m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& green(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[32m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN
);
#endif
}
return stream;
}
inline
std::ostream& yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[33m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& blue(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[34m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE
);
#endif
}
return stream;
}
inline
std::ostream& magenta(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[35m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& cyan(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[36m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN
);
#endif
}
return stream;
}
inline
std::ostream& white(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[37m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& bright_grey(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[90m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
0 | FOREGROUND_INTENSITY // grey (black)
);
#endif
}
return stream;
}
inline
std::ostream& bright_red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[91m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& bright_green(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[92m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& bright_yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[93m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& bright_blue(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[94m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& bright_magenta(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[95m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& bright_cyan(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[96m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& bright_white(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[97m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_grey(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[40m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
0 // grey (black)
);
#endif
}
return stream;
}
inline
std::ostream& on_red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[41m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_green(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[42m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN
);
#endif
}
return stream;
}
inline
std::ostream& on_yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[43m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_blue(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[44m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE
);
#endif
}
return stream;
}
inline
std::ostream& on_magenta(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[45m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_cyan(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[46m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE
);
#endif
}
return stream;
}
inline
std::ostream& on_white(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[47m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_grey(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[100m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
0 | BACKGROUND_INTENSITY // grey (black)
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[101m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_green(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[102m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[103m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_blue(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[104m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_magenta(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[105m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_cyan(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[106m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
inline
std::ostream& on_bright_white(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES)
stream << "\033[107m";
#elif defined(TERMCOLOR_USE_WINDOWS_API)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY
);
#endif
}
return stream;
}
//! Since C++ hasn't a way to hide something in the header from
//! the outer access, I have to introduce this namespace which
//! is used for internal purpose and should't be access from
//! the user code.
namespace _internal
{
// An index to be used to access a private storage of I/O streams. See
// colorize / nocolorize I/O manipulators for details. Due to the fact
// that static variables ain't shared between translation units, inline
// function with local static variable is used to do the trick and share
// the variable value between translation units.
inline int colorize_index()
{
static int colorize_index = std::ios_base::xalloc();
return colorize_index;
}
//! Since C++ hasn't a true way to extract stream handler
//! from the a given `std::ostream` object, I have to write
//! this kind of hack.
inline
FILE* get_standard_stream(const std::ostream& stream)
{
if (&stream == &std::cout)
return stdout;
else if ((&stream == &std::cerr) || (&stream == &std::clog))
return stderr;
return nullptr;
}
// Say whether a given stream should be colorized or not. It's always
// true for ATTY streams and may be true for streams marked with
// colorize flag.