|
26 | 26 | # SOFTWARE. |
27 | 27 | """This module provides docformatter's list pattern recognition functions.""" |
28 | 28 |
|
29 | | - |
30 | 29 | # Standard Library Imports |
31 | 30 | import re |
32 | 31 | from re import Match |
|
53 | 52 | from .misc import is_inline_math, is_literal_block |
54 | 53 |
|
55 | 54 |
|
| 55 | +def _create_multiline_windows(lines: list[str], window_size: int = 3) -> list[str]: |
| 56 | + r"""Create overlapping windows of consecutive lines. |
| 57 | +
|
| 58 | + This allows pattern matching against multi-line constructs like |
| 59 | + NumPy section headers (e.g., "Parameters\\n----------") and reST |
| 60 | + section headers (e.g., "Title\\n====="). |
| 61 | +
|
| 62 | + Parameters |
| 63 | + ---------- |
| 64 | + lines : list[str] |
| 65 | + The list of individual lines. |
| 66 | + window_size : int |
| 67 | + Number of consecutive lines to join (default 3). |
| 68 | +
|
| 69 | + Returns |
| 70 | + ------- |
| 71 | + list[str] |
| 72 | + List of multi-line strings, each containing window_size consecutive |
| 73 | + lines joined with newlines. |
| 74 | +
|
| 75 | + Notes |
| 76 | + ----- |
| 77 | + Example: |
| 78 | + lines = ['A', 'B', 'C', 'D'] |
| 79 | + _create_multiline_windows(lines, 2) |
| 80 | + # Returns: ['A\\nB', 'B\\nC', 'C\\nD'] |
| 81 | + """ |
| 82 | + if len(lines) < window_size: |
| 83 | + return ["\n".join(lines)] if lines else [] |
| 84 | + |
| 85 | + return [ |
| 86 | + "\n".join(lines[i : i + window_size]) |
| 87 | + for i in range(len(lines) - window_size + 1) |
| 88 | + ] |
| 89 | + |
| 90 | + |
56 | 91 | def is_type_of_list( |
57 | 92 | text: str, |
58 | 93 | strict: bool, |
@@ -83,16 +118,22 @@ def is_type_of_list( |
83 | 118 | if is_field_list(text, style): |
84 | 119 | return False |
85 | 120 |
|
| 121 | + # Check for multi-line patterns (section headers) first. |
| 122 | + # These require looking at consecutive lines together. |
| 123 | + multiline_windows = _create_multiline_windows(split_lines, window_size=2) |
| 124 | + for window in multiline_windows: |
| 125 | + if is_rest_section_header(window) or is_numpy_section_header(window): |
| 126 | + return True |
| 127 | + |
| 128 | + # Check single-line patterns. |
86 | 129 | return any( |
87 | 130 | ( |
88 | 131 | is_bullet_list(line) |
89 | 132 | or is_enumerated_list(line) |
90 | | - or is_rest_section_header(line) |
91 | 133 | or is_option_list(line) |
92 | 134 | or is_epytext_field_list(line) |
93 | 135 | or is_sphinx_field_list(line) |
94 | 136 | or is_numpy_field_list(line) |
95 | | - or is_numpy_section_header(line) |
96 | 137 | or is_google_field_list(line) |
97 | 138 | or is_user_defined_field_list(line) |
98 | 139 | or is_literal_block(line) |
|
0 commit comments