Skip to content

Commit b0dbab4

Browse files
moonchoenijel
andauthored
feat(checks): Add MultipleCapitalCheck for issue #8753 (#17265)
Add MultipleCapitalCheck to detect mistakenly used capital letters. Fixes #8753 Co-authored-by: Michal Čihař <michal@cihar.com>
1 parent edd1b16 commit b0dbab4

File tree

7 files changed

+77
-0
lines changed

7 files changed

+77
-0
lines changed

docs/changes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Weblate 5.16
55

66
.. rubric:: New features
77

8+
* :ref:`check-multiple-capital` quality check.
9+
810
.. rubric:: Improvements
911

1012
* Delete announcements permission can be assigned to teams, see :ref:`privileges`.

docs/user/checks.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,25 @@ Specifics on how each plural form is used can be found in the string definition.
14761476
Failing to fill in plural forms will in some cases lead to displaying nothing when
14771477
the plural form is in use.
14781478

1479+
.. _check-multiple-capital:
1480+
1481+
Multiple capitals
1482+
~~~~~~~~~~~~~~~~~
1483+
1484+
.. versionadded:: 5.16
1485+
1486+
:Summary: Translation contains words with multiple misplaced capital letters.
1487+
:Scope: translated strings
1488+
:Check class: ``weblate.checks.chars.MultipleCapitalCheck``
1489+
:Check identifier: ``multiple_capital``
1490+
:Trigger: This check is always enabled but can be ignored using a flag.
1491+
:Flag to ignore: ``ignore-multiple-capital``
1492+
1493+
Checks for misplaced capitalization by detecting words that contain consecutive
1494+
uppercase letters in otherwise lowercase or normally capitalized text (for
1495+
example, ``HEllo`` or ``CAmelCase``). Strings that contain capitalization in the
1496+
source string are allowed to contain capitalization in the translation.
1497+
14791498
.. _check-kabyle-characters:
14801499

14811500
Non‑standard characters in Kabyle

weblate/checks/chars.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import unicodedata
99
from typing import TYPE_CHECKING, ClassVar
1010

11+
import regex
1112
from django.utils.translation import gettext_lazy
1213

1314
from weblate.checks.base import CountingCheck, TargetCheck, TargetCheckParametrized
@@ -579,3 +580,23 @@ def get_fixup(self, unit: Unit) -> Iterable[FixupType] | None:
579580
"gu",
580581
),
581582
]
583+
584+
585+
class MultipleCapitalCheck(TargetCheck):
586+
"""Multiple capitals check."""
587+
588+
check_id = "multiple_capital"
589+
name = gettext_lazy("Multiple capitals")
590+
description = gettext_lazy(
591+
"Translation contains words with multiple misplaced capital letters."
592+
)
593+
594+
# matches sequences of 2+ uppercase letters in *any language*
595+
UPPERCASE_SEQ = regex.compile(r"\p{Lu}{2,}")
596+
597+
def check_single(self, source: str, target: str, unit: Unit) -> bool:
598+
# Flag if any uppercase sequence is present in target and not present in the source
599+
return (
600+
self.UPPERCASE_SEQ.search(target) is not None
601+
and not self.UPPERCASE_SEQ.search(source) is not None
602+
)

weblate/checks/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class WeblateChecksConf(AppConf):
6565
"weblate.checks.chars.EndEllipsisCheck",
6666
"weblate.checks.chars.EndSemicolonCheck",
6767
"weblate.checks.chars.MaxLengthCheck",
68+
"weblate.checks.chars.MultipleCapitalCheck",
6869
"weblate.checks.chars.KashidaCheck",
6970
"weblate.checks.chars.PunctuationSpacingCheck",
7071
"weblate.checks.chars.KabyleCharactersCheck",

weblate/checks/tests/test_chars_checks.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
KabyleCharactersCheck,
2424
KashidaCheck,
2525
MaxLengthCheck,
26+
MultipleCapitalCheck,
2627
NewLineCountCheck,
2728
PunctuationSpacingCheck,
2829
ZeroWidthSpaceCheck,
@@ -512,3 +513,34 @@ def test_skip(self) -> None:
512513
),
513514
"el",
514515
)
516+
517+
518+
class MultipleCapitalCheckTest(CheckTestCase):
519+
check = MultipleCapitalCheck()
520+
521+
def setUp(self) -> None:
522+
super().setUp()
523+
self.test_good_matching = ("Hello", "Hello", "")
524+
self.test_failure_1 = ("Hello", "HEllo", "")
525+
self.test_failure_2 = ("camel case", "CAmelCase", "")
526+
self.test_failure_3 = ("sigma", "ΣIGMA", "")
527+
528+
def test_acronyms(self) -> None:
529+
self.do_test(
530+
False,
531+
(
532+
"Welcome NATO",
533+
"Bonjour OTAN",
534+
"",
535+
),
536+
"fr",
537+
)
538+
self.do_test(
539+
False,
540+
(
541+
"Welcome NATO",
542+
"Vítej NATO",
543+
"",
544+
),
545+
"cs",
546+
)

weblate/settings_docker.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,7 @@
11081108
"weblate.checks.chars.EndEllipsisCheck",
11091109
"weblate.checks.chars.EndSemicolonCheck",
11101110
"weblate.checks.chars.MaxLengthCheck",
1111+
"weblate.checks.chars.MultipleCapitalCheck",
11111112
"weblate.checks.chars.KashidaCheck",
11121113
"weblate.checks.chars.PunctuationSpacingCheck",
11131114
"weblate.checks.chars.KabyleCharactersCheck",

weblate/settings_example.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@
724724
# "weblate.checks.chars.EndEllipsisCheck",
725725
# "weblate.checks.chars.EndSemicolonCheck",
726726
# "weblate.checks.chars.MaxLengthCheck",
727+
# "weblate.checks.chars.MultipleCapitalCheck",
727728
# "weblate.checks.chars.KashidaCheck",
728729
# "weblate.checks.chars.PunctuationSpacingCheck",
729730
# "weblate.checks.chars.KabyleCharactersCheck",

0 commit comments

Comments
 (0)