Source code for pyrser.fmt

## Helping class for pretty printing


[docs]class indentable: """ base of all fmt objects """ char_indent = " " num_indent = 4
[docs] def __init__(self): self._indent = 0 self._is_indented = False self._lsdata = None
[docs] def to_str(self, res: str) -> str: pass
[docs] def __str__(self): self.set_indent() strinit = (self.char_indent * self.num_indent) * (self._indent - 1) return self.to_str(strinit, self._indent)
@property def lsdata(self) -> list: return self._lsdata
[docs] def set_indent(self, indent: int=1): if self._is_indented: return self._indent = indent if isinstance(self._lsdata, indentable): self._lsdata.set_indent(self._indent) if isinstance(self._lsdata, list): list_set_indent(self._lsdata, self._indent) self._is_indented = True
[docs]def catend(dst: str, src: str, indent) -> str: """cat two strings but handle \n for tabulation""" res = dst txtsrc = src if not isinstance(src, str): txtsrc = str(src) for c in list(txtsrc): if len(res) > 0 and res[-1] == '\n': res += (indentable.char_indent * indentable.num_indent) * \ (indent - 1) + c else: res += c return res
[docs]def list_set_indent(lst: list, indent: int=1): """recurs into list for indentation""" for i in lst: if isinstance(i, indentable): i.set_indent(indent) if isinstance(i, list): list_set_indent(i, indent)
[docs]def list_to_str(lst: list, content: str, indent: int=1): """recurs into list for string computing """ for i in lst: if isinstance(i, indentable): content = i.to_str(content, indent) elif isinstance(i, list): content = list_to_str(i, content, indent) elif isinstance(i, str): content = catend(content, i, indent) return content
[docs]class block(indentable): """ for {}, (), [] """
[docs] def __init__(self, beginby: str, endby: str, lsdata: list): indentable.__init__(self) self._beginby = beginby self._endby = endby if lsdata is None: raise Exception("lsdata can't be None") self._lsdata = lsdata
[docs] def to_str(self, res: str, parent_indent) -> str: self.set_indent() content = catend(res, self._beginby, parent_indent) if isinstance(self._lsdata, indentable): return catend(self._lsdata.to_str(content, self._indent), self._endby, parent_indent) if isinstance(self._lsdata, list): content = list_to_str(self._lsdata, content, self._indent) return catend(content, self._endby, parent_indent)
[docs]class sep(indentable): """ for all list seperated by a char """
[docs] def __init__(self, ch: str, lsdata: list): indentable.__init__(self) self._ch = ch if lsdata is None: raise Exception("lsdata can't be None") self._lsdata = lsdata
[docs] def to_str(self, res: str, parent_indent) -> str: self.set_indent() content = res if isinstance(self._lsdata, indentable): return self._lsdata.to_str(res, self._indent) if isinstance(self._lsdata, list): sz = len(self._lsdata) for i in range(sz): if isinstance(self._lsdata[i], indentable): content = self._lsdata[i].to_str(content, self._indent) elif isinstance(self._lsdata[i], list): content = list_to_str(self._lsdata[i], content, self._indent) else: content = catend(content, self._lsdata[i], self._indent) if i < sz - 1: content = catend(content, self._ch, self._indent) return content
[docs]class end(indentable): """ for all list that end by a char """
[docs] def __init__(self, ch: str, lsdata: list): indentable.__init__(self) self._ch = ch if lsdata is None: raise Exception("lsdata can't be None") self._lsdata = lsdata
[docs] def to_str(self, res: str, parent_indent) -> str: self.set_indent() content = res if isinstance(self._lsdata, indentable): return catend(self._lsdata.to_str(res, self._indent), self._ch, self._indent) if isinstance(self._lsdata, list): for i in self._lsdata: if isinstance(i, indentable): content = i.to_str(content, self._indent) elif isinstance(i, list): content = list_to_str(i, content, self._indent) else: content = catend(content, i, self._indent) content = catend(content, self._ch, self._indent) return content
[docs]class tab(indentable): """ to handle indentation level """
[docs] def __init__(self, lsdata: indentable): indentable.__init__(self) if lsdata is None: raise Exception("lsdata can't be None") self._lsdata = lsdata
[docs] def set_indent(self, indent: int=1): if self._is_indented: return self._indent = indent + 1 if isinstance(self._lsdata, indentable): self._lsdata.set_indent(self._indent) if isinstance(self._lsdata, list): list_set_indent(self._lsdata, self._indent) self._is_indented = True
[docs] def to_str(self, res: str, parent_indent) -> str: self.set_indent() if isinstance(self._lsdata, indentable): return self._lsdata.to_str(res, self._indent) if isinstance(self._lsdata, list): content = res for i in self._lsdata: if isinstance(i, indentable): content = i.to_str(content, self._indent) elif isinstance(i, list): content = list_to_str(i, content, self._indent) else: content = catend(content, i, self._indent) return content