1+ """
2+ This module provides utilities for analyzing and manipulating indentation in text.
3+
4+ It includes functions and classes for extracting indentation, analyzing indentation
5+ patterns, and adjusting indentation levels in text content. These tools are particularly
6+ useful for processing and formatting source code or other text with structured indentation.
7+
8+ Key components:
9+ - get_line_indent_count: Counts the number of leading whitespace characters in a line.
10+ - extract_indentation: Extracts the leading whitespace from a line.
11+ - IndentationInfo: A class that analyzes and represents indentation patterns in text.
12+
13+ This module is designed to work with various indentation styles, including spaces and tabs,
14+ and can handle inconsistent or mixed indentation patterns.
15+ """
16+
117from collections import Counter
218from collections .abc import Sequence
319from math import gcd
420from typing import NamedTuple
521
622
7- def get_line_indent_count (line : str ):
23+ def get_line_indent_count (line : str ) -> int :
24+ """
25+ Count the number of leading whitespace characters in a line.
26+
27+ Args:
28+ line (str): The input line to analyze.
29+
30+ Returns:
31+ int: The number of leading whitespace characters.
32+
33+ Example:
34+ >>> get_line_indent_count(" Hello")
35+ 4
36+ >>> get_line_indent_count("\t \t World")
37+ 2
38+ """
839 return len (line ) - len (line .lstrip ())
940
1041
1142def extract_indentation (line : str ) -> str :
1243 """
1344 Extract the leading whitespace from a given line.
1445
46+ This function identifies and returns the leading whitespace characters
47+ (spaces or tabs) from the beginning of the input line.
48+
1549 Args:
1650 line (str): The input line to process.
1751
@@ -33,10 +67,9 @@ class IndentationInfo(NamedTuple):
3367 """
3468 A class to represent and manage indentation information.
3569
36- This class analyzes and provides utilities for working with indentation.
37- It detects the indentation character (space or tab),
38- the number of characters used for each indentation level, and provides
39- methods to adjust and normalize indentation.
70+ This class analyzes and provides utilities for working with indentation in text content.
71+ It detects the indentation character (space or tab), the number of characters used for
72+ each indentation level, and provides methods to adjust and normalize indentation.
4073
4174 Attributes:
4275 char_count (int): The number of characters used for each indentation level.
@@ -56,9 +89,16 @@ class IndentationInfo(NamedTuple):
5689 apply_relative_indents: Applies relative indentation based on annotations in the content.
5790
5891 Note:
59- This class is particularly useful for processing Python code with varying
92+ This class is particularly useful for processing code or text with varying
6093 or inconsistent indentation, and for adjusting indentation to meet specific
61- formatting requirements.
94+ formatting requirements. It can handle both space and tab indentation, as well
95+ as mixed indentation styles.
96+
97+ Example:
98+ >>> content = " def example():\n print('Hello')\n \t \t print('World')"
99+ >>> info = IndentationInfo.from_content(content)
100+ >>> print(info.char, info.char_count, info.consistency)
101+ ' ' 4 False
62102 """
63103 char_count : int
64104 char : str
@@ -134,26 +174,53 @@ def from_content(cls, content: str | Sequence[str]) -> 'IndentationInfo':
134174
135175 return cls (char_count , dominant_char , min_indent_level , consistency , message )
136176
137- def level_difference (self , base_indentation_count : int ):
177+ def level_difference (self , base_indentation_count : int ) -> int :
178+ """
179+ Calculate the difference in indentation levels.
180+
181+ Args:
182+ base_indentation_count (int): The base indentation count to compare against.
183+
184+ Returns:
185+ int: The difference in indentation levels.
186+ """
138187 return self .char_count_to_level (base_indentation_count ) - self .min_indent_level
139188
140189 def char_count_to_level (self , char_count : int ) -> int :
190+ """
191+ Convert a character count to an indentation level.
192+
193+ Args:
194+ char_count (int): The number of indentation characters.
195+
196+ Returns:
197+ int: The corresponding indentation level.
198+ """
141199 return char_count // self .char_count
142200
143201 def level_to_chars (self , level : int ) -> str :
202+ """
203+ Convert an indentation level to a string of indentation characters.
204+
205+ Args:
206+ level (int): The indentation level.
207+
208+ Returns:
209+ str: A string of indentation characters for the given level.
210+ """
144211 return level * self .char_count * self .char
145212
146213 def shift_indentation (self , lines : Sequence [str ], target_base_indentation_count : int ) -> list [str ]:
147214 """
148- Shifts the indentation of a sequence of lines based on a base indentation count.
215+ Shift the indentation of a sequence of lines based on a target base indentation count.
149216
150217 This method adjusts the indentation of each non-empty line in the input sequence.
151- It calculates the difference between the base indentation and the minimum
218+ It calculates the difference between the target base indentation and the minimum
152219 indentation found in the content, then applies this shift to all lines.
153220
154221 Args:
155222 lines (Sequence[str]): A sequence of strings representing the lines to be adjusted.
156- target_base_indentation_count (int): The base indentation count to adjust from .
223+ target_base_indentation_count (int): The target base indentation count to adjust to .
157224
158225 Returns:
159226 list[str]: A new list of strings with adjusted indentation.
@@ -163,6 +230,12 @@ def shift_indentation(self, lines: Sequence[str], target_base_indentation_count:
163230 - The method uses the IndentationInfo of the instance to determine
164231 the indentation character and count.
165232 - This method is useful for uniformly adjusting indentation across all lines.
233+
234+ Example:
235+ >>> info = IndentationInfo(4, ' ', 1, True)
236+ >>> lines = [" def example():", " print('Hello')"]
237+ >>> info.shift_indentation(lines, 8)
238+ [' def example():', ' print('Hello')']
166239 """
167240 raw_line_adjuster = self ._shift_indentation_fun (target_base_indentation_count )
168241 # Return the transformed lines
@@ -187,7 +260,7 @@ def adjust_line(line: str) -> str:
187260
188261 def apply_relative_indents (self , content : str | Sequence [str ], context_indent_count : int = 0 ) -> list [str ]:
189262 """
190- Applies relative indentation based on annotations in the content.
263+ Apply relative indentation based on annotations in the content.
191264
192265 This method processes the input content, interpreting special annotations
193266 to apply relative indentation. It uses '@' followed by a number to indicate
@@ -213,6 +286,12 @@ def apply_relative_indents(self, content: str | Sequence[str], context_indent_co
213286
214287 Raises:
215288 AssertionError: If the calculated indentation level for any line is negative.
289+
290+ Example:
291+ >>> info = IndentationInfo(4, ' ', 0, True)
292+ >>> content = ["@0:def example():", "@1: print('Hello')", "@2: if True:", "@3: print('World')"]
293+ >>> info.apply_relative_indents(content, 4)
294+ [' def example():', ' print('Hello')', ' if True:', ' print('World')']
216295 """
217296 # TODO Always send str?
218297 lines = [l .lstrip () for l in content .splitlines () if l .strip ()] if isinstance (content , str ) else content
0 commit comments