X7ROOT File Manager
Current Path:
/opt/cloudlinux/venv/lib/python3.11/site-packages/guppy/gsl
opt
/
cloudlinux
/
venv
/
lib
/
python3.11
/
site-packages
/
guppy
/
gsl
/
??
..
??
Document.py
(57.55 KB)
??
DottedTree.py
(8.58 KB)
??
Exceptions.py
(402 B)
??
FileIO.py
(2.6 KB)
??
Filer.py
(3.83 KB)
??
Gsml.py
(2.69 KB)
??
Help.py
(1018 B)
??
Html.py
(17.46 KB)
??
Latex.py
(25.16 KB)
??
Main.py
(66.91 KB)
??
SpecNodes.py
(18.48 KB)
??
Tester.py
(23.99 KB)
??
Text.py
(31.13 KB)
??
XHTML.py
(18.38 KB)
??
__init__.py
(53 B)
??
__pycache__
Editing: DottedTree.py
""" Handling of tree structures given in a special 'dotted' syntax. This represents trees of nodes with strings as tags, in a readable and writable and easy to parse syntax. There are two main functions, unparse_sexpr and parse_string. When parsing, the result is by default given in 'sexpr' format: each node is a tuple of the form (tag, ) or (tag, node) or (tag, node, node) ... The following invariant is intended to hold for every node x, parse_string(unparse_sexpr(x)) == x Currently the following invariant has been tested for some strings: unparse_sexpr(parse_string(s)).strip() == s.strip() [It only holds on stripped results but may be fixed sometime.] """ class Node(object): __slots__ = 'tag', 'children', 'index', def __init__(self, tag, children, index): self.tag = tag self.children = children self.index = index def as_sexpr(self): return (self.tag,) + tuple([c.as_sexpr() for c in self.children]) def __repr__(self): return '%s(%r, %r, %r)' % ( self.__class__.__name__, self.tag, self.children, self.index) class _GLUECLAMP_: _imports_ = ( '_parent.FileIO:IO', ) ## # The name of attributes that are configurable in instances. # _chgable_ = 'node', 'dotchar' ## # The character that begins the 'dotted' indentation. dotchar = '.' ## # The character that quotes lines beginning with dots and itself. quotechar = '\\' ## # Construct a new node. # @return # This variant returns a tuple in s-expression form. # @param tag a string # @param children a sequence of nodes # @param lineindex line index of tag, not used in s-expressions def node_sexpr(self, tag, children, lineindex): return (tag,) + tuple(children) ## # Construct a new node. # @return # This variant returns a Node object. # @param tag a string # @param children a sequence of nodes # @param lineindex line index of beginning tag, first line = 0 def node_node(self, tag, children, lineindex): return Node(tag, tuple(children), lineindex) node = node_node def parse_file(self, file, src=None): return self.parse_string(self.IO.read_file(file), src) ## # Parse a dotted tree text given as a sequence of lines. # @param pos # @param tag list with first line of tag, if any # @param lineindex line index of tag # @param it iterator yielding remaining lines # @return a triple (index, nextvar, node) where # index is the index of line 'nextvar', # nextvar is the first line of next node to parse, and # node is the resulting node of this parse. def parse_iter(self, pos, tag, lineindex, it, src=None): dotchar = self.dotchar quotechar = self.quotechar children = [] firstline = lineindex while 1: try: lineindex, nextvar = next(it) except StopIteration: nextvar = None break if not nextvar.startswith(dotchar): tag.append(nextvar) else: break for (i, t) in enumerate(tag): if (t.startswith(quotechar+dotchar) or t.startswith(quotechar+quotechar+dotchar)): tag[i] = t[len(quotechar):] if tag == ['']: tag = '\n' else: tag = '\n'.join(tag) while 1: if (nextvar is None or len(nextvar) <= pos or nextvar[pos] != dotchar or not nextvar.startswith(dotchar*(pos+1))): return lineindex, nextvar, self.node(tag, children, firstline) if len(nextvar) > pos+1 and nextvar[pos+1] == dotchar: if src is None: raise SyntaxError('Level must increase with 1 max') else: src.error('Level must increase with 1 max', lineindex) lineindex, nextvar, child = self.parse_iter(pos+1, [nextvar[pos+1:]], lineindex, it, src) children.append(child) def parse_lines(self, lines, src=None): it = enumerate(lines) lineindex, nextvar, node = self.parse_iter(0, [], 0, it, src) assert nextvar is None return node def parse_string(self, string, src=None): if string: lines = string.split('\n') else: lines = [] return self.parse_lines(lines, src) ## # Unparse a tree given on Node form def unparse_node(self, node): return self.unparse_sexpr(node.as_sexpr()) ## # Unparse a tree given on sexpr form # @return a string in dotted-tree form def unparse_sexpr(self, sexpr): li = [] def unparse(depth, sexpr): li.append(self.unparse_tag(depth, sexpr[0])) for x in sexpr[1:]: unparse(depth+1, x) unparse(0, sexpr) return '\n'.join(li) def unparse_tag(self, depth, tag): dotchar, quotechar = self.dotchar, self.quotechar tag = tag.split('\n') for (i, t) in enumerate(tag): if (t.startswith(dotchar) or t.startswith(quotechar + dotchar)): tag[i] = quotechar + t tag = '\n'.join(tag) tag = dotchar*depth+tag return tag def test_1(): # Test parsing to sexpr's and back # for a variety of cases from guppy import Root dt = Root().guppy.gsl.DottedTree dt.node = dt.node_sexpr parse = dt.parse_string unparse = dt.unparse_sexpr for x, y in [ ['', ('',)], ['a', ('a',)], ['.a', ('', ('a',))], ['a\n.b', ('a', ('b',))], ['a\nb\n.c', ('a\nb', ('c',))], ["""\n.a\n..a""", ('\n', ('a', ('a',)))], ["""hello\n.a\n.b\n..ba\nx\n..bb""", ('hello', ('a',), ('b', ('ba\nx',), ('bb',)))], # Quoting dots [r'\.', ('.',)], [r'.\.', ('', ('.',))], # Preserving quote ['\\', ('\\',)], ['.\n\\', ('', ('\n\\',))], # Quoting quote-dots [r'\\.', (r'\.',)], # Preserving whitespace starting a tag # Or should it be stripped? I think better not, it would complicate transparency. [r'. tag', ('', (' tag', ))], # Preserving initial whitespace [' ', (' ',)], # Preserving initial newline ['\n', ('\n',)], ['\na', ('\na',)], # A n intended usage example [''' initial text .aspect for guppy.hsp ..returns ...type A ...latex ~\\ \..~|begincolorbox|~raw::~LaTeX~\\ ~\\ ~~~{\textbackslash}{\textbackslash}begin{\{}center{\}}~\\ .aspect for guppy.gsl ..contains DottedTree ''', ('\ninitial\ntext', ('aspect for guppy.hsp', ('returns', ('type A',), ('latex\n~\\\n..~|begincolorbox|~raw::~LaTeX~\\\n~\\\n~~~{\textbackslash}{\textbackslash}begin{\\{}center{\\}}~\\',))), ('aspect for guppy.gsl', ('contains DottedTree\n',)))] ]: z = parse(x) if y is not None: assert z == y assert unparse(z).strip() == x.strip() # Unparsing x and then parsing should give back x transparently # for any tree x, involving any combination of dots, quotes and other characters. # List of special chars and one normal chars = [dt.quotechar, dt.dotchar, '\n', ' ', 'a'] import random ## # Generate a random node with random number of children. # Shuffles the chars list to make the tag string. # @param maxchild maximum number of children def randnode(maxchild): numchild = random.randint(0, maxchild) random.shuffle(chars) tag = ''.join(chars) children = [randnode(maxchild-1) for i in range(numchild)] return dt.node(tag, children, 0) for i in range(10): y = randnode(3) x = unparse(y) z = parse(x) assert z == y def test_2(): # Test parsing to Node # that the line lineindex are correct # They start from 0, since enumerate() generates them, # It seemed inconsistent to change them to start from 1. # Which will be made in error prints. from guppy import Root dt = Root().guppy.gsl.DottedTree parse = dt.parse_string unparse = dt.unparse_node node = parse("""\ line 0 .line 1 ..line 2 line 3 .line 4 """) exp = Node('line 0', ( Node('line 1', (Node('line 2\nline 3', (), 2),), 1), Node('line 4\n', (), 4)), 0) assert repr(node) == repr(exp) def test_main(): test_1() test_2()
Upload File
Create Folder