diff --git a/docs/user/checks.rst b/docs/user/checks.rst index a895e47da577..4a4e251808d2 100644 --- a/docs/user/checks.rst +++ b/docs/user/checks.rst @@ -439,6 +439,20 @@ not desired result from changing the translation, but occasionally it is. Checks that XML tags are replicated between both source and translation. + +.. _check-md-reflink: + +Markdown link references +~~~~~~~~~~~~~~~~~~~~~~~~ + +Markdown link references does not match source. + +.. seealso:: + + `Markdown links`_ + +.. _Markdown links: https://daringfireball.net/projects/markdown/syntax#link + Source checks ------------- diff --git a/weblate/checks/markup.py b/weblate/checks/markup.py index 1dc3e4e985f6..d41ef970702c 100644 --- a/weblate/checks/markup.py +++ b/weblate/checks/markup.py @@ -33,6 +33,12 @@ re.MULTILINE ) +MD_REFLINK = re.compile( + r'^!?\[(' + r'(?:\[[^^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*' + r')\]\s*\[([^^\]]*)\]' +) + XML_MATCH = re.compile(r'<[^>]+>') XML_ENTITY_MATCH = re.compile(r'&#?\w+;') @@ -176,3 +182,28 @@ def check_highlight(self, source, unit): for match in XML_ENTITY_MATCH.finditer(source): ret.append((match.start(), match.end(), match.group())) return ret + + +class MarkdownBaseCheck(TargetCheck): + default_disabled = True + + def __init__(self): + super(MarkdownBaseCheck, self).__init__() + self.enable_string = 'md-text' + + +class MarkdownRefLinkCheck(MarkdownBaseCheck): + check_id = 'md-reflink' + name = _('Markdown link references') + description = _('Markdown link references does not match source') + + def check_single(self, source, target, unit): + src_match = MD_REFLINK.findall(source) + if not src_match: + return False + tgt_match = MD_REFLINK.findall(target) + + src_tags = {x[1] for x in src_match} + tgt_tags = {x[1] for x in tgt_match} + + return src_tags != tgt_tags diff --git a/weblate/checks/models.py b/weblate/checks/models.py index 97294aa657d8..bf6316944d8d 100644 --- a/weblate/checks/models.py +++ b/weblate/checks/models.py @@ -67,6 +67,7 @@ class WeblateChecksConf(AppConf): 'weblate.checks.chars.ZeroWidthSpaceCheck', 'weblate.checks.markup.XMLValidityCheck', 'weblate.checks.markup.XMLTagsCheck', + 'weblate.checks.markup.MarkdownRefLinkCheck', 'weblate.checks.source.OptionalPluralCheck', 'weblate.checks.source.EllipsisCheck', 'weblate.checks.source.MultipleFailingCheck', diff --git a/weblate/checks/tests/test_checks.py b/weblate/checks/tests/test_checks.py index 7bf87a264f45..3e4b33e03282 100644 --- a/weblate/checks/tests/test_checks.py +++ b/weblate/checks/tests/test_checks.py @@ -92,6 +92,7 @@ def setUp(self): self.test_good_matching = ('string', 'string', '') self.test_good_none = ('string', 'string', '') self.test_good_ignore = () + self.test_good_flag = () self.test_failure_1 = () self.test_failure_2 = () self.test_failure_3 = () @@ -141,6 +142,17 @@ def test_single_failure_2(self): def test_single_failure_3(self): self.do_test(True, self.test_failure_3) + def test_check_good_flag(self): + if self.check is None or not self.test_good_flag: + return + self.assertFalse( + self.check.check_target( + [self.test_good_flag[0]], + [self.test_good_flag[1]], + MockUnit(None, self.test_good_flag[2]) + ) + ) + def test_check_good_matching_singular(self): if self.check is None: return diff --git a/weblate/checks/tests/test_markup_checks.py b/weblate/checks/tests/test_markup_checks.py index fa0cad31d803..1791b8d4839a 100644 --- a/weblate/checks/tests/test_markup_checks.py +++ b/weblate/checks/tests/test_markup_checks.py @@ -27,6 +27,7 @@ BBCodeCheck, XMLTagsCheck, XMLValidityCheck, + MarkdownRefLinkCheck, ) from weblate.checks.tests.test_checks import CheckTestCase @@ -149,3 +150,14 @@ def test_root(self): '' ), ) + + +class MarkdownRefLinkCheckTest(CheckTestCase): + check = MarkdownRefLinkCheck() + + def setUp(self): + super(MarkdownRefLinkCheckTest, self).setUp() + self.test_good_matching = ('[a][a1]', '[b][a1]', 'md-text') + self.test_good_none = ('string', 'string', 'md-text') + self.test_good_flag = ('[a][a1]', '[b][a2]', '') + self.test_failure_1 = ('[a][a1]', '[b][a2]', 'md-text') diff --git a/weblate/settings_example.py b/weblate/settings_example.py index e02cac07af47..6a9ba4a9b3a0 100644 --- a/weblate/settings_example.py +++ b/weblate/settings_example.py @@ -692,6 +692,7 @@ # 'weblate.checks.chars.ZeroWidthSpaceCheck', # 'weblate.checks.markup.XMLValidityCheck', # 'weblate.checks.markup.XMLTagsCheck', +# 'weblate.checks.markup.MarkdownRefLinkCheck', # 'weblate.checks.source.OptionalPluralCheck', # 'weblate.checks.source.EllipsisCheck', # 'weblate.checks.source.MultipleFailingCheck',