A Minimal, Header only Modern c++ library for terminal goodies πŸ’„βœ¨

Overview

rang Build Status Build status codecov Download

Colors for your Terminal.

rang-demo

Windows Demo

rang-windows-demo

Example usage

#include "rang.hpp"

using namespace std;
using namespace rang;

int main()
{
    cout << "Plain old text"
         << style::bold << "Rang styled text!!"
         << style::reset << endl;
}

Dependencies

rang only depends on C++ standard library, unistd.h system header on unix and windows.h & io.h system headers on windows based systems. In other words, you don't need any 3rd party dependencies.

Installation

rang is a single header-only library. Put rang.hpp in the include folder directly into the project source tree or somewhere reachable from your project.

Or, if you use the conan package manager, follow these steps:

  1. Add a reference to rang to the requires section of your project's conanfile.txt file:

     [requires]
     rang/[email protected]/stable
    
  2. Run conan's install command:

     conan install
    

How to use

Rang uses iostream objects - cout/clog/cerr to apply attributes to output text. Since rang aims to support both windows and unix like systems, it takes care of the os specific details and tries to provide a uniform interface. Due to incompatiblities b/w different OS versions, not all kinds of attributes are supported on every system so rang will try to skip the ones which might produce garbage(instead of pushing random ANSI escape codes on your streams). Detection of tty is also handled internally so you don't need to check if application user might redirect output to a file.

Need support for non-ansi terminals? Check out Termdb which supports virtually all terminals and their capablities.

Apart from setting text attributes, you can also ask rang to override its default behaviour through these methods -

void rang::setControlMode(rang::control);

where rang::control takes

  • control::Auto - Automatically detects whether terminal supports color or not(Default)
  • control::Off - Turn off colors completely
  • control::Force - Force colors even if terminal doesn't supports them or output is redirected to non-terminal
void rang::setWinTermMode(rang::winTerm);

where rang::winTerm takes

  • winTerm::Auto - Checks for newer windows and picks Ansi otherwise falls back to Native(Default)
  • winTerm::Native - This method is supported in all versions of windows but supports less attributes
  • winTerm::Ansi - This method is supported in newer versions of windows and supports rich variety of attributes

Supported attributes with their compatiblity are listed below -

Text Styles:

Code Linux/Win/Others Old Win
rang::style::bold yes yes
rang::style::dim yes no
rang::style::italic yes no
rang::style::underline yes no
rang::style::blink no no
rang::style::rblink no no
rang::style::reversed yes yes
rang::style::conceal maybe yes
rang::style::crossed yes no

Text Color:

Code Linux/Win/Others Old Win
rang::fg::black yes yes
rang::fg::red yes yes
rang::fg::green yes yes
rang::fg::yellow yes yes
rang::fg::blue yes yes
rang::fg::magenta yes yes
rang::fg::cyan yes yes
rang::fg::gray yes yes

Background Color:

Code Linux/Win/Others Old Win
rang::bg::black yes yes
rang::bg::red yes yes
rang::bg::green yes yes
rang::bg::yellow yes yes
rang::bg::blue yes yes
rang::bg::magenta yes yes
rang::bg::cyan yes yes
rang::bg::gray yes yes

Bright Foreground Color:

Code Linux/Win/Others Old Win
rang::fgB::black yes yes
rang::fgB::red yes yes
rang::fgB::green yes yes
rang::fgB::yellow yes yes
rang::fgB::blue yes yes
rang::fgB::magenta yes yes
rang::fgB::cyan yes yes
rang::fgB::gray yes yes

Bright Background Color:

Code Linux/Win/Others Old Win
rang::bgB::black yes yes
rang::bgB::red yes yes
rang::bgB::green yes yes
rang::bgB::yellow yes yes
rang::bgB::blue yes yes
rang::bgB::magenta yes yes
rang::bgB::cyan yes yes
rang::bgB::gray yes yes

Reset Styles/Colors:

Code Linux/Win/Others Old Win
rang::style::reset yes yes
rang::fg::reset yes yes
rang::bg::reset yes yes

My terminal is not detected/gets garbage output!

Check your env variable TERM's value. Then open an issue here and make sure to mention TERM's value along with your terminal name.

