godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Allow skipping script lines from POT generation #10590

Open KoBeWi opened 2 weeks ago

KoBeWi commented 2 weeks ago

Describe the project you are working on

A game with many complex scenes that will eventually need a localization.

Describe the problem or limitation you are having in your project

I started experimenting with localizing my game and tried the Generate POT option. While it seems quite reliable, it's sometimes too reliable and fills my POT file with strings I don't want there.

E.g. I have this line in my scene:

$VBoxContainer/Name.text = \"???\"

It's part of built-in script and sets a text to a Label. POT Generator surprisingly finds this line and adds to POT file, but I don't want this particular line in there. Currently there is no way to add it to exceptions.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a way to skip such lines by POT Generator. Fetching them is useful feature, so this should be allowed in case-by-case basis.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The relevant code seems to be here: https://github.com/godotengine/godot/blob/fd7239cfab228c50777cd54a8bf6eb279a02ef81/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp#L236

I think this functionality could be achieved by using comments. E.g. in case of my line I could do

$VBoxContainer/Name.text = \"???\" # NO_TRANSLATE

and POT Generator would skip this particular line.

If this enhancement will not be used often, can it be worked around with a few lines of script?

You can manually add exceptions using some post-process script that removes strings, but it's inconvenient.

Is there a reason why this should be core and not an add-on in the asset library?

POT Generator is core feature and can't be extended.

dalexeev commented 2 weeks ago
timothyqiu commented 2 weeks ago

I think this functionality could be achieved by using comments.

The current extractor is based on the GDScript parser. Comments are not available at that point I think.

POT Generator is core feature and can't be extended.

Actually, you can. POT generator uses EditorTranslationParserPlugin.

KoBeWi commented 2 weeks ago

Ok I found a plausible workaround. You can change the String to NodePath and the generator will ignore it:

$VBoxContainer/Name.text = ^"???"

🙃

(interestingly, StringNames are fetched normally)

Actually, you can. POT generator uses EditorTranslationParserPlugin.

But GDScript resources are parsed using GDScriptEditorTranslationParserPlugin. I don't think there is reasonable way to override its behavior for specific cases.

dalexeev commented 2 weeks ago

Translation strings are extracted in GDScriptEditorTranslationParserPlugin. We could simply skip strings extracted from AST nodes marked with NO_TRANSLATE comment. TRANSLATORS: comments additionally require a new parameter on the EditorTranslationParserPlugin side.

(interestingly, StringNames are fetched normally)

See the source code.

KoBeWi commented 1 week ago

You can change the String to NodePath and the generator will ignore it:

Apparently this only works with unsafe assignments (like the $Label.text in the example). When you do

extends Label
func _ready():
    text = ^"Text"

the parser/compiler/whatever will interpret the constant as String. It's nice that it can do that, but it's a problem here :/ I'll need an even more ugly workaround like text = Globals.kill_translation_lol("Text") 💀

dalexeev commented 1 week ago

@KoBeWi You can use str(). Since it's a non-math @GlobalScope function, it is currently not compile-time evaluated.

const A = "test" # OK.
const B = str("test") # Error: Assigned value for constant "B" isn't a constant expression.