Completed
Push — master ( fd0be2...07b14a )
by Jace
03:41
created

Text.path()   A

Complexity

Conditions 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 9
ccs 6
cts 6
cp 1
crap 2
rs 9.6666
c 0
b 0
f 0
1 1
class Text:
2
3 1
    EMPTY = '_'
4 1
    SPACE = '-'
5 1
    SPECIAL = {
6
        '?': '~q',
7
        '%': '~p',
8
        '#': '~h',
9
        '/': '~s',
10
        '"': "''",
11
    }
12
13 1
    def __init__(self, path=None, *, translate_spaces=True):
14 1
        if path is None:
15 1
            self._parts = []
16 1
        elif isinstance(path, str):
17 1
            self._parts = path.split('/')
18
        else:
19 1
            assert isinstance(path, list)
20 1
            self._parts = path
21 1
        self._translate_spaces = translate_spaces
22
23 1
    def __str__(self):
24 1
        return ' / '.join(self.lines)
25
26 1
    def __bool__(self):
27 1
        return bool(self.path.strip(self.EMPTY + '/'))
28
29 1
    def __getitem__(self, key):
30 1
        try:
31 1
            part = self._parts[key]
32 1
        except (IndexError, ValueError):
33 1
            return ""
34
        else:
35 1
            return part.strip()
36
37 1
    @property
38
    def top(self):
39 1
        return self.get_line(0)
40
41 1
    @property
42
    def bottom(self):
43 1
        return self.get_line(1)
44
45 1
    @property
46
    def lines(self):
47 1
        lines = []
48
49 1
        previous_part = True
50 1
        for part in self:
51 1
            if part:
52 1
                line = self._format_line(part, self._translate_spaces)
53 1
                lines.append(line)
54 1
            elif not previous_part:
55 1
                break
56
            else:
57 1
                lines.append(' ')
58 1
            previous_part = part
59
60 1
        return lines[:-1]
61
62 1
    @property
63
    def path(self):
64 1
        paths = []
65
66 1
        for line in self.lines:
67 1
            path = self._format_path(line)
68 1
            paths.append(path)
69
70 1
        return '/'.join(paths)
71
72 1
    @classmethod
73
    def _format_line(cls, text, translate_spaces):
74 1
        for special, replacement in cls.SPECIAL.items():
75 1
            text = text.replace(replacement, special)
76 1
            text = text.replace(replacement.upper(), special)
77
78 1
        chars = []
79 1
        escape = None
80
81 1
        for index, char in enumerate(text):
82
83 1
            if char in (cls.EMPTY, cls.SPACE) and translate_spaces:
84 1
                if char == escape:
85 1
                    chars[-1] = escape
86 1
                    escape = None
87
                else:
88 1
                    chars.append(' ')
89 1
                    escape = char
90 1
                continue
91
            else:
92 1
                escape = None
93
94 1
            if not char.isalpha():
95 1
                chars.append(char)
96 1
                continue
97
98 1
            if len(chars) >= 2:
99 1
                if char.isupper() and chars[-1].islower() and chars[-2] != ' ':
100 1
                    chars.append(' ' + char)
101 1
                    continue
102
103 1
            if len(chars) >= 1 and len(text) > index + 1:
104 1
                n_char = text[index + 1]
105 1
                if char.isupper() and chars[-1].isupper() and n_char.islower():
106 1
                    chars.append(' ' + char)
107 1
                    continue
108
109 1
            chars.append(char)
110
111 1
        return ''.join(chars).upper()
112
113 1
    @classmethod
114
    def _format_path(cls, line):
115 1
        if line == ' ':
116 1
            path = cls.EMPTY
117
        else:
118 1
            path = line.lower()
119 1
            path = path.replace(cls.SPACE, cls.SPACE * 2)
120 1
            path = path.replace(cls.EMPTY, cls.EMPTY * 2)
121 1
            path = path.replace(' ', cls.SPACE)
122 1
            for special, replacement in cls.SPECIAL.items():
123 1
                path = path.replace(special, replacement)
124
125 1
        return path
126
127 1
    def get_line(self, index):
128
        return self._format_line(self[index], self._translate_spaces)
129