osmanip icon indicating copy to clipboard operation
osmanip copied to clipboard

A cross-platform library for output stream manipulation using ANSI escape sequences.

A library used to manipulate the output stream of a program using ANSI escape sequences. Features: colors and styles manipulators, progress bars and terminal graphics.

v4.1 license C++17
code size repo size total lines codeq doc


Table of contents

  • Introduction
  • News from the latest releases
  • List of features
    • ANSI escape sequences manipulators
    • Progress bars
    • Terminal graphics
    • Extra support for UNICODE and ANSI on Windows
  • Install and use
    • Install
    • Use in your device
    • Compile examples and test codes
  • Useful scripts
  • Repository structure
  • Todo
  • Credits
    • Project leaders
    • Other contributors
    • Other contributors with no GitHub account

Introduction

osmanip is a C++ library containing useful tools to manipulate ANSI escape sequences and customize the output stream of your programs. Within this tools you can add colors and styles to the printed strings, change cursor location on the terminal and manage other tools like progress bars and terminal graphics. Using this features may be very useful to adorn your general output stream log or to perform cursor operations.

If you want to mention this software in one of your project / articles, please cite it.

If you want to contribute to the repository, please read this file before.

Code documentation is generated using Doxygen and can be accessed here. An extra wiki is also provided and contains how-to guides and many examples.

Colors and styles manipulators examples:

Progress bars examples:

2D terminal-graphics examples:

The software is and will stay free, but if you want to support me with a donation it would be really appreciated!

Buy Me A Coffee

Supported operating systems

  • Linux
    • Ubuntu (tested)
  • Windows (release 10 or higher)
    • Cygwin64 (tested)
    • MSYS2 (tested)
    • MinGW (tested)
    • WSL (tested)
  • MacOS

News from the latest releases

  • Added a OS_Decorator class to efficiently manage the output stream style of a program.
  • Added the Wiki of the library.
  • Added full support to Windows operating system.
  • Added full support to MacOS operating system.

List of features

ANSI escape sequences manipulators

#include <iostream>
#include <osmanip/manipulators/colsty.hpp>

// Print a red string
std::cout << osm::feat( osm::col, "red" ) << "This string is red!" << osm::feat( osm::rst, "color" );

// Print a bold string
std::cout << osm::feat( osm::sty, "red" ) << "This string is bold!" << osm::feat( osm::rst, "bd/ft" );
#include <iostream>
#include <osmanip/manipulators/cursor.hpp>

// Move the cursor right by 2 spaces
std::cout << osm::feat( osm::crs, "right", 2 ) << "Cursor moved!";
#include <iostream>
#include <osmanip/manipulators/cursor.hpp>

// Output a bell sound
std::cout << osm::feat( osm::tcs, "bell" );
#include <iostream>
#include <osmanip/manipulators/printer.hpp>

// Similar to the Python "print" function
osm::print( std::cout, "This is the ", "\"print\" ", "function for the normal output stream! ", 100, "% working!" );
#include <iostream>
#include <osmanip/manipulators/printer.hpp>

osm::OS_Decorator my_shell;

// Change std::cout predefined style and color
my_shell.setColor( "green", std::cout );
my_shell.setStyle( "underlined", std::cout );

my_shell( std::cout ) << "The stdout stream has been changed using the OS_Decorator class!" << "\n";

// Change std::cerr predefined style and color
my_shell.setColor( "red", std::cerr );
my_shell.setStyle( "bold italics", std::cerr ); // NOTE: added 2 styles

my_shell( std::cerr ) << "The stderr stream has been changed using the OS_Decorator class!" << "\n";

More examples and how-to guides can be found here.

Why choosing this library for ANSI escape sequences manipulation:

  • All the functions used to manipulate these sequences are very easy to use and don't require complex code signatures.
  • All the most common ANSI sequences can be manipulated.
  • Using the OS_Decorator class you can set the style of an output stream at the beginning of your program and keep it unchanged until the end.

Progress bars

#include <iostream>
#include <osmanip/progressbar/progressbar.hpp>
#include <osmanip/utility/options.hpp>

osm::ProgressBar<int> percentage_bar;

percentage_bar.setMin( 5 );
percentage_bar.setMax ( 46 );
percentage_bar.setStyle( "indicator", "%" );

std::cout << "This is a normal percentage bar: " << "\n";
osm::OPTION( osm::CURSOR::OFF ); // Hide cursor for better output rendering
 for ( int i = percentage_bar.getMin(); i < percentage_bar.getMax(); i++ )
  {
   percentage_bar.update( i );
   //Do some operations...
  }
osm::OPTION( osm::CURSOR::ON );
#include <iostream>
#include <osmanip/progressbar/progressbar.hpp>
#include <osmanip/utility/options.hpp>

osm::ProgressBar<int> loading_bar( 3, 25 );

loading_bar.setStyle( "loader", "#" );
loading_bar.setBrackets( "{", "}" );
loading_bar.setMessage( "processing..." );

std::cout << "This is a normal loading bar: " << "\n";
osm::OPTION( osm::CURSOR::OFF ); // Hide cursor for better output rendering
for ( int i = loading_bar.getMin(); i < loading_bar.getMax(); i++ )
 {
  loading_bar.update( i );
  //Do some operations...
 }
osm::OPTION( osm::CURSOR::ON );
#include <iostream>
#include <osmanip/progressbar/progressbar.hpp>
#include <osmanip/utility/options.hpp>

osm::ProgressBar<int> progress_bar( 3, 25 );

progress_bar.setStyle( "complete", "%", "■" );
progress_bar.setBrackets( "[", "]" );
progress_bar.setMessage( "elaborating..." );
progress_bar.setRemainingTimeFlag( "on" );
progress_bar.setColor( "red" );

std::cout << "This is a mixed progress bar with color and time remaining info: " << "\n";
osm::OPTION( osm::CURSOR::OFF ); // Hide cursor for better output rendering
for ( int i = progress_bar.getMin(); i < progress_bar.getMax(); i++ )
 {
  progress_bar.update( i );
  //Do some operations...
 }
osm::OPTION( osm::CURSOR::ON );
#include <iostream>
#include <osmanip/progressbar/progressbar.hpp>
#include <osmanip/utility/options.hpp>

osm::ProgressBar<int> spinner;

spinner.setMin( 2 );
spinner.setMax ( 33 );
spinner.setStyle( "spinner", "/-\\|" );

std::cout << "This is a progress spinner: " << "\n";
osm::OPTION( osm::CURSOR::OFF ); // Hide cursor for better output rendering
for ( int i = spinner.getMin(); i < spinner.getMax(); i++ )
 {
  spinner.update( i );
  //Do some operations...
 }
osm::OPTION( osm::CURSOR::ON );

More examples and how-to guides can be found here.

Why choosing this library for progress bars? Some properties:

  • Extremely easy to use.
  • Compatible with positive or negative variable of any standard type (integer, float, double and others).
  • Maximum and minimum values can be set with any value you prefer and the progress bars will be self-built with respect to them.
  • Each progress bar feature can be fully customized (messages, style, color, brackets type, time remaining info etc...) regarding to your requirements. You can also choose to use only a progress indicator or a loading bar instead of a complete progress bar.
  • It is thread-safe, hence you can use also multiple progress bars simultaneously.

Terminal graphics

#include <osmanip/manipulators/colsty.hpp>
#include <osmanip/graphics/canvas.hpp>

osm::Canvas canvas(10,10);

canvas.setBackground( '.', osm::feat( osm::col, "bg white" ) + osm::feat( osm::col, "black" ) );
std::cout << "Display an animation in a canvas\n";

for( uint i = 0; i < 10; i++ )
 {
  canvas.clear();
  canvas.put( 0, 2, 'x' );
  canvas.put( i, 3, 'A', osm::feat( osm::col, "red" ) );
  canvas.put( 5, 0, 'B', osm::feat( osm::col, "blue" ) );
  canvas.put( 7, 8, 'Z', osm::feat( osm::col, "bg cyan" ) + osm::feat( osm::col, "black" ) + osm::feat( osm::sty, "bold" ) );
  canvas.refresh();
 }
#include <functional>
#include <osmanip/manipulators/colsty.hpp>
#include <osmanip/graphics/canvas.hpp>

osm::Plot2DCanvas plot_2d_canvas( 50, 20 );

std::cout << "\n" << "Plot2DCanvas with sin and cos" << "\n";
plot_2d_canvas.setBackground( ' ', osm::feat( osm::col, "bg white" ) );
plot_2d_canvas.enableFrame( true );
plot_2d_canvas.setFrame( osm::FrameStyle::BOX, osm::feat( osm::col, "bg white" ) + osm::feat( osm::col, "black" ) );
plot_2d_canvas.enableFrame( true );
plot_2d_canvas.setFrame( osm::FrameStyle::BOX, osm::feat( osm::col, "bg white" ) + osm::feat( osm::col, "black" ) );
plot_2d_canvas.setScale( 1/3.14, 0.2) ;

for( float i = 0; i < 40; i++ )
 {
  plot_2d_canvas.setOffset( i/3.14, -2 );
  plot_2d_canvas.clear();
  plot_2d_canvas.draw( std::function <float( float )>( []( float x ) -> 
                       float{ return std::cos( x ); } ), 'X', osm::feat( osm::col, "bg white" ) + osm::feat( osm::col, "bd red" ) );
  plot_2d_canvas.draw( std::function <float( float )>( []( float x ) -> 
                       float{ return std::sin( x ); } ), 'X', osm::feat( osm::col, "bg white" ) + osm::feat( osm::col, "bd blue" ) );
  plot_2d_canvas.refresh();
  sleep_for( milliseconds( 100 ) );
 }

More examples and how-to guides can be found here.

Why choosing this library for terminal graphics:

  • There are very few C++ libraries doing this job, and this is one of them.
  • High level of customizability.
  • A faster and most comfortable alternative to plot simple functions without the needing of GUI.

Extra support for UNICODE and ANSI on Windows

// Enable ANSI escape sequences
osm::OPTION( osm::ANSI::ON );
// doing some stuff...
osm::OPTION( osm::ANSI::ON );
// Enable unicode characters
osm::OPTION( osm::UNICODECH::ON );
// doing some stuff...
osm::OPTION( osm::UNICODECH::ON );

More examples and how-to guides can be found here.

Install and use

Install

Steps to be reproduced:

1) Download one of the releases of the repository

2) Unzip and enter the downloaded repository directory

3) Install and compile the library and its dependencies with the installer script

./script/install.sh

This script supports the installation on Ubuntu, MacOS and Windows operating systems.

NOTE: if you are on Cygwin64 you may get an error related to the \r character. To solve it run the dos2unix command on the script (ex: dos2unix install.sh) before running it.

A new library libosmanip.a will be created into the /usr/lib folder of your computer and the header files will be installed into /usr/include path.

NOTE: if you are on MacOS or Windows the paths are slightly different (looks at install.sh).

Mandatory prerequisites (automatically installed with the script):

  • C++17 standard.
  • g++ compiler (g++ 9.3.0 has been tested so far) for compilation.
  • GNU make for compilation.
  • Boost library.
  • arsenalgear library.

Optional prerequisites for developers:

  • Valgrind to run the debug.sh script.
  • Cppcheck to run the debug.sh script.
  • Clang formatter to format the code for pull requests.
  • wget to download extra dependencies repositories.
  • unzip to unzip zipped directories during download and installation.
  • Doxygen for documentation generation while developing.
  • doctest for testing.
  • hurry.filesize for size_of_dir.py script.
  • termcolor for size_of_dir.py script.
  1. EXTRA: to update the repository after some time
./scripts/update.sh
./scripts/install.sh
  1. EXTRA: to uninstall the repository from the system
./scripts/uninstall.sh

Use in your device

Tu use on or more headers of the library:

#include <osmanip/module_folder/module_name.hpp>

If you are using the library in a program, add the -losmanip flag to link source code.

NOTE: remember also to add -pthread flag if you want to use some thread-dependent libraries like progressbar/multi_progress_bar.hpp.

Compile examples and test codes

To compile example codes:

make main

To run all examples:

./bin/manipulators
./bin/progressbar
./bin/graphics

NOTE: executables end with .exe if you are on Windows of course.

To compile tests:

make tests

To run tests:

./bin/tests

NOTE: executables end with .exe if you are on Windows of course.

There is also an option to go back to the pre-compilation state of the code, to do this simply type this command:

make clean

Useful scripts

Other scripts have been provided into the scripts folder. After compiling the source code, they can be run from the repository home directory.

The debug.sh script is used to run Valgrind and Cppcheck debugging tools on the whole code.

You can run Valgrind debugging tools with a specific executable:

./scripts/debug_cpp.sh [valgrind-tool-name] [executable-name]

Repository structure

osmanip/
├── .github/
│   ├── workflows/
│   │   ├── DocGenerator.yml
│   │   ├── codeql-analysis.yml
├── img/
├── include/
│   ├── graphics/
│   │   ├── canvas.hpp
│   │   ├── plot_2D.hpp
│   ├── manipulators/
│   │   ├── colsty.hpp
│   │   ├── cursor.hpp
│   │   ├── common.hpp
│   │   ├── printer.hpp
│   ├── progressbar/
│   │   ├── progress_bar.hpp
│   │   ├── multi_progress_bar.hpp
│   ├── utility/
│   │   ├── windows.hpp
│   │   ├── options.hpp
├── src/
│   ├── graphics/
│   │   ├── canvas.cpp
│   │   ├── plot_2D.cpp
│   ├── manipulators/
│   │   ├── colsty.cpp
│   │   ├── cursor.cpp
│   │   ├── common.cpp
│   │   ├── printer.hpp
│   ├── progressbar/
│   │   ├── progress_bar.cpp
│   │   ├── multi_progress_bar.cpp
│   ├── utility/
│   │   ├── windows.cpp
├── examples/
│   ├── manipulators.cpp
│   ├── progressbar.cpp
│   ├── graphics.cpp
├── scripts/
│   ├── debug.sh
│   ├── install.sh
│   ├── uninstall.sh
│   ├── update.sh
│   ├── size_of_dir.py
├── test/
│   ├── graphics/
│   │   ├── tests_canvas.cpp
│   │   ├── tests_plot_2D.cpp
│   ├── manipulators/
│   │   ├── tests_common.cpp
│   │   ├── tests_colsty.cpp
│   │   ├── tests_cursor.cpp
│   │   ├── tests_printer.cpp
│   ├── progressbar/
│   │   ├── tests_progress_bar.cpp
│   │   ├── tests_multi_progress_bar.cpp
│── README.md
│── CONTRIBUTING.md
│── LICENSE
│── CITATION.cff
│── Makefile
│── Doxyfile
│── .gitignore
│── .clang-format
│── .valgrindrc
│── .gitignore
│── .all-contributorsrc

Todo

ANSI escape sequences manipulators

  • Add UNICODE characters manipulators.
  • Add new methods to the OS_decorator class.
  • Implement file redirection when manipulating the output.

Progress bars

  • Add an elapsedTime() method to show elapsed progress bar time and substitute it to the already existing getTime() method.

Terminal graphics

  • Add a method to set the Legend of a plot.
  • Add automatic plot resize.
  • Add option to display axes.
  • Extend the 2D terminal-graphics to 3D.

System features

  • Improve the compilation using CMake.
  • Benchmarking and other studies with respect to similar libraries.

Credits

Project leaders


Gianluca Bianco

Other contributors


MiguelMJ

Ted Lyngmo

myermo

nick-botticelli

Other contributors with no GitHub account