MediaWiki does not treat [[]] or [[|...]] as wikilinks because their title is empty. Calls to filter_wikilinks() on text containing these sequences returned false positives. The fix is in builder.py (pure Python, runs for both the C and Python tokenizers): when a WikilinkClose token is encountered and the resulting title is an empty string, the node is demoted to a plain Text node containing the original bracket sequence instead of being wrapped in a Wikilink. Fixes #292.pull/362/head
| @@ -162,8 +162,14 @@ class Builder: | |||||
| self._push() | self._push() | ||||
| elif isinstance(token, tokens.WikilinkClose): | elif isinstance(token, tokens.WikilinkClose): | ||||
| if title is not None: | if title is not None: | ||||
| return Wikilink(title, self._pop()) | |||||
| return Wikilink(self._pop()) | |||||
| wikilink = Wikilink(title, self._pop()) | |||||
| else: | |||||
| wikilink = Wikilink(self._pop()) | |||||
| # MediaWiki treats [[]] and [[|...]] (empty title) as plain | |||||
| # text rather than actual wikilinks. | |||||
| if not str(wikilink.title): | |||||
| return Text(str(wikilink)) | |||||
| return wikilink | |||||
| else: | else: | ||||
| self._write(self._handle_token(token)) | self._write(self._handle_token(token)) | ||||
| raise ParserError("_handle_wikilink() missed a close token") | raise ParserError("_handle_wikilink() missed a close token") | ||||
| @@ -102,3 +102,24 @@ def test_skip_style_tags(pyparser): | |||||
| without_style = parser.Parser().parse(text, skip_style_tags=True) | without_style = parser.Parser().parse(text, skip_style_tags=True) | ||||
| assert_wikicode_equal(a, with_style) | assert_wikicode_equal(a, with_style) | ||||
| assert_wikicode_equal(b, without_style) | assert_wikicode_equal(b, without_style) | ||||
| @pytest.mark.parametrize( | |||||
| "text", | |||||
| [ | |||||
| "[[]]", | |||||
| "[[|]]", | |||||
| "[[|foo]]", | |||||
| "[[|||]]", | |||||
| ], | |||||
| ) | |||||
| def test_empty_title_wikilink_is_text(text): | |||||
| """[[]] and [[|...]] have an empty title and should not be wikilinks. | |||||
| MediaWiki does not render these as hyperlinks; the parser must treat them | |||||
| as plain text so that filter_wikilinks() does not return false positives. | |||||
| Regression test for https://github.com/earwig/mwparserfromhell/issues/292. | |||||
| """ | |||||
| parsed = parser.Parser().parse(text) | |||||
| assert parsed.filter_wikilinks() == [] | |||||
| assert str(parsed) == text | |||||