diff --git a/sphinxlint/checkers.py b/sphinxlint/checkers.py index 5354606f6..4fe038c62 100644 --- a/sphinxlint/checkers.py +++ b/sphinxlint/checkers.py @@ -461,10 +461,12 @@ def check_block(block_lineno, block): yield from errors +_DANGLING_HYPHEN_RE = re.compile(r".*[a-z]-$") + @checker(".rst", rst_only=True) def check_dangling_hyphen(file, lines, options): """Check for lines ending in a hyphen.""" for lno, line in enumerate(lines): stripped_line = line.rstrip("\n") - if re.match(r".*[a-z]-$", stripped_line): + if _DANGLING_HYPHEN_RE.match(stripped_line): yield lno + 1, f"Line ends with dangling hyphen" diff --git a/sphinxlint/utils.py b/sphinxlint/utils.py index f15465545..61a2ec75c 100644 --- a/sphinxlint/utils.py +++ b/sphinxlint/utils.py @@ -121,17 +121,22 @@ def looks_like_glued(match): return True +_START_OF_COMMENT_BLOCK_RE = re.compile(r"^\s*\.\.$") +_PRODUCTION_LIST_DIRECTIVE_RE = re.compile(r"^ *.. productionlist::") +_COMMENT_RE = re.compile(r"^ *\.\. ") + + def is_multiline_non_rst_block(line): """Returns True if the next lines are an indented literal block.""" - if re.match(r"^\s*\.\.$", line): # it's the start of a comment block. + if _START_OF_COMMENT_BLOCK_RE.search(line): return True if rst.DIRECTIVES_CONTAINING_RST_RE.match(line): return False if rst.DIRECTIVES_CONTAINING_ARBITRARY_CONTENT_RE.match(line): return True - if re.match(r"^ *.. productionlist::", line): + if _PRODUCTION_LIST_DIRECTIVE_RE.search(line): return True - if re.match(r"^ *\.\. ", line) and type_of_explicit_markup(line) == "comment": + if _COMMENT_RE.search(line) and type_of_explicit_markup(line) == "comment": return True if line.endswith("::\n"): # It's a literal block return True @@ -164,7 +169,7 @@ def hide_non_rst_blocks(lines, hidden_block_cb=None): block_line_start = lineno assert not excluded_lines if ( - re.match(r" *\.\. ", line) + _COMMENT_RE.search(line) and type_of_explicit_markup(line) == "comment" ): line = "\n"