diff --git a/bytebeat_compiler.py b/bytebeat_compiler.py index c9f3207..ed2d225 100644 --- a/bytebeat_compiler.py +++ b/bytebeat_compiler.py @@ -4,7 +4,7 @@ from argparse import ArgumentParser from os import environ, makedirs from os.path import exists, join as path_join from shlex import split as command_line_split -from sys import stdin, exit +from sys import stdin, stdout, exit from typing import Dict, Union import subprocess @@ -41,6 +41,8 @@ DEFAULT_PARAMETERS = { "OUTPUT_FILE": PATHS["output"] } +stdout_atty = hasattr(stdout, "isatty") and stdout.isatty() + def fetch(name: str): if from_env := environ.get(name): return from_env @@ -137,6 +139,9 @@ if __name__ == "__main__": help="show progress during generation") parser.add_argument("-E", "--show-substituted-values", default=False, action="store_true", help="show substituted values") + parser.add_argument("--color", default="auto", type=str, + help="ANSI escape codes. Set to 'always' to enable them, 'none' to " + "disable. Default: 'auto'.") args = parser.parse_args() bytebeat_contents = read_from_file_or_stdin(args.file).strip() @@ -203,6 +208,9 @@ if __name__ == "__main__": gen_length = args.channels * samples + ansi_escape_codes_supported = args.color == "auto" and stdout_atty or \ + args.color == "always" + rewrite_file(PATHS["substitute"], substitute_vars({ "bytebeat_contents": bytebeat_contents, "output_file": C_str_repr(args.output), @@ -223,7 +231,8 @@ if __name__ == "__main__": "block_size": args.block_size, "silent_mode": args.silent, "verbose_mode": args.verbose and not args.silent, - "fwrite_le": PATHS["fwrite_le_header"] + "fwrite_le": PATHS["fwrite_le_header"], + "ansi_escape_codes_supported": ansi_escape_codes_supported }, read_file(PATHS["template"]), args.show_substituted_values)) # Compile by invoking the shell script diff --git a/src/template.c b/src/template.c index 38c8f85..a437855 100644 --- a/src/template.c +++ b/src/template.c @@ -10,14 +10,17 @@ #include "`fwrite_le`" // constants -#if defined(_WIN32) -# define __ANSI_CLEAR_STRING "\r" -#elif defined(__unix__) || defined(__linux__) -# define __ANSI_CLEAR_STRING "\x1B[2K\r" -#else -# define __ANSI_CLEAR_STRING "\n" +#define ANSI_ESCAPE_CODES_SUPPORTED `ansi_escape_codes_supported` + +#ifndef _ANSI_CLEAR_STRING /* can be defined during compilation */ +# if ANSI_ESCAPE_CODES_SUPPORTED +# define _ANSI_CLEAR_STRING "\x1B[2K\r" +# elif defined(_WIN32) +# define _ANSI_CLEAR_STRING "\r" +# else +# define _ANSI_CLEAR_STRING "\n" +# endif #endif -const char* ANSI_CLEAR = __ANSI_CLEAR_STRING; #define OUTPUT_FILE `output_file` @@ -310,7 +313,7 @@ main(void) " (part %" PRIuMAX "/%" PRIuMAX ")" #endif , - ANSI_CLEAR, + _ANSI_CLEAR_STRING, gen_length_minus_1 - time, ((long double) time * 100) / (long double) GEN_LENGTH #if SEQUENTIAL_MODE @@ -323,7 +326,7 @@ main(void) } #if !SILENT_MODE - printf(ANSI_CLEAR); + printf(_ANSI_CLEAR_STRING); // 5. log #if !(SEQUENTIAL_MODE && VERBOSE_MODE)