Completed
Push — master ( 41137e...c24e96 )
by
unknown
02:00
created

SpacingHelper.replace_spaces_with_tabs()   D

Complexity

Conditions 8

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
c 0
b 0
f 0
dl 0
loc 44
rs 4
1
from coalib.bearlib.abstractions.SectionCreatable import SectionCreatable
2
from coala_utils.decorators import enforce_signature
3
4
5
class SpacingHelper(SectionCreatable):
6
    DEFAULT_TAB_WIDTH = 4
7
8
    def __init__(self, tab_width: int=DEFAULT_TAB_WIDTH):
9
        """
10
        Creates a helper object for spacing operations.
11
12
        :param tab_width: The number of spaces which visually equals a tab.
13
        """
14
        SectionCreatable.__init__(self)
15
        if not isinstance(tab_width, int):
16
            raise TypeError("The 'tab_width' parameter should be an integer.")
17
18
        self.tab_width = tab_width
19
20
    @enforce_signature
21
    def get_indentation(self, line: str):
22
        """
23
        Checks the lines indentation.
24
25
        :param line: A string to check for indentation.
26
        :return:     The indentation count in spaces.
27
        """
28
        count = 0
29
        for char in line:
30
            if char == ' ':
31
                count += 1
32
                continue
33
34
            if char == '\t':
35
                count += self.tab_width - (count % self.tab_width)
36
                continue
37
38
            break
39
40
        return count
41
42
    @enforce_signature
43
    def replace_tabs_with_spaces(self, line: str):
44
        """
45
        Replaces tabs in this line with the appropriate number of spaces.
46
47
        Example: " \t" will be converted to "    ", assuming the tab_width is
48
        set to 4.
49
50
        :param line: The string with tabs to replace.
51
        :return:     A string with no tabs.
52
        """
53
        for t_position, t_length in sorted(self.yield_tab_lengths(line),
54
                                           reverse=True):
55
            line = line[:t_position] + t_length * ' ' + line[t_position+1:]
56
57
        return line
58
59
    @enforce_signature
60
    def yield_tab_lengths(self, input: str):
61
        """
62
        Yields position and size of tabs in a input string.
63
64
        :param input: The string with tabs.
65
        """
66
        tabless_position = 0
67
        for index, char in enumerate(input):
68
            if char == '\t':
69
                space_count = (self.tab_width - tabless_position
70
                               % self.tab_width)
71
                yield index, space_count
72
                tabless_position += space_count
73
                continue
74
75
            tabless_position += 1
76
77
    @enforce_signature
78
    def replace_spaces_with_tabs(self, line: str):
79
        """
80
        Replaces spaces with tabs where possible. However in no case only one
81
        space will be replaced by a tab.
82
83
        Example: " \t   a_text   another" will be converted to
84
        "\t   a_text\tanother", assuming the tab_width is set to 4.
85
86
        :param line: The string with spaces to replace.
87
        :return:     The converted string.
88
        """
89
        currspaces = 0
90
        result = ""
91
        # Tracking the index of the string isnt enough because tabs are
92
        # spanning over multiple columns
93
        tabless_position = 0
94
        for char in line:
95
            if char == " ":
96
                currspaces += 1
97
                tabless_position += 1
98
            elif char == "\t":
99
                space_count = (self.tab_width - tabless_position
100
                               % self.tab_width)
101
                currspaces += space_count
102
                tabless_position += space_count
103
            else:
104
                result += currspaces*" " + char
105
                currspaces = 0
106
                tabless_position += 1
107
108
            # tabless_position is now incremented to point _after_ the current
109
            # char
110
            if tabless_position % self.tab_width == 0 and currspaces:
111
                if currspaces == 1 and char == " ":
112
                    result += " "
113
                else:
114
                    result += "\t"
115
116
                currspaces = 0
117
118
        result += currspaces*" "
119
120
        return result
121