| 163 | |
| 164 | |
| 165 | class Untokenizer: |
| 166 | |
| 167 | def __init__(self): |
| 168 | self.tokens = [] |
| 169 | self.prev_row = 1 |
| 170 | self.prev_col = 0 |
| 171 | self.prev_type = None |
| 172 | self.prev_line = "" |
| 173 | self.encoding = None |
| 174 | |
| 175 | def add_whitespace(self, start): |
| 176 | row, col = start |
| 177 | if row < self.prev_row or row == self.prev_row and col < self.prev_col: |
| 178 | raise ValueError("start ({},{}) precedes previous end ({},{})" |
| 179 | .format(row, col, self.prev_row, self.prev_col)) |
| 180 | self.add_backslash_continuation(start) |
| 181 | col_offset = col - self.prev_col |
| 182 | if col_offset: |
| 183 | self.tokens.append(" " * col_offset) |
| 184 | |
| 185 | def add_backslash_continuation(self, start): |
| 186 | """Add backslash continuation characters if the row has increased |
| 187 | without encountering a newline token. |
| 188 | |
| 189 | This also inserts the correct amount of whitespace before the backslash. |
| 190 | """ |
| 191 | row = start[0] |
| 192 | row_offset = row - self.prev_row |
| 193 | if row_offset == 0: |
| 194 | return |
| 195 | |
| 196 | newline = '\r\n' if self.prev_line.endswith('\r\n') else '\n' |
| 197 | line = self.prev_line.rstrip('\\\r\n') |
| 198 | ws = ''.join(_itertools.takewhile(str.isspace, reversed(line))) |
| 199 | self.tokens.append(ws + f"\\{newline}" * row_offset) |
| 200 | self.prev_col = 0 |
| 201 | |
| 202 | def escape_brackets(self, token): |
| 203 | characters = [] |
| 204 | consume_until_next_bracket = False |
| 205 | for character in token: |
| 206 | if character == "}": |
| 207 | if consume_until_next_bracket: |
| 208 | consume_until_next_bracket = False |
| 209 | else: |
| 210 | characters.append(character) |
| 211 | if character == "{": |
| 212 | n_backslashes = sum( |
| 213 | 1 for char in _itertools.takewhile( |
| 214 | "\\".__eq__, |
| 215 | characters[-2::-1] |
| 216 | ) |
| 217 | ) |
| 218 | if n_backslashes % 2 == 0 or characters[-1] != "N": |
| 219 | characters.append(character) |
| 220 | else: |
| 221 | consume_until_next_bracket = True |
| 222 | characters.append(character) |
no outgoing calls
no test coverage detected
searching dependent graphs…