Skip to content

ibnunes/Escape

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Escape the ANSI Escape Code hell

This project aims to provide small, easily mantainable "libraries" allowing developers to add some flair to their CLI apps through ANSI Escape Codes (AEC) without the need to manually manage those codes.

Languages

Not in alphabetical order nor by preference:

  • C (standard: ≥C99)
  • C++ (standard: ≥C++20)
  • C#
  • Delphi (Object Pascal)
  • Python 3
  • OCaml
  • Pascal
  • [WIP] sh — command language:
    • zsh
    • Bash
  • Haskell
  • Java
  • Kotlin
  • Rust
  • Swift

The codes

The ANSI Escape Codes used can be found in AEC.md.

Usage examples

Expected output:

Expected output

zsh

echo "$(font bold fg_red)Fatality!$(font reset) An error has not occurred :("
echo "And here is a $(font italic fg 69)Color Test, Standard$(font reset)."
echo "$(font italic underline bg 100 50 9)Color Test, RGB$(font reset), and also $(font underline italic fg 9 100 50)Color Test, RGB$(font reset)"

To be used, it is recommended to place escape.zsh in a folder like ~/.zshrc.d and add the following to .zshrc:

source ~/.zshrc.d/escape.zsh

Escape is used in the zshrc project, being directly provided by it. It can be out-of-date, however, since the two projects are independent and thus have different workflows.

Python 3

from escape import Ansi.escape as font

# With formatted strings
print( f"{font('bold', 'fg_red')}Fatality!{font('reset')} An error has not occurred :(" )
print( f"And here is a {font('italic', 'fg', 69)}Color Test, Standard{font('reset')}." )

# And with the str.format method
print( "{1}Color Test, RGB{0}, and also {2}Color Test, RGB{0}".format(    \
    font('reset'),                                                        \
    font('italic', 'underline', 'bg', 100, 50, 9),                        \
    font('underline', 'italic', 'fg', 9, 100, 50) ) )

C

#define __FONT_AS_ANSI_ESCAPE__
#include "escape.h"
#include <stdio.h>

int main(void) {
    printf("%s%s%s\n", font(BOLD, FG_RED), "Fatality!", nofont);
    printf("%s%s%s%s%s\n", "And here is a ", font(ITALIC, FG(69)), "Color Test, Standard", nofont, ".");
    printf("%s%s%s%s%s%s%s\n", font(UNDERLINE, ITALIC, BG(100, 50, 9)), "Color Test, RGB", nofont, ", and also ", font(ITALIC, FG(9, 100, 50), ITALIC), "Color Test, RGB", nofont);
    return 0;
}

C++20

  • Ansify<codes...>("string"): Works with any string in runtime;
  • AnsifyS<length, codes...>("string"): Run in compile-time, needing the exact length of the string as first template parameter (excluding \0) — reads as "Ansify Static".

No version is currently available for previous C++ standards. See at the end how to contribute.

#include "escape.hpp"
#include <iostream>

using namespace std;
using namespace Ansi;

int main(void) {
    cout << AnsifyS<9, Code::BOLD, Code::FG_RED>("Fatality!") << " An error has not occurred :(" << endl;
    cout << "And here is a " << Ansify<Code::ITALIC, Color::FG<69>>("Color Test, Standard") << "." << endl;
    cout << AnsifyS<15, Code::UNDERLINE, Color::BG<100, 50, 9>, Code::ITALIC>("Color Test, RGB") <<
        ", and also " << Ansify<Code::ITALIC, Code::UNDERLINE, Color::FG<9, 100, 5>>("Color Test, RGB") << endl;
    return 0;
}

OCaml

open Escape

let () =
  let () = ansify [Bold; Fg_Red] "Fatality" ^ " An error has not occurred :(" |> print_endline in
  let () = "And here is a " ^ ansify [Italic; Fg 69] "Color Test, Standard" ^ "." |> print_endline in
    ansify [Underline; Italic; Bgx (100, 50, 9)] "Color Test, RGB" ^ ", and also " ^ ansify [Fgx (9, 100, 50); Underline; Italic] "Color Test, RGB" |> print_endline

Pascal

{$mode objfpc}
program test;
uses escape;

begin
    writeln( Ansify([BOLD, FG_RED], 'Fatality!'), ' An error has not occurred! :(' );
    writeln( 'And here is a ', Ansify([ITALIC, FG, 69], 'Color Test, Standard'), '.' );
    writeln( Ansify([UNDERLINE, BG, 100, 50, 9, ITALIC], 'Color Test, RGB'), ', and also ', Ansify([UNDERLINE, FG, 9, 100, 50, ITALIC], 'Color Test, RGB') );
end.

Delphi (Object Pascal)

Tested in Free Pascal Compiler, version 3.2.2.

{$mode delphi}
program test;
uses escape;

begin
    writeln( Ansify([BOLD, FG_RED], 'Fatality!'), ' An error has not occurred! :(' );
    writeln( 'And here is a ', Ansify([ITALIC, FG(69)], 'Color Test, Standard'), '.' );
    writeln( Ansify([UNDERLINE, BG(100, 50, 9), ITALIC], 'Color Test, RGB'), ', and also ', Ansify([UNDERLINE, FG(9, 100, 50), ITALIC], 'Color Test, RGB') );
end.

C#

using Escape;

public static void Main() {
  //With formatted strings
  Console.WriteLine($"{AecEscape.Escape(Aec.Bold, Aec.FgRed)}Fatality!{AecEscape.Escape(Aec.Reset)} An error has not occurred! :(");
  Console.WriteLine($"And here is a {AecEscape.Escape(Aec.Italic, Aec.Fg, 69)}Color Test, Standard{AecEscape.Escape(Aec.Reset)}.");

  //And with the string.Format method
  Console.WriteLine(
      string.Format(
          "{1}Color Test, RGB{0}, and also {2}Color Test, RGB{0}",
          AecEscape.Escape(Aec.Reset),
          AecEscape.Escape(Aec.Underline, Aec.Italic, Aec.Bg, 100, 50, 9),
          AecEscape.Escape(Aec.Underline, Aec.Italic, Aec.Fg, 9, 100, 50)
      )
  );
}

License

The software is provided without warranty and as is under the GNU General Public License version 2.

Roadmap

Notice! This section can be expanded without prior notice.

  • [WIP] Add fundamental function to apply AECs to the languages in the initial list.
  • Add support to interpolated AECs.
  • Add support to more CSIs (Control Sequence Introducers).

Contribute

Notice! This section can be expanded as needed without prior notice.

These are the current guidelines for contribution:

  1. Contributions shall be provided via forks.
  2. All AEC descriptors must be the same across supported languages as long as it is feasible or possible.
  3. Each supported language must have at least one dedicated branch.
  4. The branch dev is to have the current status of all supported languages.
  5. Current working changes are to be merged into dev though Pull Requests1.
  6. Changes to be merged to main are to be done exclusively through Pull Requests2

Footnotes

  1. Except for Collaborators and the Owner.

  2. Except the Owner in exceptional circumstances to be explicitly provided in the merge message.

About

Escape the ANSI escape code hell (multi-language)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors