Skip to content

Conversation

@zlomzlom
Copy link
Contributor

I think right now everything is translatable except for Lua stuff and logging (and I still don't know how to squash, sorry)

@arch1t3cht
Copy link
Member

Generally the solution to translatable strings in different contexts having the same string is not to subtly change one of them, but to add a context to the translation. Then, instead of _("Open Audio File") you can use wxGETTEXT_IN_CONTEXT("Open Audio File", "dialog"), for example.

@zlomzlom
Copy link
Contributor Author

zlomzlom commented Jan 4, 2026

Yeah, but every other string in file selectors already isn't capitalized (like in "Save audio clip", "Open keyframes file", "Open subtitles file", etc.)

@zlomzlom
Copy link
Contributor Author

zlomzlom commented Jan 8, 2026

I don't know what I should do. Do I replace every non-capitalized string just like you said (wxGETTEXT_IN_CONTEXT("Open Audio File", "dialog")), or?..

@arch1t3cht
Copy link
Member

I'll make the changes I need and squash the commits and push to your branch soon, like last time.

@arch1t3cht arch1t3cht force-pushed the more_translations branch 2 times, most recently from 8a83e0e to 757d6c5 Compare January 21, 2026 21:39
zlomzlom and others added 4 commits January 21, 2026 23:37
Use title case for all dialogs except when the dialog title contains
some longer explanation like when extracting attachments.
Use context to allow these strings to be translated independently.
@arch1t3cht
Copy link
Member

Done; will merge tomorrow if the CI goes through.

@zlomzlom
Copy link
Contributor Author

Nice, thank you for bearing with me. I also wanted to ask some questions (and probably make my final contribution, if it is possible):

  1. How come throwing an exception generates a dialog window? I tried searching around in the code and in the wxWidgets documentation, but didn't find anything meaningful;
  2. Is there any smart and feasible way of making logging and exception dialogs translatable too? I was experimenting with exceptions in the meantime by replacing std::strings with wxString instead in libaegisub/include/libaegisub/exception.h and tried to make some strings translatable through the _() macro (although I wish there was a fast way to debug every exception, because I don't know which exceptions should be displayable and which not);
  3. While looking into exporting subtitltes, I noticed that some subtitle formats ("EBU subtitling data exchange format (EBU tech 3264, 1991)", "MPEG-4 Streaming Text", "Plain-Text") could be translatable as well. I kinda didn't manage to succeed, because you can't overload from_wx() function to handle str::string_view due to the second wxString argument (on second thought, prolly the most sane thing is just to use std::string_view(_("Plain-Text").utf8_str()) maybe?)

@0tkl
Copy link
Contributor

0tkl commented Jan 22, 2026

@zlomzlom I don't have permission to write this PR directly, so I opened a PR in your repository. Dividing it into 4 commits is just for easier browsing; I recommend squashing when merging.

@arch1t3cht #482 and this PR brought about too many petty changes to the original text, especially those that did not change or barely changed the translation. Since you put the “Regenerate pot file” commit in this PR, I suggest putting the regeneration and manual intervention to po files here as well.

@zlomzlom
Copy link
Contributor Author

First of all, I deliberately don't add po files while regenerating pot, because there are three translation requests hanging around (two of them seem abandoned, though (and any other translator can manually update their language's po file from pot and patch up fuzzy strings if there are any))

And I've already told two times, I don't know how to squash commits and I have no idea what will happen when I accept your pull request

@arch1t3cht
Copy link
Member

How come throwing an exception generates a dialog window?

Exceptions are caught somewhere in some Aegisub component and displayed as a dialog there, or, if they propagate all the way upwards, caught by wxWidgets and passed to AegisubApp::OnUnhandledException in main.cpp where they are then displayed as a dialog.

Is there any smart and feasible way of making logging and exception dialogs translatable too?

I don't think translating log messages is a good idea (at least without any further handling), since logs are mainly used as debug info to be passed onto developers when reporting bugs, and translating the logs would just complicate this. If logs are made translatable, they'd need some sort of special handling where every log message is a translatable format string that's translated in the log window but not translated in log files, but that'd need a big refactor.

Translating exceptions is also hard in general. We can translate the exceptions that Aegisub itself generates, and addressing #379 might help translate some of wxWidgets's exceptions, but exceptions from other libraries like ffms2 cannot be easily translated. But, similarly to log messages, I also don't think they should be: Exceptions are only supposed to be interesting to developers. If there are situations where an exception contains necessary information for the user that's only visible in the exception message, then that should instead be solved by catching the exception and adding a more user-friendly translatable error message in Aegisub.

because you can't overload from_wx() function to handle str::string_view

This I cannot answer immediately, I'll look into this when I can.

add some ad-hoc code (which I didn't push into this branch) so that at runtime, it automatically preserves the translation for some original texts that only involve case changes, such as from "Open video file" to "Open Video File".

I don't think this is the best solution here. First of all, I agree with @.zlomzlom that po files should not be regenerated every time the pot file is updated since this only complicates in-progress translation PRs with no real gain (when fuzzy matching is disabled).

Ideally the po files should be updated to match the small fixes to some strings, yes, but doing this automatically is not ideal. It's quite possible that the various languages will also need to make fixes to the capitalization, for example.

gettext already has features to handle this - this is what fuzzy matching is for. This will mark the strings as needing human review in the po file and keep the previous msgid around for comparison. The correct solution here is to split the added strings and the changes to strings into separate pot file updates and then msgmerge the changes into the po files with fuzzy matching enabled. I will do this soon.

@zlomzlom
Copy link
Contributor Author

I don't think translating log messages is a good idea

Okay, I see

Exceptions are only supposed to be interesting to developers.

But some of them are still displayed to the users (I mean the Aegisub ones, which are describing the errors). I myself definitely encountered a few, however, I don't remember which exactly

@KerimDemirkaynak
Copy link
Contributor

But some of them are still displayed to the users (I mean the Aegisub ones, which are describing the errors). I myself definitely encountered a few, however, I don't remember which exactly

Translating something that appears so infrequently might not be worth the effort/time on your part.

@zlomzlom
Copy link
Contributor Author

You might be right... I've already spent hours on marking strings for translating

@0tkl
Copy link
Contributor

0tkl commented Jan 22, 2026

zlomzlom: I deliberately don't add po files while regenerating pot, because there are three translation requests hanging around
arch1t3cht: I agree with @.zlomzlom that po files should not be regenerated every time the pot file is updated since this only complicates in-progress translation PRs with no real gain (when fuzzy matching is disabled).

I will skip Russian since you zlom is actively working on #344 . I will postpone applying the changes to Korean for the time being to await Hackjjang's response. I will apply the changes to Chinese (China), as I will eventually have to decide whether to address or abandon that severely deviating PR.

zlomzlom: I don't know how to squash your commits

While squashing your own commits on the web isn't convenient, you can indeed squash other's commits from PRs pushed to you on the web:

image

arch1t3cht: The correct solution here is to split the added strings and the changes to strings into separate pot file updates…

Seconded. I'll close the PR on the zlom side as soon as you're ready.

@zlomzlom
Copy link
Contributor Author

zlomzlom commented Jan 22, 2026

Alright, just to clarify: I don't need to do anything else on my end (like merging 0tkl's pull request)?

@arch1t3cht
Copy link
Member

No, that's fine, I'll handle this myself.

@zlomzlom
Copy link
Contributor Author

Okay, thank you again

The first in a series of commits to update the translation files with
the small fixes to English strings without creating fuzzy matches for
the added strings.

This commit merges an aegisub.pot generated on 6f7e314
into the current po files *without* fuzzy matching, since the relevant
commit only adds new strings.
Skip tr.po and zh_CN.po, since these were already updated since.
This commit merges the current aegisub.pot (with the changes from
9120a91) into the current po files
*with* fuzzy matching (and --previous).
This commit updates aegisub.pot with the added translations from
db1dbd8 and merges it into the po files
*without* fuzzy matching.
This commit updates aegisub.pot with the remaining fixes to English
strings (f349d6c and
25173eb) and merges the updates into
the po files *with* fuzzy matching and --previous.
@arch1t3cht
Copy link
Member

Pushed now. Will merge in a bit unless there are more complaints.

@0tkl
Copy link
Contributor

0tkl commented Jan 23, 2026

(Zlom, thank you for your contribution. The following discussion requires no operation from you; you can confidently leave it to arch1t3cht.)
(The following message is addressed only to arch1t3cht.)

Are these commits your latest version? What I agreed with yesterday was your decision to "split commits." I do not agree with using automatic fuzzing as the sole method for handling modified fields. I ran make_pot.sh with fuzzy, but I wasn't quite satisfied. That's why I manually intervene in the results.


@@ -605,6 +607,8 @@ msgid "Save an audio clip of the selected line"
 msgstr ""
 
 #: ../src/command/audio.cpp:177
+#, fuzzy
+#| msgid "Save audio clip"
 msgid "Save Audio Clip"
 msgstr "حفظ قصاصة الصوت"
 
@@ -1578,6 +1582,8 @@ msgid "Open a keyframe list file"
 msgstr ""
 
 #: ../src/command/keyframe.cpp:72
+#, fuzzy
+#| msgid "Open keyframes file"
 msgid "Open Keyframes File"
 msgstr "فتح ملف إطارات مفتاحية"
 

When the only difference between the old and new strings is capitalization, if the target language does not have the concept of capitalization, then fuzzy tags are unnecessary. Limited to the languages ​​supported by Aegisub, those that meet the criteria include Arabic ar, Persian fa, Chinese zh, Japanese ja, and Korean ko. It makes sense to retain this fuzzy tag for other languages.


-#: ../src/dialog_automation.cpp:289
+#: ../src/dialog_automation.cpp:291
 #, c-format
 msgid ""
 "\n"
@@ -2841,64 +3064,65 @@ msgid ""
 "Version: %s\n"
 "Full path: %s\n"
 "State: %s\n"
-"\n"
-"Features provided by script:"
 msgstr ""
-"\n"
-"Звесткі пра скрыпт:\n"
-"Назва: %s\n"
-"Апісанне: %s\n"
-"Аўтар: %s\n"
-"Версія: %s\n"
-"Шлях: %s\n"
-"Стан: %s\n"
-"\n"
-"Прадстаўлена:"

+#: ../src/dialog_automation.cpp:303
+msgid "Features provided by script:\n"
+msgstr ""

+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "Script info:\n"
+#~ "Name: %s\n"
+#~ "Description: %s\n"
+#~ "Author: %s\n"
+#~ "Version: %s\n"
+#~ "Full path: %s\n"
+#~ "State: %s\n"
+#~ "\n"
+#~ "Features provided by script:"
+#~ msgstr ""
+#~ "\n"
+#~ "Звесткі пра скрыпт:\n"
+#~ "Назва: %s\n"
+#~ "Апісанне: %s\n"
+#~ "Аўтар: %s\n"
+#~ "Версія: %s\n"
+#~ "Шлях: %s\n"
+#~ "Стан: %s\n"
+#~ "\n"
+#~ "Прадстаўлена:"

This is a recent change: 1f0fcf9. And this is an appropriate place for manual intervention to directly disassemble existing translations. (I just notice that I move the large block but forgot to move the smaller block in my branch; additional work is required therefore.)


-#: ../src/preferences.cpp:358
+#: ../src/preferences.cpp:367
 msgid ""
-"Changing these settings might result in bugs and/or crashes.  Do not touch "
+"Changing these settings might result in bugs and/or crashes. Do not touch "
 "these unless you know what you're doing."
 msgstr ""
-"Змена гэтых налад можа выклікаць некарэктную працу праграмы. Не змяняйце іх, "
-"калі сапраўды не ўпэўнены ў тым, што робіце."

