godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.22k stars 21.22k forks source link

Using print_rich with a hexidecimal color code results in the color tag being output to logs #97432

Open scott-lin opened 1 month ago

scott-lin commented 1 month ago

Tested versions

System information

Godot v4.3.stable.mono - Windows 10.0.19045 - GLES3 (Compatibility) - NVIDIA GeForce RTX 2080 (NVIDIA; 32.0.15.6081) - AMD Ryzen 7 2700X Eight-Core Processor (16 Threads)

Issue description

print_rich does not output color tags to the godot log file when using built-in colors names. However, when using hexadecimal color codes, the color tag is output to the godot log file. This behavior seems inconsistent.

In my opinion, the color tag should never be output to the log file as the color information is for console use only.

Steps to reproduce

  1. Create a node with the following code:
extends Node
func _ready() -> void:
    print_rich("[color=#af7ac5]Hello[/color]")
    print_rich("[color=red]Goodbye[/color]")
  1. Run the scene
  2. Inspect the godot.log file contents and observe the following contents:
[color=#af7ac5]Hello
Goodbye

Expectation: [color=#af7ac5] would not be present in the log file.

Minimal reproduction project (MRP)

printrich.zip

akien-mga commented 1 month ago

Only some named colors are supported by print_rich, not hexadecimal codes.

See the documentation for print_rich: https://docs.godotengine.org/en/latest/classes/class_%40globalscope.html#class-globalscope-method-print-rich

And the source code:

        if (p_string_ansi.contains("[color")) {
                p_string_ansi = p_string_ansi.replace("[color=black]", "\u001b[30m");
                p_string_ansi = p_string_ansi.replace("[color=red]", "\u001b[91m");
                p_string_ansi = p_string_ansi.replace("[color=green]", "\u001b[92m");
                p_string_ansi = p_string_ansi.replace("[color=lime]", "\u001b[92m");
                p_string_ansi = p_string_ansi.replace("[color=yellow]", "\u001b[93m");
                p_string_ansi = p_string_ansi.replace("[color=blue]", "\u001b[94m");
                p_string_ansi = p_string_ansi.replace("[color=magenta]", "\u001b[95m");
                p_string_ansi = p_string_ansi.replace("[color=pink]", "\u001b[38;5;218m");
                p_string_ansi = p_string_ansi.replace("[color=purple]", "\u001b[38;5;98m");
                p_string_ansi = p_string_ansi.replace("[color=cyan]", "\u001b[96m");
                p_string_ansi = p_string_ansi.replace("[color=white]", "\u001b[97m");
                p_string_ansi = p_string_ansi.replace("[color=orange]", "\u001b[38;5;208m");
                p_string_ansi = p_string_ansi.replace("[color=gray]", "\u001b[90m");
                p_string_ansi = p_string_ansi.replace("[/color]", "\u001b[39m");
        }
scott-lin commented 1 month ago

Understood.

Just for the record though, hexadecimal colors may not be "supported", but they do indeed work as expected with respect to coloring text. The only side effect I'm experiencing is the log output of the color tag.

I'll check elsewhere on the internet as this isn't a support forum, but I'll throw out the question here just in case: is there a way to modify the log output before it is flushed to the godot log file? I'm happy to remove the color tags myself if there's a means to do it.

akien-mga commented 1 month ago

Right, thinking about it this is maybe something we could still strip from the plain log output.

It works in the editor because RichTextLabel supports this, but the print_rich function also doubles as a way to print ANSI color codes in the terminal, which only supports a few named colors.

But I assume we could strip [color=#.....] tags before passing it to stdout, so that the terminal output doesn't have those colors but also no stray bbcode formatting.

CC @Calinou

Calinou commented 1 month ago

For future reference, this is already being tracked in https://github.com/godotengine/godot/issues/87899.

But I assume we could strip [color=#.....] tags before passing it to stdout, so that the terminal output doesn't have those colors but also no stray bbcode formatting.

Should be easy with RegEx, but I originally wanted to avoid running a regex on every printed line. I wanted to build a custom parser for BBCode-to-ANSI conversion as it could cover more BBCode tags and be faster. A RegEx-based parser could still support arbitrary colors, which is probably the most important missing thing right now. That said, we now run a regex on every printed line for https://github.com/godotengine/godot/pull/90900 anyway (when file logging is enabled), so maybe it's not such a big problem.