diff --git a/sphinxlint/checkers.py b/sphinxlint/checkers.py index 05afe352d..7b94be74f 100644 --- a/sphinxlint/checkers.py +++ b/sphinxlint/checkers.py @@ -250,13 +250,28 @@ def check_missing_underscore_after_hyperlink(file, lines, options=None): Bad: `Link text ` Good: `Link text `_ + + Note: + URLs within download directives don't need trailing underscores. + https://www.sphinx-doc.org/en/master/usage/referencing.html#role-download """ for lno, line in enumerate(lines, start=1): if "`" not in line: continue for match in rst.SEEMS_HYPERLINK_RE.finditer(line): if not match.group(2): - yield lno, "missing underscore after closing backtick in hyperlink" + # Check if this is within any download directive on the line + # Include optional underscore in pattern to handle both cases + is_in_download = False + for download_match in rst.HYPERLINK_WITHIN_DOWNLOAD_RE.finditer(line): + if ( + match.start() >= download_match.start() + and match.end() <= download_match.end() + ): + is_in_download = True + break + if not is_in_download: + yield lno, "missing underscore after closing backtick in hyperlink" @checker(".rst", ".po") diff --git a/sphinxlint/rst.py b/sphinxlint/rst.py index 4c8c02617..455c186f0 100644 --- a/sphinxlint/rst.py +++ b/sphinxlint/rst.py @@ -270,9 +270,10 @@ def inline_markup_gen(start_string, end_string, extra_allowed_before=""): # The :issue`123` is ... ROLE_MISSING_RIGHT_COLON_RE = re.compile(rf"(^|\s):{SIMPLENAME}`(?!`)") - SEEMS_HYPERLINK_RE = re.compile(r"`[^`]+?(\s?)`(_?)") +HYPERLINK_WITHIN_DOWNLOAD_RE = re.compile(r":download:`[^`]*`_?") + LEAKED_MARKUP_RE = re.compile(r"[a-z]::\s|`|\.\.\s*\w+:") TRIPLE_BACKTICKS_RE = re.compile( diff --git a/tests/fixtures/xpass/download-directive-with-url.rst b/tests/fixtures/xpass/download-directive-with-url.rst new file mode 100644 index 000000000..149252495 --- /dev/null +++ b/tests/fixtures/xpass/download-directive-with-url.rst @@ -0,0 +1,16 @@ +Download directives should not require underscores after URLs. + +A basic download directive with https: +:download:`Download file ` + +One with http: +:download:`Get the archive ` + +An inline download: +This line contains a :download:`link to a file `. + +Multiple download directives in a row: +First :download:`Download this file ` and +then :download:`this one ` something else + +These should not trigger missing-underscore-after-hyperlink errors.