def template_engine(self, entry, startnode):
        """The format template interpetation engine.  See the comment at the
        beginning of this module for the how we interpret format specifications such as
        %c, %C, and so on.
        """

        # self.println("-----")
        # print("XXX", startnode)

        fmt = entry[0]
        arg = 1
        i = 0

        m = escape.search(fmt)
        while m:
            i = m.end()
            self.write(m.group('prefix'))

            typ = m.group('kind') or '{'
            node = startnode
            try:
                if m.group('child'):
                    node = node[int(m.group('child'))]
            except:
                print(node.__dict__)
                raise

            if   typ == '%':	self.write('%')
            elif typ == '+':	self.indentMore()
            elif typ == '-':	self.indentLess()
            elif typ == '|':	self.write(self.indent)
            elif typ == 'c':
                index = entry[arg]
                if isinstance(index, tuple):
                    assert node[index[0]] == index[1], (
                        "at %s[%d], %s vs %s" % (
                            node.kind, arg, node[index[0]].kind, index[1])
                        )
                    index = index[0]
                if isinstance(index, int):
                    self.preorder(node[index])
                arg += 1
            elif typ == 'p':
                p = self.prec
                length = len(entry)
                if length == 3:
                    (index, self.prec, name) = entry[arg]
                    assert node[index] == name, (
                        "at %s[%d], %s vs %s" % (
                            node.kind, arg, node[index[0]].kind, index[1])
                        )
                elif length == 2:
                    (index, self.prec) = entry[arg]
                else:
                    raise RuntimeError("Invalid %%p tuple length %d; length should be 1 or 2"
                                       % length)

                self.preorder(node[index])
                self.prec = p
                arg += 1
            elif typ == 'C':
                low, high, sep = entry[arg]
                remaining = len(node[low:high])
                for subnode in node[low:high]:
                    self.preorder(subnode)
                    remaining -= 1
                    if remaining > 0:
                        self.write(sep)
                arg += 1
            elif typ == 'D':
                low, high, sep = entry[arg]
                remaining = len(node[low:high])
                for subnode in node[low:high]:
                    remaining -= 1
                    if len(subnode) > 0:
                        self.preorder(subnode)
                        if remaining > 0:
                            self.write(sep)
                            pass
                        pass
                    pass
                arg += 1
            elif typ == 'x':
                # This code is only used in fragments
                assert isinstance(entry[arg], tuple)
                arg += 1
            elif typ == 'P':
                p = self.prec
                low, high, sep, self.prec = entry[arg]
                remaining = len(node[low:high])
                # remaining = len(node[low:high])
                for subnode in node[low:high]:
                    self.preorder(subnode)
                    remaining -= 1
                    if remaining > 0:
                        self.write(sep)
                self.prec = p
                arg += 1
            elif typ == '{':
                d = node.__dict__
                expr = m.group('expr')
                try:
                    self.write(eval(expr, d, d))
                except:
                    print(node)
                    raise
            m = escape.search(fmt, i)
        self.write(fmt[i:])
def template_engine ( self , entry , startnode ) : fmt = entry [ 0 ] arg = 1 i = 0 m = escape . search ( fmt ) while m : i = m . end ( ) self . write ( m . group ( 'prefix' ) ) typ = m . group ( 'kind' ) or '{' node = startnode try : if m . group ( 'child' ) : node = node [ int ( m . group ( 'child' ) ) ] except : print ( node . __dict__ ) raise if typ == '%' : self . write ( '%' ) elif typ == '+' : self . indentMore ( ) elif typ == '-' : self . indentLess ( ) elif typ == '|' : self . write ( self . indent ) elif typ == 'c' : index = entry [ arg ] if isinstance ( index , tuple ) : assert node [ index [ 0 ] ] == index [ 1 ] , ( "at %s[%d], %s vs %s" % ( node . kind , arg , node [ index [ 0 ] ] . kind , index [ 1 ] ) ) index = index [ 0 ] if isinstance ( index , int ) : self . preorder ( node [ index ] ) arg += 1 elif typ == 'p' : p = self . prec length = len ( entry ) if length == 3 : ( index , self . prec , name ) = entry [ arg ] assert node [ index ] == name , ( "at %s[%d], %s vs %s" % ( node . kind , arg , node [ index [ 0 ] ] . kind , index [ 1 ] ) ) elif length == 2 : ( index , self . prec ) = entry [ arg ] else : raise RuntimeError ( "Invalid %%p tuple length %d; length should be 1 or 2" % length ) self . preorder ( node [ index ] ) self . prec = p arg += 1 elif typ == 'C' : low , high , sep = entry [ arg ] remaining = len ( node [ low : high ] ) for subnode in node [ low : high ] : self . preorder ( subnode ) remaining -= 1 if remaining > 0 : self . write ( sep ) arg += 1 elif typ == 'D' : low , high , sep = entry [ arg ] remaining = len ( node [ low : high ] ) for subnode in node [ low : high ] : remaining -= 1 if len ( subnode ) > 0 : self . preorder ( subnode ) if remaining > 0 : self . write ( sep ) pass pass pass arg += 1 elif typ == 'x' : assert isinstance ( entry [ arg ] , tuple ) arg += 1 elif typ == 'P' : p = self . prec low , high , sep , self . prec = entry [ arg ] remaining = len ( node [ low : high ] ) for subnode in node [ low : high ] : self . preorder ( subnode ) remaining -= 1 if remaining > 0 : self . write ( sep ) self . prec = p arg += 1 elif typ == '{' : d = node . __dict__ expr = m . group ( 'expr' ) try : self . write ( eval ( expr , d , d ) ) except : print ( node ) raise m = escape . search ( fmt , i ) self . write ( fmt [ i : ] )
The format template interpetation engine.  See the comment at the
        beginning of this module for the how we interpret format specifications such as
        %c, %C, and so on.