#!/usr/bin/env python # encoding: utf-8 """Utilities to deal with text.""" def unescape(text): """Removes '\\' escaping from 'text'.""" rv = '' i = 0 while i < len(text): if i + 1 < len(text) and text[i] == '\\': rv += text[i + 1] i += 1 else: rv += text[i] i += 1 return rv def escape(text, chars): """Escapes all characters in 'chars' in text using backspaces.""" rv = '' for char in text: if char in chars: rv += '\\' rv += char return rv def fill_in_whitespace(text): """Returns 'text' with escaped whitespace replaced through whitespaces.""" text = text.replace(r"\n", '\n') text = text.replace(r"\t", '\t') text = text.replace(r"\r", '\r') text = text.replace(r"\a", '\a') text = text.replace(r"\b", '\b') return text def head_tail(line): """Returns the first word in 'line' and the rest of 'line' or None if the line is too short.""" generator = (t.strip() for t in line.split(None, 1)) head = next(generator).strip() tail = '' try: tail = next(generator).strip() except StopIteration: pass return head, tail class LineIterator(object): """Convenience class that keeps track of line numbers in files.""" def __init__(self, text): self._line_index = -1 self._lines = list(text.splitlines(True)) def __iter__(self): return self def __next__(self): """Returns the next line.""" if self._line_index + 1 < len(self._lines): self._line_index += 1 return self._lines[self._line_index] raise StopIteration() next = __next__ # for python2 @property def line_index(self): """The 1 based line index in the current file.""" return self._line_index + 1 def peek(self): """Returns the next line (if there is any, otherwise None) without advancing the iterator.""" try: return self._lines[self._line_index + 1] except IndexError: return None