6
61
Fork
You've already forked reuse-tool
23

Add placeholders to reuse-tool Weblate component #1361

Open
opened 2026年05月18日 03:08:30 +02:00 by rffontenelle · 5 comments

The translators experience in the reuse-tool translation component in Weblate could be improved by adding placeholders to part of strings that should be changed. The ultimate benefit is to let the translator and maintainer know when the translation doesn't contain the expression from the source string. See Checks and fixups in Weblate documentation.

Here is my suggestion (untested in Weblate, but tested locally):

placeholders:r"{[^}\s]*}":r"\-\-\w[\w\-]*":r"<[^>]+>'":r"https:\/\/[A-Za-z0-9.-]+(?:\/[^\s]*)?"

This matches:

  • {}, {word}, and {name!r} and other curly bracket expressions (some were automatically
  • long options like --add-license-concluded or --license
  • URLs surrounded by < > tags
  • URLs (without < >)
The translators experience in the [reuse-tool](https://hosted.weblate.org/projects/fsfe/reuse-tool) translation component in Weblate could be improved by adding placeholders to part of strings that should be changed. The ultimate benefit is to let the translator and maintainer know when the translation doesn't contain the expression from the source string. See [Checks and fixups](https://docs.weblate.org/en/weblate-5.17.1/admin/checks.html#customizing-behavior-using-flags) in Weblate documentation. Here is my suggestion (untested in Weblate, but tested locally): ```placeholders:r"{[^}\s]*}":r"\-\-\w[\w\-]*":r"<[^>]+>'":r"https:\/\/[A-Za-z0-9.-]+(?:\/[^\s]*)?"``` This matches: - `{}`, `{word}`, and `{name!r}` and other curly bracket expressions (some were automatically - long options like `--add-license-concluded` or `--license` - URLs surrounded by < > tags - URLs (without < >)

Hello Raffael,
this sounds interesting. Can you explain this usecase in more details. I don't understand. What is the problem this tries to solve?

Regards,
Christian

Hello Raffael, this sounds interesting. Can you explain this usecase in more details. I don't understand. What is the problem this tries to solve? Regards, Christian

Translators may accidentally translate texts that should be kept in English. Placeholders in Weblate is a way of "sort of protecting" these texts. Placeholders don't prevent the translation to be saved, but it raise a Warning in the edition page to let the translator know that a text that should not be translated was translated.

It is a good way to get translator's attention when using machine translation to bootstrap translation (which might wrongly translate URLs or {variables}) or even a simple "oops" that translate incorrectly.

Examples:

  • Some {expr} are already automatically flagged as placeholder by Weblate (see this source string from reuse annotate), but I noticed strings extracted from click not flagged as such. For instance, this source string has {name!r} and {extra_message} not treated as palceholders.
  • CLI options like in this string should not be translated, but one may translate as --licença or --colaborador (not good!).
  • URLs like in this string don't seem to you may want to be kept untouched
Translators may accidentally translate texts that should be kept in English. Placeholders in Weblate is a way of "sort of protecting" these texts. Placeholders don't prevent the translation to be saved, but it raise a Warning in the edition page to let the translator know that a text that should not be translated was translated. It is a good way to get translator's attention when using machine translation to bootstrap translation (which might wrongly translate URLs or {variables}) or even a simple "oops" that translate incorrectly. Examples: - Some `{expr}` are already automatically flagged as placeholder by Weblate (see [this source string](https://hosted.weblate.org/translate/fsfe/reuse-tool/en/?checksum=62a599ada191bde7) from `reuse annotate`), but I noticed strings extracted from click not flagged as such. For instance, [this source string](https://hosted.weblate.org/translate/fsfe/reuse-tool/en/?checksum=14c4e988a22f759e) has `{name!r}` and `{extra_message}` not treated as palceholders. - CLI options like in [this string](https://hosted.weblate.org/translate/fsfe/reuse-tool/en/?checksum=46c9aacbf39d8a18) should not be translated, but one may translate as --licença or --colaborador (not good!). - URLs like in [this string](https://hosted.weblate.org/translate/fsfe/reuse-tool/en/?checksum=f4c9c3cad8e12dae) don't seem to you may want to be kept untouched

Thank you for explaining.

My confusion might depend on my experience with Python.

@rffontenelle wrote in #1361 (comment):

Translators may accidentally translate texts that should be kept in English.

If it should kept in English it shouldn't be marked as translatable and therefore wouldn't appear in the Weblate project.

Example in Python

print(_('You can translate me.'))
print('Wan't get translated, because translators never seeing it.') # the _() is missing here.
# Here I would hope the best and count an the intelligence of the translators and also users reporting those translation bugs.
print(_('Option '--copyright', '--license', or '--contributor' is required.'))
# Workaround: Ugly in code, but more clean for translators
options = ['--copyright', '--license', '--contributor']
options = "'" + "', '".join(options[:-1]) + "' " + _('or') + "'" + options[-1] + "'"
print(_('Option {opt} is required.').format(op=options))

Regards,
Christian

EDIT: For checks like this I do have my own script I run when syncing between Weblate instance and my repository. I am not using the commit/PR way. The sync happens manually in my case. I also check for GUI-keyboard-shortcut markers like in _('&Help'), checking if placeholder markers {} are all closed, etc pp.

Thank you for explaining. My confusion might depend on my experience with Python. @rffontenelle wrote in https://codeberg.org/fsfe/reuse-tool/issues/1361#issuecomment-15380108: > Translators may accidentally translate texts that should be kept in English. If it should kept in English it shouldn't be marked as translatable and therefore wouldn't appear in the Weblate project. Example in Python ```py print(_('You can translate me.')) print('Wan't get translated, because translators never seeing it.') # the _() is missing here. # Here I would hope the best and count an the intelligence of the translators and also users reporting those translation bugs. print(_('Option '--copyright', '--license', or '--contributor' is required.')) # Workaround: Ugly in code, but more clean for translators options = ['--copyright', '--license', '--contributor'] options = "'" + "', '".join(options[:-1]) + "' " + _('or') + "'" + options[-1] + "'" print(_('Option {opt} is required.').format(op=options)) ``` Regards, Christian **EDIT**: For checks like this I do have my own script I run when syncing between Weblate instance and my repository. I am not using the commit/PR way. The sync happens manually in my case. I also check for GUI-keyboard-shortcut markers like in `_('&Help')`, checking if placeholder markers `{}` are all closed, etc pp.

In my experience as translator, developers normally prefer not change too much with the source string to adjust the printable strings since it requires both finding all occurrences in the source code to change and refactoring them, which demands time away from other issues they consider more important. If you prefer to change the code to removing these text in first place, I fine with it.

The specific workaround you presented could be a problem for some languages, although I'm not sure. For instance Chinese has different use of whitespace for numbers and characters (i.e. maybe they don't put these spaces between CLI options and comma). So IMHO would be safer to pass one format placeholder per option, e.g.:

print(_('Option {copyright}, {license} or {contributor} is required.').format(copyright='--copyright', license='--license', contributor='--contributor'))

Translation comments should be considering depending on the scenario. In my example it wouldn't be needed, but some placeholders (e.g. %s) in a not very clear string may lead to a incorrect translation, hence requiring a small explanation.

Great you have checks. I'm not familiar with the checks you apply (I'm new in this repo) so if you think it covers the problems I presented, feel free to close this.

A little bit off-topic, but I personally have hard time keeping CLI options correctly on translations, so I also created a script for checking if translation in a PO file contains the correct CLI options. Helped me a lot for fixing my own translation in coreutils.

In my experience as translator, developers normally prefer not change too much with the source string to adjust the printable strings since it requires both finding all occurrences in the source code to change and refactoring them, which demands time away from other issues they consider more important. If you prefer to change the code to removing these text in first place, I fine with it. The specific workaround you presented could be a problem for some languages, although I'm not sure. For instance Chinese has different use of whitespace for numbers and characters (i.e. maybe they don't put these spaces between CLI options and comma). So IMHO would be safer to pass one format placeholder per option, e.g.: ```python print(_('Option {copyright}, {license} or {contributor} is required.').format(copyright='--copyright', license='--license', contributor='--contributor')) ``` Translation comments should be considering depending on the scenario. In my example it wouldn't be needed, but some placeholders (e.g. %s) in a not very clear string may lead to a incorrect translation, hence requiring a small explanation. Great you have checks. I'm not familiar with the checks you apply (I'm new in this repo) so if you think it covers the problems I presented, feel free to close this. A little bit off-topic, but I personally have hard time keeping CLI options correctly on translations, so I also created [a script for checking if translation in a PO file contains the correct CLI options](https://gitlab.com/rafaelff/scripts/-/blob/master/compare-cli-options.py). Helped me a lot for fixing my own translation in coreutils.

FYI: I am also just a Weblate user. I am not the maintainer of this repo here. I was asking initially just to learn how others work with Weblate.

FYI: I am also just a Weblate user. I am not the maintainer of this repo here. I was asking initially just to learn how others work with Weblate.
Sign in to join this conversation.
No Branch/Tag specified
main
janderssonse/fix/add-security-policy
mirror-codeberg
changelog-2.0.0-extend
readme-reuse-3.1
feature/debian-inspector
feature/dep5-error-handling
v6.2.0
v6.1.2
v6.1.1
v6.1.0
v6.0.0
v5.1.1
v5.1.0
v5.0.2
v5.0.1
v5.0.0
v4.0.3
v4.0.2
v4.0.1
v4.0.0
v3.1.0a1
v3.0.2
v3.0.1
v3.0.0
v2.1.0
v2.0.0
v1.1.2
v1.1.1
v1.1.0
v1.0.0
v0.14.0
v0.13.0
v0.12.1
v0.12.0
v0.11.1
v0.11.0
v0.10.1
v0.10.0
v0.9.0
v0.8.1
v0.8.0
v0.7.0
v0.6.0
v0.5.2
v0.5.1
v0.5.0
v0.4.1
v0.4.0
v0.4.0a1
v0.3.4
v0.3.3
v0.3.2
v0.3.1
v0.3.0
v0.2.0
v0.1.1
v0.1.0
v0.0.4
v0.0.3
v0.0.2
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
fsfe/reuse-tool#1361
Reference in a new issue
fsfe/reuse-tool
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?