Return a (line, char) tuple of int indexes into self.data. This implements .index without converting the result back to a string. The result is constrained by the number of lines and linelengths of self.data. For many indexes, the result is initially (1, 0). The inp
(self, index, endflag=0)
| 117 | return "%s.%s" % self._decode(index, endflag=1) |
| 118 | |
| 119 | def _decode(self, index, endflag=0): |
| 120 | """Return a (line, char) tuple of int indexes into self.data. |
| 121 | |
| 122 | This implements .index without converting the result back to a string. |
| 123 | The result is constrained by the number of lines and linelengths of |
| 124 | self.data. For many indexes, the result is initially (1, 0). |
| 125 | |
| 126 | The input index may have any of several possible forms: |
| 127 | * line.char float: converted to 'line.char' string; |
| 128 | * 'line.char' string, where line and char are decimal integers; |
| 129 | * 'line.char lineend', where lineend='lineend' (and char is ignored); |
| 130 | * 'line.end', where end='end' (same as above); |
| 131 | * 'insert', the positions before terminal \n; |
| 132 | * 'end', whose meaning depends on the endflag passed to ._endex. |
| 133 | * 'sel.first' or 'sel.last', where sel is a tag -- not implemented. |
| 134 | """ |
| 135 | if isinstance(index, (float, bytes)): |
| 136 | index = str(index) |
| 137 | try: |
| 138 | index=index.lower() |
| 139 | except AttributeError: |
| 140 | raise TclError('bad text index "%s"' % index) from None |
| 141 | |
| 142 | lastline = len(self.data) - 1 # same as number of text lines |
| 143 | if index == 'insert': |
| 144 | return lastline, len(self.data[lastline]) - 1 |
| 145 | elif index == 'end': |
| 146 | return self._endex(endflag) |
| 147 | |
| 148 | line, char = index.split('.') |
| 149 | line = int(line) |
| 150 | |
| 151 | # Out of bounds line becomes first or last ('end') index |
| 152 | if line < 1: |
| 153 | return 1, 0 |
| 154 | elif line > lastline: |
| 155 | return self._endex(endflag) |
| 156 | |
| 157 | linelength = len(self.data[line]) -1 # position before/at \n |
| 158 | if char.endswith(' lineend') or char == 'end': |
| 159 | return line, linelength |
| 160 | # Tk requires that ignored chars before ' lineend' be valid int |
| 161 | if m := re.fullmatch(r'end-(\d*)c', char, re.A): # Used by hyperparser. |
| 162 | return line, linelength - int(m.group(1)) |
| 163 | |
| 164 | # Out of bounds char becomes first or last index of line |
| 165 | char = int(char) |
| 166 | if char < 0: |
| 167 | char = 0 |
| 168 | elif char > linelength: |
| 169 | char = linelength |
| 170 | return line, char |
| 171 | |
| 172 | def _endex(self, endflag): |
| 173 | '''Return position for 'end' or line overflow corresponding to endflag. |