Skip to content

Commit

Permalink
Fixed #10296: Tolerated interrobang swapping. (#11290)
Browse files Browse the repository at this point in the history
* Added documentation for "EndInterrobangCheck" function

* Fixed #10296: Tolerated interrobang swapping.
The updated code now allows for the swapping of "?!/!?" while translating and checks for the presence of interrobangs in both the source and translation. Tests have been implemented to validate the changes made to the code.


* Fix: Removed the "check_interrobang" function, added logic to "EndInterrobangCheck", incorporated support for pre-combined ⁈ (U+2048) and ⁉ (U+2049), as well as fullwidth ?! and !?, and included additional tests.

* Fix:  Refactored to simplify conditionals for checking the presence of interrobangs in "EndExclamationCheck" and "EndQuestionCheck".

* Fix: Full width and standard width can now be used interchangeably.

Co-authored-by: Michal Čihař <[email protected]>
  • Loading branch information
manuelmcruz and nijel authored Apr 9, 2024
1 parent 4e1022b commit 86ce9ac
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
18 changes: 18 additions & 0 deletions docs/user/checks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,24 @@ Coptic).

`Question mark on Wikipedia <https://en.wikipedia.org/wiki/Question_mark>`_

.. _check-end-interrobang:

Mismatched interrobang mark
~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Summary: Source and translation do not both end with a interrobang mark
:Scope: translated strings
:Check class: ``weblate.checks.chars.EndInterrobangCheck``
:Check identifier: ``end_Interrobang``
:Flag to ignore: ``ignore-end-Interrobang``

Checks that interrobang marks are replicated between both source and translation.
It allows the swap between "!?" and "?!".

.. seealso::

`Interrobang mark on Wikipedia <https://en.wikipedia.org/wiki/Interrobang>`_

.. _check-end-semicolon:

Mismatched semicolon
Expand Down
27 changes: 27 additions & 0 deletions weblate/checks/chars.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ class EndQuestionCheck(TargetCheck):
"Source and translation do not both end with a question mark"
)
question_el = ("?", ";", ";")
interrobangs = ("?!", "!?", "?!", "!?", "⁈", "⁉")

def _check_hy(self, source, target):
if source[-1] == "?":
Expand All @@ -248,6 +249,8 @@ def _check_my(self, source, target):
def check_single(self, source, target, unit):
if not source or not target:
return False
if source.endswith(self.interrobangs) or target.endswith(self.interrobangs):
return False
if unit.translation.language.is_base(("jbo",)):
return False
if unit.translation.language.is_base(("hy",)):
Expand All @@ -270,10 +273,13 @@ class EndExclamationCheck(TargetCheck):
description = gettext_lazy(
"Source and translation do not both end with an exclamation mark"
)
interrobangs = ("?!", "!?", "?!", "!?", "⁈", "⁉")

def check_single(self, source, target, unit):
if not source or not target:
return False
if source.endswith(self.interrobangs) or target.endswith(self.interrobangs):
return False
if (
unit.translation.language.is_base(("eu",))
and source[-1] == "!"
Expand All @@ -290,6 +296,27 @@ def check_single(self, source, target, unit):
return self.check_chars(source, target, -1, ("!", "!", "՜", "᥄", "႟", "߹"))


class EndInterrobangCheck(TargetCheck):
"""Check for final interrobang expression."""

check_id = "end_Interrobang"
name = gettext_lazy("Mismatched interrobang")
description = gettext_lazy(
"Source and translation do not both end with an interrobang expression"
)

def check_single(self, source, target, unit):
if not source or not target:
return False

interrobangs = ("!?", "?!", "?!", "!?")

if (source.endswith(interrobangs)) != (target.endswith(interrobangs)):
return True

return bool(self.check_chars(source, target, -1, ("⁈", "⁉")))


class EndEllipsisCheck(TargetCheck):
"""Check for ellipsis at the end of string."""

Expand Down
1 change: 1 addition & 0 deletions weblate/checks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class WeblateChecksConf(AppConf):
"weblate.checks.chars.EndColonCheck",
"weblate.checks.chars.EndQuestionCheck",
"weblate.checks.chars.EndExclamationCheck",
"weblate.checks.chars.EndInterrobangCheck",
"weblate.checks.chars.EndEllipsisCheck",
"weblate.checks.chars.EndSemicolonCheck",
"weblate.checks.chars.MaxLengthCheck",
Expand Down
41 changes: 41 additions & 0 deletions weblate/checks/tests/test_chars_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
EndColonCheck,
EndEllipsisCheck,
EndExclamationCheck,
EndInterrobangCheck,
EndNewlineCheck,
EndQuestionCheck,
EndSemicolonCheck,
Expand Down Expand Up @@ -198,6 +199,14 @@ def test_my(self) -> None:
self.do_test(False, ("Text?", "ပုံဖျက်မလား။", ""), "my")
self.do_test(True, ("Te xt", "ပုံဖျက်မလား။", ""), "my")

def test_interrobang(self) -> None:
self.do_test(False, ("string!?", "string?", ""))
self.do_test(False, ("string?", "string?!", ""))
self.do_test(False, ("string⁈", "string?", ""))
self.do_test(False, ("string?", "string⁉", ""))
self.do_test(False, ("string?!", "string?", ""))
self.do_test(False, ("string?", "string!?", ""))


class EndExclamationCheckTest(CheckTestCase):
check = EndExclamationCheck()
Expand All @@ -216,6 +225,38 @@ def test_hy(self) -> None:
def test_eu(self) -> None:
self.do_test(False, ("Text!", "¡Texte!", ""), "eu")

def test_interrobang(self) -> None:
self.do_test(False, ("string!?", "string!", ""))
self.do_test(False, ("string!", "string?!", ""))
self.do_test(False, ("string⁈", "string!", ""))
self.do_test(False, ("string!", "string⁉", ""))
self.do_test(False, ("string?!", "string!", ""))
self.do_test(False, ("string!", "string!?", ""))


class EndInterrobangCheckTest(CheckTestCase):
check = EndInterrobangCheck()

def setUp(self) -> None:
super().setUp()
self.test_good_matching = ("string!?", "string?!", "")
self.test_failure_1 = ("string!?", "string?", "")
self.test_failure_2 = ("string!?", "string!", "")
self.test_failure_3 = ("string!", "string!?", "")

def test_translate(self) -> None:
self.do_test(False, ("string!?", "string!?", ""))
self.do_test(False, ("string⁉", "string⁈", ""))
self.do_test(False, ("string⁉", "string⁉", ""))
self.do_test(False, ("string!?", "string!?", ""))
self.do_test(False, ("string!?", "string?!", ""))
self.do_test(False, ("string?!", "string?!", ""))
self.do_test(False, ("string!?", "string!?", ""))
self.do_test(True, ("string?", "string?!", ""))
self.do_test(True, ("string⁉", "string!?", ""))
self.do_test(True, ("string?!", "string⁈", ""))
self.do_test(True, ("string?!", "string⁈", ""))


class EndEllipsisCheckTest(CheckTestCase):
check = EndEllipsisCheck()
Expand Down
1 change: 1 addition & 0 deletions weblate/settings_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@
"weblate.checks.chars.EndColonCheck",
"weblate.checks.chars.EndQuestionCheck",
"weblate.checks.chars.EndExclamationCheck",
"weblate.checks.chars.EndInterrobangCheck",
"weblate.checks.chars.EndEllipsisCheck",
"weblate.checks.chars.EndSemicolonCheck",
"weblate.checks.chars.MaxLengthCheck",
Expand Down
1 change: 1 addition & 0 deletions weblate/settings_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@
# "weblate.checks.chars.EndColonCheck",
# "weblate.checks.chars.EndQuestionCheck",
# "weblate.checks.chars.EndExclamationCheck",
# "weblate.checks.chars.EndInterrobangCheck",
# "weblate.checks.chars.EndEllipsisCheck",
# "weblate.checks.chars.EndSemicolonCheck",
# "weblate.checks.chars.MaxLengthCheck",
Expand Down

0 comments on commit 86ce9ac

Please sign in to comment.