Giter VIP home page Giter VIP logo

eliminmax / colortest Goto Github PK

View Code? Open in Web Editor NEW
2.0 1.0 0.0 271 KB

Code to print out a test pattern for 256-color terminals, written in many languages

C 2.41% JavaScript 3.04% Python 2.18% Shell 38.19% Brainfuck 15.84% Rust 2.25% Perl 2.19% Java 3.47% Ruby 2.26% C# 3.49% Go 2.13% PowerShell 2.95% Haskell 1.61% Kotlin 2.21% R 2.14% Scala 2.29% PHP 2.23% C++ 2.54% Fortran 3.39% COBOL 3.20%
256-colors terminal console-application ansi-escape-codes ansi-colors ansi-escape-sequences ansi-escape

colortest's Introduction

Colortest

A series of tiny, non-interactive programs written in various languages that all output a specific, strictly-defined pattern of ANSI escape codes and whitespace to create a 256-color test pattern, and generate it following a specific procedure.

Each program is entirely my original work unless otherwise noted. My understanding and comfort with the languages I've used varies greatly.

Languages

At the current moment, I've implemented it in the following languages:

  • AWK
  • Algol 68
  • Babalang (an esoteric programming language inspired by the puzzle game Baba is you. The specification is here and the official interpreter is available here
  • Befunge
  • Brainfuck
  • C
  • C#
  • C++
  • Cobol
  • D
  • DC (desk calculator - a very early UNIX stack-based RPN calculator that predates C. Works in the GNU implementation, but not portable to some other implementations. Described by the Esolangs wiki as "the esoteric language that 'made it big'", presumably due to its obscure syntax.)
  • Elixir
  • Erlang (via Escript)
  • Fender (a language created by 3 of my fellow Champlain College students in my senior year, available here)
  • Forth
  • Fortran
  • Go
  • Haskell
  • Java
  • JavaScript (via Node.js)
  • Kotlin
  • Lisp (Common Lisp)
  • Lua
  • Nim
  • Objecive-C (lightly tweaked C implementation)
  • Odin
  • OCaml
  • Octave (the GNU project's MATLAB-like analytical language)
  • Pascal (via FreePascal) (in memory of Niklaus Wirth)
  • Perl
  • PHP
  • PowerShell
  • Python
  • R
  • Rockstar (an esoteric programming language based on 80s metal and power ballads. Specification and reference implementation are here)
  • Ruby
  • Rust
  • Scala
  • Scheme
  • Shell Script (should work in any POSIX shell)
  • TypeScript (lightly tweaked JavaScript implementation) (via ts-node)
  • Vala
  • x86_64 assembly (NASM Intel-style syntax, 64-bit Linux System calls)
  • Zig

For instructions on how to run any specific implementation on Debian GNU/Linux 12 (Bookworm), see HOW_TO_RUN.md. All languages have been run in a Debian 12 Podman container with the instructions in that document.

I am experienced with some of those languages, and others I learned barely enough to implement this program as I was working on them.

Questions and Answers

Why?

Why not? It's what I find fun, and it's not the first time I've messed with ANSI escape sequences in the terminal.

It also gives me a sense of how different languages are designed.

The details

The output of the program should look like this:

Screenshot of Colortest output

The following is the pattern itself, with the ASCII escape character replaced by '␛':


␛[48;5;0m  ␛[48;5;1m  ␛[48;5;2m  ␛[48;5;3m  ␛[48;5;4m  ␛[48;5;5m  ␛[48;5;6m  ␛[48;5;7m  ␛[48;5;8m  ␛[48;5;9m  ␛[48;5;10m  ␛[48;5;11m  ␛[48;5;12m  ␛[48;5;13m  ␛[48;5;14m  ␛[48;5;15m  ␛[0m

␛[48;5;16m  ␛[48;5;17m  ␛[48;5;18m  ␛[48;5;19m  ␛[48;5;20m  ␛[48;5;21m  ␛[0m  ␛[48;5;52m  ␛[48;5;53m  ␛[48;5;54m  ␛[48;5;55m  ␛[48;5;56m  ␛[48;5;57m  ␛[0m  ␛[48;5;88m  ␛[48;5;89m  ␛[48;5;90m  ␛[48;5;91m  ␛[48;5;92m  ␛[48;5;93m  ␛[0m
␛[48;5;22m  ␛[48;5;23m  ␛[48;5;24m  ␛[48;5;25m  ␛[48;5;26m  ␛[48;5;27m  ␛[0m  ␛[48;5;58m  ␛[48;5;59m  ␛[48;5;60m  ␛[48;5;61m  ␛[48;5;62m  ␛[48;5;63m  ␛[0m  ␛[48;5;94m  ␛[48;5;95m  ␛[48;5;96m  ␛[48;5;97m  ␛[48;5;98m  ␛[48;5;99m  ␛[0m
␛[48;5;28m  ␛[48;5;29m  ␛[48;5;30m  ␛[48;5;31m  ␛[48;5;32m  ␛[48;5;33m  ␛[0m  ␛[48;5;64m  ␛[48;5;65m  ␛[48;5;66m  ␛[48;5;67m  ␛[48;5;68m  ␛[48;5;69m  ␛[0m  ␛[48;5;100m  ␛[48;5;101m  ␛[48;5;102m  ␛[48;5;103m  ␛[48;5;104m  ␛[48;5;105m  ␛[0m
␛[48;5;34m  ␛[48;5;35m  ␛[48;5;36m  ␛[48;5;37m  ␛[48;5;38m  ␛[48;5;39m  ␛[0m  ␛[48;5;70m  ␛[48;5;71m  ␛[48;5;72m  ␛[48;5;73m  ␛[48;5;74m  ␛[48;5;75m  ␛[0m  ␛[48;5;106m  ␛[48;5;107m  ␛[48;5;108m  ␛[48;5;109m  ␛[48;5;110m  ␛[48;5;111m  ␛[0m
␛[48;5;40m  ␛[48;5;41m  ␛[48;5;42m  ␛[48;5;43m  ␛[48;5;44m  ␛[48;5;45m  ␛[0m  ␛[48;5;76m  ␛[48;5;77m  ␛[48;5;78m  ␛[48;5;79m  ␛[48;5;80m  ␛[48;5;81m  ␛[0m  ␛[48;5;112m  ␛[48;5;113m  ␛[48;5;114m  ␛[48;5;115m  ␛[48;5;116m  ␛[48;5;117m  ␛[0m
␛[48;5;46m  ␛[48;5;47m  ␛[48;5;48m  ␛[48;5;49m  ␛[48;5;50m  ␛[48;5;51m  ␛[0m  ␛[48;5;82m  ␛[48;5;83m  ␛[48;5;84m  ␛[48;5;85m  ␛[48;5;86m  ␛[48;5;87m  ␛[0m  ␛[48;5;118m  ␛[48;5;119m  ␛[48;5;120m  ␛[48;5;121m  ␛[48;5;122m  ␛[48;5;123m  ␛[0m

␛[48;5;124m  ␛[48;5;125m  ␛[48;5;126m  ␛[48;5;127m  ␛[48;5;128m  ␛[48;5;129m  ␛[0m  ␛[48;5;160m  ␛[48;5;161m  ␛[48;5;162m  ␛[48;5;163m  ␛[48;5;164m  ␛[48;5;165m  ␛[0m  ␛[48;5;196m  ␛[48;5;197m  ␛[48;5;198m  ␛[48;5;199m  ␛[48;5;200m  ␛[48;5;201m  ␛[0m
␛[48;5;130m  ␛[48;5;131m  ␛[48;5;132m  ␛[48;5;133m  ␛[48;5;134m  ␛[48;5;135m  ␛[0m  ␛[48;5;166m  ␛[48;5;167m  ␛[48;5;168m  ␛[48;5;169m  ␛[48;5;170m  ␛[48;5;171m  ␛[0m  ␛[48;5;202m  ␛[48;5;203m  ␛[48;5;204m  ␛[48;5;205m  ␛[48;5;206m  ␛[48;5;207m  ␛[0m
␛[48;5;136m  ␛[48;5;137m  ␛[48;5;138m  ␛[48;5;139m  ␛[48;5;140m  ␛[48;5;141m  ␛[0m  ␛[48;5;172m  ␛[48;5;173m  ␛[48;5;174m  ␛[48;5;175m  ␛[48;5;176m  ␛[48;5;177m  ␛[0m  ␛[48;5;208m  ␛[48;5;209m  ␛[48;5;210m  ␛[48;5;211m  ␛[48;5;212m  ␛[48;5;213m  ␛[0m
␛[48;5;142m  ␛[48;5;143m  ␛[48;5;144m  ␛[48;5;145m  ␛[48;5;146m  ␛[48;5;147m  ␛[0m  ␛[48;5;178m  ␛[48;5;179m  ␛[48;5;180m  ␛[48;5;181m  ␛[48;5;182m  ␛[48;5;183m  ␛[0m  ␛[48;5;214m  ␛[48;5;215m  ␛[48;5;216m  ␛[48;5;217m  ␛[48;5;218m  ␛[48;5;219m  ␛[0m
␛[48;5;148m  ␛[48;5;149m  ␛[48;5;150m  ␛[48;5;151m  ␛[48;5;152m  ␛[48;5;153m  ␛[0m  ␛[48;5;184m  ␛[48;5;185m  ␛[48;5;186m  ␛[48;5;187m  ␛[48;5;188m  ␛[48;5;189m  ␛[0m  ␛[48;5;220m  ␛[48;5;221m  ␛[48;5;222m  ␛[48;5;223m  ␛[48;5;224m  ␛[48;5;225m  ␛[0m
␛[48;5;154m  ␛[48;5;155m  ␛[48;5;156m  ␛[48;5;157m  ␛[48;5;158m  ␛[48;5;159m  ␛[0m  ␛[48;5;190m  ␛[48;5;191m  ␛[48;5;192m  ␛[48;5;193m  ␛[48;5;194m  ␛[48;5;195m  ␛[0m  ␛[48;5;226m  ␛[48;5;227m  ␛[48;5;228m  ␛[48;5;229m  ␛[48;5;230m  ␛[48;5;231m  ␛[0m

␛[48;5;232m  ␛[48;5;233m  ␛[48;5;234m  ␛[48;5;235m  ␛[48;5;236m  ␛[48;5;237m  ␛[48;5;238m  ␛[48;5;239m  ␛[48;5;240m  ␛[48;5;241m  ␛[48;5;242m  ␛[48;5;243m  ␛[48;5;244m  ␛[48;5;245m  ␛[48;5;246m  ␛[48;5;247m  ␛[48;5;248m  ␛[48;5;249m  ␛[48;5;250m  ␛[48;5;251m  ␛[48;5;252m  ␛[48;5;253m  ␛[48;5;254m  ␛[48;5;255m  ␛[0m

The MD5 checksum of the output should be 5ee6c8ad78719bc2a515fbee5957ba06. Note: I am aware that it is trivial to find MD5 hash collisions, and would not rely on MD5 for security under any circumstance. Given the assumption that it looks right, and I just want to validate that nothing is off about the whitespace, I think it should be fine.

Each implementation consists of 3 parts, each of which begins with a specific comment and follows the same general structure across implementations, though there is some flexibility depending on the specifics of the language.

Note that in the following pseudocode, print is assumed not to add a trailing newline, for loops work the way they do in C, and within strings, \e represents the ASCII escape character and \n represents the ASCII newline character.

Part 1 begins with the following comment:

Print the first 16 colors - these vary by terminal configuration

The general structure of part 1 can be expressed with the following pseudocode:

print("\n")
for (i=0; i < 16; i++) {
  print("\e[48;5;{i}m  ")
}
print("\e[0m\n\n")

Part 2 begins with the following comment:

Print the 6 sides of the color cube - these are more standardized, but the order is a bit odd, thus the need for this trickery

The general structure of part 2 can be expressed with the following pseudocode:

for (i=16; i < 52; i+=6) {
  for (ii=0; ii < 6; ii++) {
    print("\e[48;5;{i+ii}m  ")
  }
  print("\e[0m  ")
  for (ii=36; ii < 42; ii++) {
    print("\e[48;5;{i+ii}m  ")
  }
  print("\e[0m  ")
  for (ii=72; ii < 78; ii++) {
    print("\e[48;5;{i+ii}m  ")
  }
  print("\e[0m\n")
}
print("\n")
for (i=124; i < 160; i+=6) {
  for (ii=0; ii < 6; ii++) {
    print("\e[48;5;{i+ii}m  ")
  }
  print("\e[0m  ")
  for (ii=36; ii < 42; ii++) {
    print("\e[48;5;{i+ii}m  ")
  }
  print("\e[0m  ")
  for (ii=72; ii < 78; ii++) {
    print("\e[48;5;{i+ii}m  ")
  }
  print("\e[0m\n")
}
print("\n")

Part 3 begins with the following comment:

Finally, the 24 grays

The general structure of part 3 can be expressed with the following pseudocode:

for (i=232; i < 256; i++) {
  print("\e[48;5;{i}m  ")
}
print("\e[0m\n\n")

colortest's People

Contributors

eliminmax avatar

Stargazers

 avatar  avatar

Watchers

 avatar

colortest's Issues

AWK implementation uses non-standard "\x1b"

According to Appendix A section 7 of the GAWK (GNU AWK) documentation (link), using \xNN to represent a character with the hex value 0xNN, is not part of the AWK standard (here). That said, the GAWK documentation page states that it is supported by gawk, mawk, and Brian Kernighan's awk, which it states are "the three most widely used freely available versions of awk". When testing for portability, I tested against those 3, as well as the BusyBox AWK implementation, which appears to also support the \xNN functionality, so I did not catch it.

Possible license issue

The OCaml implementation uses a snippet from StackOverflow, which I credited properly.

The problem is that StackOverflow code snippets are CC-BY-SA license, which is not GPL compatible.

Need to rewrite the code snippet in question

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.