
Osmanip – это библиотека C++, предоставляющая полезные механизмы для работы с управляющими последовательностями ANSI и настройки потока вывода программ. С помощью этих механизмов вы можете оформлять выводимые строки различными цветами и стилями, изменять расположение курсора в терминале и регулировать прочие компоненты вроде индикаторов выполнения и графики. Весь этот функционал будет очень полезен для придания желаемого вида общему потоку вывода программы или для выполнения операций с курсором.
Если вы захотите использовать это ПО в своём проекте или упомянуть в статье, будьте добры, указывайте на его ссылку.
Если у вас возникнет желание внести свой вклад в репозиторий, сначала прочтите этот файл.
Документация кода сгенерирована при помощи Doxygen и доступна здесь. Помимо этого, есть ещё справочная страница GitHub, которая содержит дополнительные практические инструкции и множество примеров.
Вот некоторые из них:

Цвета и стили

Индикаторы выполнения

Двухмерная графика в терминале
Поддерживаемые ОС:
- Linux;
- Ubuntu (протестировано);
- Windows (версия 10 и выше);
- Cygwin64 (протестировано);
- MSYS2 (протестировано);
- MinGW (протестировано);
- WSL (протестировано);
- MacOS.
▍ Новости последних релизов
- добавлен класс
OS_Decoratorдля удобства управления стилизацией потока вывода программы; - добавлена справочная страница библиотеки;
- добавлена полная поддержка Windows и MacOS;
Список возможностей
▍ Механизмы работы с escape-последовательностями ANSI
#include <iostream> #include <osmanip/manipulators/colsty.hpp> // Вывод красной строки std::cout << osm::feat( osm::col, "red" ) << "This string is red!" << osm::feat( osm::rst, "color" ); // Вывод жирной строки std::cout << osm::feat( osm::sty, "red" ) << "This string is bold!" << osm::feat( osm::rst, "bd/ft" );
#include <iostream> #include <osmanip/manipulators/cursor.hpp> // Перемещение курсора вправо на два пробела std::cout << osm::feat( osm::crs, "right", 2 ) << "Cursor moved!";
Управляющие последовательности для терминала:
#include <iostream> #include <osmanip/manipulators/cursor.hpp> // Вывод звука колокольчика std::cout << osm::feat( osm::tcs, "bell" );
#include <iostream> #include <osmanip/manipulators/printer.hpp> // Аналог Python функции "print" 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; // Изменение предопределённого стиля и цвета std::cout 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"; // Изменение предопределённого стиля и цвета std::cerr my_shell.setColor( "red", std::cerr ); my_shell.setStyle( "bold italics", std::cerr ); // Примечание: добавлено 2 стиля my_shell( std::cerr ) << "The stderr stream has been changed using the OS_Decorator class!" << "\n";
Дополнительные примеры и инструкции можно найти здесь.
Почему для работы с escape-последовательностями стоит выбрать именно эту библиотеку:
- все функции использования этих последовательностей очень просты в использовании и не требуют сложных сигнатур кода.
- можно работать со всеми самыми популярными последовательностями.
- с помощью класса OS Decorator можно устанавливать стиль вывода в начале программы, сохраняя его неизменным до ее завершения.
▍ Индикаторы выполнения
#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 ); // Сокрытие курсора для лучшей отрисовки вывода for ( int i = percentage_bar.getMin(); i < percentage_bar.getMax(); i++ ) { percentage_bar.update( i ); //Выполнение операций... } 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 ); // Сокрытие курсора для лучшей отрисовки вывода for ( int i = loading_bar.getMin(); i < loading_bar.getMax(); i++ ) { loading_bar.update( i ); //Выполнение операций... } 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 ); // Сокрытие курсора для лучшей отрисовки вывода for ( int i = progress_bar.getMin(); i < progress_bar.getMax(); i++ ) { progress_bar.update( i ); //Выполнение операций... } 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 ); // Сокрытие курсора для лучшей отрисовки вывода for ( int i = spinner.getMin(); i < spinner.getMax(); i++ ) { spinner.update( i ); //Выполнение операций... } osm::OPTION( osm::CURSOR::ON );

Дополнительные примеры и инструкции можно найти здесь.
Преимущества использования именно этой библиотеки для реализации индикаторов выполнения:
- крайняя простота применения;
- поддерживает положительные и отрицательные переменные любого стандартного типа (
integer,float,doubleи прочих); - в качестве максимума и минимума можно установить любые нужные значения, и индикатор будет построен относительно них;
- каждый элемент индикатора настраивается (сообщения, стиль, цвет, тип скобок, оставшееся время и т.д.). Также можно использовать вместо смешанного прогресс бара только индикацию выполнения или загрузки.
- потокобезопасность, то есть можно одновременно использовать множество индикаторов выполнения.
▍ Графика в терминале
#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 ) ); }

Дополнительные примеры и инструкции можно найти здесь.
Преимущества реализации графики в терминале с помощью этой библиотеки:
- подобный функционал обеспечивается очень немногими библиотеками C++, и эта одна из них;
- высокий уровень кастомизируемости;
- более шустрая и удобная альтернатива отрисовке графиков простых функций без потребности в GUI.
▍ Дополнительная поддержка UNICODE и ANSI в Windows
// Активация escape-последовательностей ANSI osm::OPTION( osm::ANSI::ON ); // выполнение нужных действий... osm::OPTION( osm::ANSI::ON ); // Активация символов unicode osm::OPTION( osm::UNICODECH::ON ); // выполнение нужных действий... osm::OPTION( osm::UNICODECH::ON );
Дополнительные примеры и инструкции можно найти здесь.
Установка и использование
▍ Установка
1. Скачать один из релизов репозитория.
2. Распаковать архив и открыть каталог.
3. Установить и скомпилировать библиотеку с зависимостями при помощи установочного скрипта.
./script/install.sh
Этот скрипт поддерживает установку под Ubuntu, MacOS, Windows и прочими операционными системами.
Примечание: если вы работаете в Cygwin64, то можете получить ошибку, связанную с символом
\r. Чтобы её избежать, предварительно выполните для скрипта командуdos2unix.
В результате в каталоге /usr/lib создаётся новая библиотека, а файлы заголовков устанавливаются по пути /usr/include.
Примечание: если вы работаете в MacOS или Windows, пути будут несколько отличаться (см. install.sh).
Обязательные программы (устанавливаются автоматически скриптом):
- C++17;
- компилятор g++ (последняя протестированная версия 9.3.0);
- GNU make;
- библиотека Boost;
- библиотека arsenalgear.
Необязательные программы, для разработчиков:
- Valgrind для запуска скрипта debug.sh;
- Cppcheck для запуска скрипта debug.sh;
- Clang formatter для подготовки кода к пул-реквестам;
- wget для скачивания дополнительных репозиториев зависимостей;
- unzip для распаковки архивных каталогов во время скачивания и установки;
- Doxygen для генерации документации при разработке;
- doctest для тестирования;
- hurry.filesize для скрипта size_of_dir.py;
- termcolor для скрипта size_of_dir.py.
4. Дополнительно: для периодического обновления репозитория:
./scripts/update.sh ./scripts/install.sh
5. Дополнительно: для деинсталляции репозитория из системы:
./scripts/uninstall.sh
▍ Использование на вашем устройстве
Для использования одного или более заголовков библиотеки:
#include <osmanip/module_folder/module_name.hpp>
В случае использования библиотеки в программе добавьте флаг -losmanip для линковки исходного кода.
Примечание: не забудьте также добавить флаг
-pthread, если хотите использовать потокозависимые библиотеки вроде progressbar/multi_progress_bar.hpp.
▍ Компиляция примеров и тестирование
Компиляция примеров:
make main
Запуск примеров:
./bin/manipulators ./bin/progressbar ./bin/graphics
Примечание: если вы работаете в Windows, исполняемые файлы оканчиваются на .exe.
Компиляция тестов:
make tests
Запуск тестов:
./bin/tests
Также есть вариант вернуться обратно в состояние до компиляции. Для этого просто выполните:
make clean
▍ Полезные скрипты
Я добавил кое-какие дополнительные полезные скрипты в каталог scripts. После компиляции исходного кода их можно будет запустить из домашнего каталога репозитория.
Скрипт debug.sh используется для запуска отладчиков Valgrind и Cppcheck для всего кода.
Valgrind можно запустить через отдельный исполняемый файл:
./scripts/debug_cpp.sh [valgrind-tool-name] [executable-name]
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
▍ Дальнейшие планы
- Работа с escape-последовательностями ANSI:
- добавить механизмы работы с символами UNICODE;
- добавить в класс
OS_decoratorновые методы; - реализовать перенаправление файлов при работе с выводом.
- Индикаторы выполнения:
- добавить метод
elapsedTime()для отображения пройденного времени выполнения, заменив им существующий методgetTime();
- добавить метод
- Графика для терминала:
- добавить метод для сопровождения графиков легендой;
- добавить автоматическое изменение размера графика;
- добавить опцию отображения осей;
- расширить 2D графику до 3D;
- Системный функционал:
- улучшить компиляцию с помощью CMake;
- сравнить библиотеку с аналогами на основе бенчмарков и прочих исследований.
ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/679758/

Добавить комментарий