Redirecting cout/cerr/clog rdbuf?

Rang doesn't interfere if you try to redirect cout/cerr/clog to somewhere else and leaves the decision to the library user. Make sure you've read this conversation and check out the example code here.

Issues
  • Feature: Unformatted Input

    Feature: Unformatted Input

    Note: This is work-in-progress code. There are things like printf statements and junk that are expected to be removed from the final commit. Also some things continue to be refactored between working commits.

    enhancement help wanted 
    opened by qbradq 26
  • Respect ANSICON environment variable on Windows

    Respect ANSICON environment variable on Windows

    If environment variable ANSICON is set on Windows, the console is capable of ANSI sequences, so preferably use them.

    What about this patch?

    --- a/include/rang.hpp +++ b/include/rang.hpp @@ -205,6 +205,7 @@ namespace rang_implementation { inline HANDLE getVersionDependentHandle() { if (IsWindowsVersionOrGreater(10, 0, 0)) return nullptr; + if (getenv("ANSICON")) return nullptr; return GetStdHandle(STD_OUTPUT_HANDLE); }

    Sorry for the formatting, it seems markup is mocking up ...

    opened by sbellon 18
  • add support for windows<10 (issue #2)

    add support for windows<10 (issue #2)

    • Old behavior is preserved for windows >=10
    • Windows version is checked dynamically
    • Console handle is statically stored for windows <10

    A bit verbose perhaps, but should do the trick

    opened by AxelStrem 16
  • MSVC not compiling when including

    MSVC not compiling when including "rang.hpp"

    I'm not sure what am I doing wrong but whenever I include "rang.hpp" outside of Main.cpp i get this compile error:

    error LNK2005: "void * __cdecl rang::rang_implementation::getVersionDependentHandle(void)" ([email protected][email protected]@@YAPAXXZ) already defined in [Wathever].obj

    Any idea what is happening ~~and how could I fix it~~?

    opened by tatjam 9
  • Fixed work on Windows during resetting bg/fg color

    Fixed work on Windows during resetting bg/fg color

    1. Fixed work on Windows during resetting bg/fg color, fixes #66
    2. Added support of Windows 10 ANSI terminal sequences
    3. Code should be work on native windows terminals
    opened by kingseva 8
  • add forceColor command which allows forcing color on non-tty devices

    add forceColor command which allows forcing color on non-tty devices

    Hey agauniyal, I tried my best at implementing the forceColor ostream modifier. I'm a first timer in PR's and would really appreciate if you could take a look and give me some criticism :smile:. I hope I didn't mess up too bad :sweat_smile:.

    Regarding the code, I don't really like to expose the getIword method, but I cannot think of any other way to give access to it.

    Hope this kind of helps and thanks in advance, benni012

    opened by benni012 8
  • Better CMake support

    Better CMake support

    This PR builds on the work of @zethon in #92 and a template I used for one of my projects

    • Basic package config file when installing the library
    • New CMakeLists.txt for the tests
    • CTest for test/test.cpp

    Hopefully, this makes integrating rang in other package managers (such as Hunter and Vcpkg) easier.

    opened by maddouri 7
  • Remove use of std::atomics

    Remove use of std::atomics

    Originally we had fully threadsafe Linux only code but along the way I'm realizing most users need to synchronize text output by themselves(mutex over cout), hence removal of thread safe code.

    opened by agauniyal 6
  • Undocumented Behavior: Not Thread-Safe in C++11

    Undocumented Behavior: Not Thread-Safe in C++11

    The implementation of rang::rang_implementation::getIword() is not thread-safe in a strictly standards-compliant C++11 compiler. According to this thread-saftey for std::ios_base::xalloc was standardized in C++14. Please document the library as thread-unsafe for C++11 compilers or change the implementation to use a synchronization object when required.

    bug 
    opened by qbradq 6
  • avoid multiple pointer copies

    avoid multiple pointer copies

    Current approach of capturing initial pointer to cout/clog/cerr buffer requires multiple copies since each .cpp file that'll include it will have their own copy.

    But since the lib is using just 3 pointers within internal linkage, the overhead is almost negligible. But it can be resolved by providing static returns from function, see this stackoverflow question.

    enhancement 
    opened by agauniyal 6
  • New release tag

    New release tag

    Is the code on master in a good state to be made into a new release? The last release is lacking the CMakeLists.txt file, so I'm forced to use master in my project when I pull this in. It'd be nice to have a release point to pull in instead.

    opened by zethon 5
  • A warning may be fixed

    A warning may be fixed

    When I used parameter -Wextra in g++, it gives a warning:

    [Warning] cast between incompatible function types from 'FARPROC' {aka 'long long int ()()'} to 'WINBOOL ()(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD)' {aka 'int ()(void, _FILE_INFO_BY_HANDLE_CLASS, void*, long unsigned int)'} [-Wcast-function-type]

    It's on line 175 in rang.hpp:

    inline bool isMsysPty(int fd) noexcept
        {
            // Dynamic load for binary compability with old Windows
            const auto ptrGetFileInformationByHandleEx
              = reinterpret_cast<decltype(&GetFileInformationByHandleEx)>(
                GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
                               "GetFileInformationByHandleEx"));
            if (!ptrGetFileInformationByHandleEx) {
                return false;
            }
    

    All the parameters I used under Windows 10 1903, g++ 8.1.0: g++ -std=c++2a -Wall -Wextra -Dlocal

    opened by SodiumCyanide 3
  • [feature request] Please support true-color terminals

    [feature request] Please support true-color terminals

    For example, see how the awk script on this page prints a colorful line on text: https://gist.github.com/XVilka/8346728

    kde/gnome/xfce4 terminals now support true-color, and C++ interface can certainly support this functionality.

    opened by yurivict 1
  • Created a RangBuffer class in response to (enhancement) issue #52

    Created a RangBuffer class in response to (enhancement) issue #52

    I created a RangBuffer class to store the display settings in an object. You might want to make a class 'buffer' inside rang namespace. It has setter functions to set the properties. This is how it works:

    RangBuffer rg;
    
    rg.setBgColor(rang::bg::cyan);
    rg.setFgBColor(rang::fgB::yellow);
    
    cout << rg << "hello world\n" << endl;
    rg.ignoreMySettings(cout);
    
    RangBuffer rg2;
    rg2.setBgBColor(rang::bgB::blue);
    cout << rg2 << "hello world\n";
    cout << rg << "This is my first contribution";
    

    There is a unique function RangBuffer::ignoreMysettings(std::ostream& os). It resets the ostream. So for example in the above code, the second line is displayed with a bright blue background and white foreground. Commenting that line will display the second line with a bright blue background and yellow colour (set by rg1).

    Now you might be wandering what's the difference between ignoreMySettings and reset()?

    • Reset resets the all the bitset (elementSet) to 0 in addition to resetting the terminal. So, after calling the clear function, it is as good as a new object.
    • IgnoreMySettings resets the terminal but does not reset the bitset. It means the next time the object is used to display using ostream.

    Plus, the design choice is such that say you have a common setting that the text you display is red, but at some point, you want red and the text to be bold, you can do this:

    RangBuffer rg;
    rg.setFgBColor(rang::fgB::red);
    
    cout << rang::style::bold << rg << "Hello world";
    rg.reset(cout);
    

    And it does all this without breaking code.

    I compiled my example on g++(version 8.2.1) and clang++(version 7.0) both on my Fedora 29. And it works as expected

    opened by HemilTheRebel 17
  • storing color in variable

    storing color in variable

    Hi ! this is not an issue. I get inspired by your library. I need to store style and fg color in a variable for a postponed usage. Here is the idea:

    rang::color mycolor = std::pair(rang::red, rang::italic);
    std::cout << mycolor << "hello" << std::endl;
    

    So why not adding in your lib something like:

    struct color
      {
        color(rang::style style,
              rang::fg fg,
              rang::bg bg = rang::bg::reset)
          : m_style(style), m_fg(fg), m_bg(bg)
        {
        }
    
        rang::style m_style;
        rang::fg m_fg;
        rang::bg m_bg;
      };
    
    inline std::ostream& setColor(std::ostream &os, rang::color const c)
      {
        return os << "\033["
          << static_cast<int>(c.m_fg) << ';'
          << static_cast<int>(c.m_bg) << ';'
          << static_cast<int>(c.m_style) << "m";
      }
    

    A simple test code could be:

    #define ERROR_COLOR  rang::color(rang::style::bold, rang::fg::red)
    rang::color c = ERROR_COLOR;
    std::cout << c << "hello" << std::endl;
    

    I dunno what could be the best: std::pair (ugly and long syntax but can be used with constexpr) or struct (drawback: make copy). personally I would prefer something like red | italic (but can achieve easily). Other solution ?

    (Maybe your lib already can do this, in this case ignore my comment)

    opened by Lecrapouille 9
Releases(v3.2)
  • v3.2(Jul 30, 2021)

  • v3.1.0(Feb 14, 2018)

    • Release date: 2018-02-14
    • Md5: 29539c60e2c0bfc8874c9da476de15c8

    Summary

    This is a minor release for rang which aims at delegating a potential UB on windows platform(note that even without this change it should be working fine since UB is present in winapi and supported by the platform itself).

    Support

    You can file issues here. And Pull Requests are always welcome.

    Once again, thanks to @kingseva for valuable contributions!

    Source code(tar.gz)
    Source code(zip)
    rang.hpp(14.96 KB)
  • v3.0(Jan 27, 2018)

    • Release date: 2018-01-28
    • Md5: 83cf6f86968457b5797e1ba5cdb2760b

    Summary

    This is the third release for rang - a Minimal, single header, Modern c++ library for colors in your terminal. Apart from a single removal, the rest of the interface is kept similar to last two releases. This release brings a few bug fixes, removal of <versionhelpers.h> dependency(credits to @vladimirgamalyan), better testing framework and ease of installation thanks to @conan-io. Newly written documentation has been added to project README.md as well!

    This release was possible due to significant contributions by @kingseva!

    Source code(tar.gz)
    Source code(zip)
    rang.hpp(14.74 KB)
  • 2.1(May 28, 2017)

    • Release date: 2017-05-28
    • Md5: ab029d8e257d17ea4ea9f5552619f6d0

    Summary

    This is a minor release for rang which aims at fixing minor issues like correcting escape code, std::string optimizations, adding fg::reset and bg::reset options and building rang library on windows properly.

    Support

    Everything else you need to know is inside the wiki. You can file issues here. And Pull Requests are always welcome.

    Thanks to @SuperV1234, @blastrock and @tatjam for their significant contributions to this release.

    Source code(tar.gz)
    Source code(zip)
    rang.hpp(6.05 KB)
  • v2.0(Dec 11, 2016)

    • Release date: 2016-12-11
    • Md5: 5bcac3439faf5e8ce0fc2eb5d10c0e44

    Summary

    This is the second release for rang - a simple, modern & header only c++11 library for colors in your terminal. The much-awaited windows support is finally here. Since it only needs a single header to get integrated with your project, no custom build system is required. However support for conan & meson build system is also provided.

    Support

    Everything else you need to know is inside the wiki. You can file issues here. And Pull Requests are always welcome.

    Thanks to @AxelStrem, @benni012, @zeokav and others for their significant contributions to this release.

    Source code(tar.gz)
    Source code(zip)
    rang.hpp(6.00 KB)
  • v1.0(Sep 3, 2016)

    • Release date: 2016-09-03
    • Md5: 3f6c3243ca9d32ae00504cfffd2f4c1e

    Summary

    This is the first release for rang - a simple, modern & header only c++11 library for colors in your terminal. Since it only needs a single header to get integrated with your project, no custom build system is required. However support for meson build system is also provided so you can use wrapdb.

    Support

    Everything else you need to know is inside the wiki. You can file issues here. And Pull Requests are always welcome.

    Source code(tar.gz)
    Source code(zip)
    rang.hpp(3.07 KB)
minimal but extensible header only implementation of photon mapping in C++

photon_mapping minimal but extensible header only implementation of photon mapping in C++. Features Direct illumination with explicit light sampling I

yumcyawiz 61 Jun 23, 2022
Tuibox - A single-header terminal UI (TUI) library, capable of creating mouse-driven, interactive applications on the command line.

tuibox tuibox ("toybox") is a single-header terminal UI library, capable of creating mouse-driven, interactive applications on the command line. It is

Andrew 8 May 31, 2022
The purpose of this project is to create a modern C++17 header-only interface to the FreeRTOS kernel API

FreeRTOS-Cpp The purpose of this project is to create a modern C++17 header-only interface to the FreeRTOS kernel API. Goals of this project include:

Jon Enz 14 Apr 23, 2022
A very minimal & simple text editor written in C with only Standard C Library.

Texterm Text Editor A very minimal & simple text editor written in C with only Standard Library. Syntax highlighting supported for C JavaScript Python

Biraj 37 Jun 3, 2022
Minimal, modern embedded V8 for Python.

Welcome to knight_v8 ?? Minimal, modern embedded V8 for Python. ?? Homepage Install pip install knight_v8 or: git clone https://github.com/Esbiya/knig

Esbiya 8 Feb 17, 2022
2D physics header-only library for videogames developed in C using raylib library.

Physac Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop to simluate physics. A physics step contai

VΓ­ctor Fisac 218 Jun 24, 2022
Library with useful output stream tools like: color and style manipulators, progress bars and terminal graphics.

Library with useful output stream tools like: color and style manipulators, progress bars and terminal graphics Table of contents Introduction Documen

Gianluca Bianco 104 May 30, 2022
Lightweight Windows/Linux terminal control library for C/C++

TerControl Table of Contents About TerControl Features Installation Contributing License Contact Thanks TerControl is a lightweight opinion based term

Zackery .R. Smith 3 Apr 2, 2022
A header-only library for C++(0x) that allows automagic pretty-printing of any container.

cxx-prettyprint =============== A pretty printing library for C++ containers. Synopsis: Simply by including this header-only library in your sourc

Louis Delacroix 526 Jun 9, 2022
Cross-platform C++11 header-only library for memory mapped file IO

mio An easy to use header-only cross-platform C++11 memory mapping library with an MIT license. mio has been created with the goal to be easily includ

null 1.3k Jun 24, 2022
A C++ header-only library for creating, displaying, iterating and manipulating dates

The ASAP date/time library for beautiful C++ code ASAP is a small, header-only date-time library for C++11 and beyond. It is heavily inspired by my gr

Leonardo Guilherme de Freitas 53 Jun 21, 2022
AssociatedEnum: header-only library for C++ for enumerations with associated values

asenum AssociatedEnum is a header-only library for C++ for enumerations with associated values asenum is C++ implementation of very neat enums from Sw

Vladimir (Alkenso) 17 Mar 9, 2022
A header only library that provides parser combinators to C++

This is an experimental C++ library for rapidly building parsers. It is inspired by parser combinators in haskell such as attoparsec and, like those libraries, allows for the construction of fully fledged parsers in a few lines of code.

Jotron AS 13 Apr 12, 2022
Small and dirty header-only library that supports user input with some more advanced features than in the standard lib.

dirty-term Small and dirty header-only library that supports user input with some more advanced features than in the standard lib. This small, lightwe

null 3 Apr 24, 2022
Small Extremely Powerful Header Only C++ Lexical Analyzer/String Parser Library

lexpp Small Extremely Powerful Header Only C++ Lexical Analyzer/String Parser Library Lexpp is made with simplicity and size in mind. The entire libra

Jaysmito Mukherjee 49 Jun 21, 2022
Header-only library providing unicode aware string support for C++

CsString Introduction CsString is a standalone library which provides unicode aware string support. The CsBasicString class is a templated class which

CopperSpice 89 Jun 4, 2022
Header-only library to instrument scopes in C++

ScopeTimer Header Only Library How to use it? Easy cheesy: If you need milliseconds, just specify it and the compiler will do the rest of the work: #i

Ignacio Vizzo 2 Nov 29, 2021
ServiceLocator - Service Locator Pattern Header-Only Library

Service Locator Very fast, header-only C++ Service Locator Pattern library What is the Service Locator Pattern The Service Locator Pattern is a design

Richard Zampieri 7 Feb 21, 2022