| 779 | |
| 780 | |
| 781 | class _TemplateReader(object): |
| 782 | def __init__(self, name: str, text: str, whitespace: str) -> None: |
| 783 | self.name = name |
| 784 | self.text = text |
| 785 | self.whitespace = whitespace |
| 786 | self.line = 1 |
| 787 | self.pos = 0 |
| 788 | |
| 789 | def find(self, needle: str, start: int = 0, end: Optional[int] = None) -> int: |
| 790 | assert start >= 0, start |
| 791 | pos = self.pos |
| 792 | start += pos |
| 793 | if end is None: |
| 794 | index = self.text.find(needle, start) |
| 795 | else: |
| 796 | end += pos |
| 797 | assert end >= start |
| 798 | index = self.text.find(needle, start, end) |
| 799 | if index != -1: |
| 800 | index -= pos |
| 801 | return index |
| 802 | |
| 803 | def consume(self, count: Optional[int] = None) -> str: |
| 804 | if count is None: |
| 805 | count = len(self.text) - self.pos |
| 806 | newpos = self.pos + count |
| 807 | self.line += self.text.count("\n", self.pos, newpos) |
| 808 | s = self.text[self.pos : newpos] |
| 809 | self.pos = newpos |
| 810 | return s |
| 811 | |
| 812 | def remaining(self) -> int: |
| 813 | return len(self.text) - self.pos |
| 814 | |
| 815 | def __len__(self) -> int: |
| 816 | return self.remaining() |
| 817 | |
| 818 | def __getitem__(self, key: Union[int, slice]) -> str: |
| 819 | if isinstance(key, slice): |
| 820 | size = len(self) |
| 821 | start, stop, step = key.indices(size) |
| 822 | if start is None: |
| 823 | start = self.pos |
| 824 | else: |
| 825 | start += self.pos |
| 826 | if stop is not None: |
| 827 | stop += self.pos |
| 828 | return self.text[slice(start, stop, step)] |
| 829 | elif key < 0: |
| 830 | return self.text[key] |
| 831 | else: |
| 832 | return self.text[self.pos + key] |
| 833 | |
| 834 | def __str__(self) -> str: |
| 835 | return self.text[self.pos :] |
| 836 | |
| 837 | def raise_parse_error(self, msg: str) -> None: |
| 838 | raise ParseError(msg, self.name, self.line) |