+#~ msgid ""
+#~ "Changing these settings might result in bugs and/or crashes.  Do not "
+#~ "touch these unless you know what you're doing."
+#~ msgstr ""
+#~ "Змена гэтых налад можа выклікаць некарэктную працу праграмы. Не змяняйце "
+#~ "іх, калі сапраўды не ўпэўнены ў тым, што робіце."

This is where the fuzzy option fails.


-#: ../src/dialog_kara_timing_copy.cpp:402
-msgid "Attempt to &interpolate kanji."
+#: ../src/dialog_kara_timing_copy.cpp:408
+#, fuzzy
+#| msgid "Attempt to &interpolate kanji."
+msgid "Attempt to &interpolate kanji"
 msgstr "&Спрабаваць прадугадаць кандзі"

Remove periods as well as fuzzy tags from all languages in this entry. Special handling of CJK full-width periods may be required.


Apart from contents above, there are also many grammatical changes, such as replacing "Appends" with "Append" and "Play video" with "Play the video." Which taget languages ​​will these changes affect in terms of meaning? For other languages I might need to ask LLM, so I can't be 100% sure; however I believe the fuzzy tags are unnecessary for Chinese zh, Japanese ja, Korean ko, and Vietnamese vi in these cases.

@arch1t3cht
Copy link
Member

I was working under the incorrect assumption that fuzzy translations are still compiled into the message catalog and displayed in Aegisub. But, yes, they aren't, at least not by default.

When the only difference between the old and new strings is capitalization, if the target language does not have the concept of capitalization, then fuzzy tags are unnecessary.

Assuming for a second that fuzzy translations are displayed, I disagree with this line of thinking. I do not want to make changes to languages I'm not proficient in, and I do not trust an LLM to make them either. Even if they may seem plausible for comparatively simple changes like this one, this is a slippery slope and I think it's much better to have a single consistent policy here. Trying to perfectly adapt all translations for every change made to English strings creates too much friction for improvements to the interface (in a project that already has massive friction for every change at the moment due to decades of backwards compatibility). I'm happy to adopt a policy that groups small adjustments to strings into batches and separates them from additions and larger changes so that messages in the po files can be properly tagged, but I think trying to port every fix to every language is unsustainable in the long run. Most translations are more than ten years old and their original translators aren't available any more, so those translations will inevitably decay anyway when more strings are added or changed in significant ways. On the other hand, translations whose translators are available can be fixed by the translators themselves.

By default, msgfmt does not include fuzzy entries, but can be configured to do so using --use-fuzzy. Unfortunately this does not seem to be exposed in meson, but I can see if I can make a pull request adding this.

Assuming we manage to run msgfmt with --use-fuzzy, I can propose the following policy:

  • Clear existing fuzzy translations (prior to this PR there are less than 5 of them per translation)
  • Changes that add or significantly change English strings are merged into po files with --preserve --no-fuzzy-matching (probably either at regular intervals or as late as possible, i.e. just before a commit making small fixes to strings)
  • Commits that make small fixes to English strings are separated from the others and grouped or squashed together. Their changes to the pot file are merged into the po files with --preserve (so with fuzzy matching).

This way, all changes to strings result in alerts for translators (either via missing translations or fuzzy translations) but small changes to English strings will still keep their old translations.

The alternative policy would be to simply continue as before and accept that unmaintained translations may decay slowly (which they will either way; it's just a question of how quickly). Active translators for languages will get a notification before upcoming releases so they can update their respective languages.

Tangentially: I plan to set up a Weblate instance for Aegisub or something similar eventually, which may help with some of these issues. But at the moment this has lower priority than releasing 3.5.0.

@KerimDemirkaynak
Copy link
Contributor

Updating .po files with every change hides the true state of the translations. Seeing a recent commit date on an abandoned language discourages new contributors from stepping in, as they assume it's up-to-date. I suggest keeping only aegisub.pot current. Translators should be the ones to manually merge changes from the .pot file when they intend to translate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants