PyXR

C:\Python24\Lib\site-packages\pyxr \ astToHtml.py



0001 # Copyright 2003, Grant T. Olson, see License.txt for details
0002 
0003 import sys, os
0004 import token
0005 import tokenize
0006 import symbol
0007 import string
0008 
0009 import nsNode
0010 from astCrawler import astCrawler
0011 from lexicalTree import lexicalTree, getLibraryReference, libTree
0012 from misc import keywords, operators, pathToUrl, useLibraryReference, openPythonFile, InvalidSourceError
0013     
0014 class astToHtml(astCrawler):
0015     """
0016     Generates pprinted HTML Output from the ast
0017 
0018     the asts lose the info we need to print whitespace and comments properly.
0019     So we also setup a token generator to grab a stream of tokens with the info
0020     (and we can't just use the tokens to begin with because that won't determine
0021     structure of the doc easily)
0022     
0023     It's important to consume a token each time you discard a TOKEN node so that
0024     they stay in sync.  This essentially means we need to call getNextToken() everytime
0025     we use a token durring processing, even if we ignore the actual token text in our
0026     output
0027     """
0028    
0029     def __init__(self, filename="", outputStream=sys.stdout.write):
0030         self.filename = filename
0031         self.outputStream = outputStream
0032         if useLibraryReference:
0033             self.lexicalScope = lexicalTree("", "", mapBuiltins=1)
0034         else:
0035             self.lexicalScope = lexicalTree("", "")
0036         self.oldToken  = [[],[],[-1,-1],[-1,-1],""]
0037         self.currentToken = [[],[],[-1,-1],[-1,-1],""]
0038         infile = openPythonFile(filename)
0039         astCrawler.__init__(self, infile.read() + "\n\n")
0040         infile.close()
0041         infile = openPythonFile(filename)
0042         self.tokenGen = tokenize.generate_tokens(infile.readline)
0043 
0044         currentLocation = nsNode.pathToNode(filename)
0045         if currentLocation and currentLocation.parent: #search locally first
0046             currentLocation = currentLocation.parent
0047             self.searchPath = []
0048             self.searchPath.extend(currentLocation.getModules())
0049             self.searchPath.extend(currentLocation.getPackages())
0050             self.searchPath.extend(currentLocation.getDirectories())
0051             self.searchPath.append(nsNode.nsNodeTree)
0052         else:
0053             self.searchPath = None
0054 
0055         if useLibraryReference:
0056             libName = os.path.split(filename)[1]
0057             libName = libName[:-3]
0058             self.libReference = getLibraryReference(libName)
0059         else:
0060             self.libReference = None
0061         
0062     def getTokenText(self, formatString="%s"):
0063         """ Makes sure we have proper whitespace"""
0064         retVal = ""
0065         if self.oldToken[3] != self.currentToken[2]: # some sort of whitespace
0066             if self.oldToken[3][0] != self.currentToken[2][0]: #new line
0067                 retVal += self.oldToken[4][self.oldToken[3][1]:] + self.currentToken[4][:self.currentToken[2][1]]
0068             else: # normal whitespace
0069                 retVal += self.currentToken[4][self.oldToken[3][1]:self.currentToken[2][1]]
0070         retVal += formatString % self.getSafeText(self.currentToken[1])
0071         self.oldToken = self.currentToken
0072         retVal = retVal.expandtabs() #python assumes tabs are 8 spaces
0073         return retVal
0074     
0075     def getSafeText(self, text):
0076         htmlFixes = [ ("&", "&amp;"), ("<", "&lt;"), (">", "&gt;"), ]
0077         for fix in htmlFixes:
0078             text = text.replace(*fix)
0079         return text
0080         
0081     def printText(self, text):
0082         """ sends general text to the output stream """
0083         self.outputStream(text)
0084         
0085     def printToken(self, formatString="%s"):
0086         """
0087         Prints the current tokens text
0088         """
0089         text = self.getTokenText(formatString)
0090         self.printText(text)
0091 
0092     def printComment(self):
0093         self.printToken("<span class='comment'>%s</span>")
0094         
0095     def getNextToken(self, validationText):
0096         self.currentToken = self.tokenGen.next()
0097         while self.currentToken[0] in (token.N_TOKENS, tokenize.NL):
0098             if self.currentToken[0] == token.N_TOKENS:
0099                 self.printComment()
0100             if self.currentToken[0] == tokenize.NL:
0101                 self.printToken()
0102             self.currentToken = self.tokenGen.next()
0103         #make sure we're synched with the tree.  Note the real compile doesn't give text for NL's, INDENTS
0104         # so we have to account for that
0105         if self.currentToken[1] != validationText and \
0106            (validationText == '' and self.currentToken[0] not in (token.NEWLINE, token.INDENT, token.DEDENT)):
0107             raise InvalidSourceError("[%s] tokenize doesn't match the AST tree ACTUAL: %s TOKENGEN:%s" % (self.filename, validationText, self.currentToken))            
0108     ###
0109     ### HANDLERS
0110     ###
0111     def registerHandlers(self):
0112         self.handlers[token.ENDMARKER] = self.endHandler
0113         self.handlers[token.STRING] = self.stringHandler
0114         self.handlers[symbol.funcdef]= self.functionHandler
0115         self.handlers[symbol.classdef] = self.classHandler
0116         self.handlers[token.NAME] = self.nameHandler
0117         #self.handlers[symbol.import_stmt] = self.importHandler
0118         self.handlers[symbol.expr_stmt] = self.expressionHandler
0119         self.handlers[token.OP] = self.opHandler
0120         self.handlers[symbol.power] = self.powerHandler
0121         if hasattr(symbol, "encoding_decl"): #python 2.3
0122             self.handlers[getattr(symbol, "encoding_decl")] = self.encodingDeclHandler
0123 
0124         if hasattr(symbol, "import_name"): #python 2.4 tree
0125             self.handlers[symbol.import_as_names] = self.importAsNamesHandler
0126             self.handlers[symbol.dotted_as_names] = self.dottedAsNamesHandler
0127             self.handlers[symbol.import_from] = self.importFromHandler
0128             self.handlers[symbol.import_name] = self.importNameHandler
0129         else: #python < 2.4 tree
0130             self.handlers[symbol.import_stmt] = self.importHandler
0131             
0132         if hasattr(symbol,"decorator"): # python 2.4 tree
0133             self.handlers[symbol.decorator] = self.decoratorHandler
0134         
0135     def linkToLibReference(self, name):
0136         """
0137         Links to library reference if possible.
0138         As a general rule, any reference to function/class/method xxx will
0139         link to source code if possible.  If code doesn't exist but a library
0140         reference does, it will link directly to that.
0141         If code does exist and there is a library reference, the declaration
0142         of the function/class/method (the def or class statement) will link
0143         to the reference manual
0144         """
0145         linkText = ""
0146         if self.libReference:
0147             currentScope = self.libReference
0148             for item in self.lexicalScope.getScopeList(self.libReference):
0149                 currentScope = currentScope.findMember(item)
0150                 if not currentScope:
0151                     break
0152             if currentScope:
0153                 linkText = "<span class='funcname'><a name='%s'><a href='%s'>%%s</a></a></span>"
0154                 linkText = linkText % (self.lexicalScope.getName(), currentScope.ref)
0155 
0156         if not linkText:        
0157             linkText = "<span class='funcname'><a name='%s'>%%s</a></span>"% self.lexicalScope.getName()
0158         #print self.lexicalScope.getScopeList()
0159         self.printToken(linkText)
0160             
0161     def defaultHandleToken(self, item):  
0162         try:
0163             self.getNextToken(item)
0164             self.printToken()
0165         except StopIteration:
0166             if item:
0167                 print "\nUnmatched token from tree '%s' %s" % (item, self.filename)
0168     
0169     def endHandler(self, params):
0170         """tokenize doesn't spit this out, so we just ignore EOF"""
0171         pass
0172 
0173 
0174     def opHandler(self, params):
0175         if len(params) != 1:
0176             raise InvalidSourceError("[%s] Invalide Operator %s" % (self.filename, params))
0177         self.printToken("<span class='operator'>%s</span>")
0178         
0179     def nameHandler(self, params):
0180         if len(params) != 1:
0181             raise InvalidSourceError("[%s] invalid name %s" % (self.filename, params))
0182         name = params[0]
0183         self.getNextToken(name)
0184         if name in keywords:
0185             self.printToken("<span class='keyword'>%s</span>")
0186         else:
0187             self.printToken("<span class='pythonName'>%s</span>")
0188         
0189     def functionHandler(self, params):
0190         if hasattr(symbol, "decorators"): #python2.4
0191             if params[0][0] == symbol.decorators:
0192                 offset = 1
0193                 self.process(params[0])
0194             else:
0195                 offset = 0
0196         else:
0197             offset = 0
0198             
0199         defConstant = params[0 + offset]
0200         funcName = params[1 + offset][1]
0201         rest = params[2 + offset:]
0202 
0203         self.getNextToken(defConstant)
0204         self.printToken("<span class='funcdef'>%s</span>")
0205         self.getNextToken(funcName)
0206         self.lexicalScope = self.lexicalScope.addMember(funcName)
0207         self.linkToLibReference(funcName)
0208         map(self.process,rest)
0209         self.lexicalScope = self.lexicalScope.parent
0210 
0211     def classHandler(self, params):
0212         classConst = params[0]
0213         className = params[1][1]
0214         rest = params[2:]
0215 
0216         self.getNextToken(classConst)
0217         self.printToken("<span class='classdef'>%s</span>")
0218         self.getNextToken(className)
0219         self.lexicalScope = self.lexicalScope.addMember(className)
0220         self.linkToLibReference(className)
0221         if rest[0][1] == '(': #subclasses, if we want to try to resolve methods.
0222             openParen = rest[0]
0223             baseClasses = rest[1]
0224             closeParen = rest[2]
0225             rest = rest[3:]
0226             self.getNextToken(openParen)
0227             self.printToken()
0228             map(self.process, baseClasses[1:])
0229             self.getNextToken(closeParen)
0230             self.printToken()
0231         map(self.process, rest)
0232         self.lexicalScope = self.lexicalScope.parent
0233 
0234     def nsNodeToLexical(self, lexicalNode, nsNode, lexicalName=""):
0235         if not lexicalName:
0236             lexicalName = nsNode.name
0237         tmpNode = lexicalNode.addMember(lexicalName)
0238         tmpPath = nsNode.getPath()
0239         if tmpPath:
0240             tmpNode.ref = pathToUrl(tmpPath)
0241         for child in nsNode.children:
0242             self.nsNodeToLexical(tmpNode, child)
0243 
0244     def graftLexicalNode(self, lexTree, lexicalNode, optName=""):
0245         if optName:
0246             lexTree.members[optName] = lexicalNode
0247         else:
0248             lexTree.members[lexicalNode.name] = lexicalNode
0249 
0250     #
0251     # THe 'any'... functions deal with the fact that resolving references
0252     # to the "Library Reference" is completely different than resolving
0253     # references to nsNodes from the .py source.
0254     #
0255     # s'pose I should make a better interface for these classes
0256     def anyNodeToLexical(self, lexTree, node, lexicalName=""):
0257         if isinstance(node, lexicalTree):
0258             self.graftLexicalNode(lexTree, node, lexicalName)
0259         elif isinstance(node, nsNode.nsNode):
0260             self.nsNodeToLexical(lexTree, node, lexicalName)
0261         else:
0262             raise InvalidSourceError("Invalid node type.  Can't merge with current lexical scope")
0263         
0264     def anyChildToLexical(self, lexTree, node, childName, lexicalName=""):
0265         if isinstance(node, lexicalTree):
0266             tmpNode = node.findMember(childName)
0267             if tmpNode:
0268                 self.graftLexicalNode(lexTree, tmpNode, lexicalName)
0269         elif isinstance(node, nsNode.nsNode):
0270             tmpNode = node.getAnyChild(childName)
0271             if tmpNode:
0272                 if not lexicalName: lexicalName = childName
0273                 url = "%s#%s:" % (pathToUrl(node.getPath()), childName)
0274                 self.lexicalScope.addMember(lexicalName, url)
0275                 #self.nsNodeToLexical(lexTree, tmpNode, lexicalName)
0276         else:
0277             raise InvalidSourceError("Invalid node type. Can't merge with current lexical scope")
0278 
0279     def anyChildrenToLexical(self, lexTree, node):
0280         if isinstance(node, lexicalTree):
0281             for child in node.members.keys():
0282                 self.graftLexicalNode(lexTree, node.findMember(child))
0283         elif isinstance(node, nsNode.nsNode):
0284             for child in node.children:
0285                 self.nsNodeToLexical(lexTree, child)
0286         else:
0287             raise InvalidSourceError("Invalid node type. Can't merge with current lexical scope")
0288 
0289     def anyPrintToken(self, node, name):
0290         """
0291         prints a token with appropriate link to the listed node if possible
0292         """
0293         formatString = "%s"
0294         if not node:
0295             pass
0296         elif isinstance(node, lexicalTree):
0297             childNode = node.findMember(name)
0298             if childNode:
0299                 formatString = "<a href='%s'>%%s</a>" % childNode.ref
0300         elif isinstance(node, nsNode.nsNode):
0301             childNode = node.getAnyChild(name)
0302             if childNode:
0303                 url = "%s#%s:" % (pathToUrl(node.getPath()), name)
0304                 formatString = "<a href='%s'>%%s</a>" %(url)
0305         else:
0306             raise InvalidSourceError("Invalid node type. Can't merger with current Lexical scope")
0307         self.printToken(formatString)
0308         
0309     def dottedName(self, dottedName):
0310         """
0311         DEPRECIATED- use anyDottedName instead.  This only accounts for imports of
0312         modules with python source (no .pyds)
0313         """
0314         dottedNameString = ""
0315         for x in dottedName[1:]:
0316             self.getNextToken(x[1])
0317             if x[1] == ".":
0318                 self.printToken()
0319             else:
0320                 if dottedNameString:dottedNameString += "/"
0321                 dottedNameString = dottedNameString + x[1] 
0322                 tmpNode = nsNode.getModuleNode(dottedNameString, self.searchPath)
0323                 if tmpNode:
0324                     href = "<a href='%s'>%%s</a>" % pathToUrl(tmpNode.getPath())
0325                 else:
0326                     href = "%s"
0327                 self.printToken(href)
0328         return tmpNode
0329     
0330     def anyDottedName(self, dottedName):
0331         """
0332         Resolves an 'import' dotted name to something we can integrate into our current
0333         lexical tree.  This 'something' could be either an nsNode or a lexicalTree node,
0334         so it should always be grafted in via the anyNodeToLexicalNode method
0335         """
0336         firstPass = 1
0337         tmpNode = None
0338         for x in dottedName[1:]:
0339             self.getNextToken(x[1])
0340             if x[1] == ".":
0341                 self.printToken()
0342             else:
0343                 modName = x[1]
0344                 # locate node if we can
0345                 if firstPass:
0346                     # try to locate lexically
0347                     tmpNode = nsNode.getModuleNode(modName, self.searchPath)
0348                     if not tmpNode and useLibraryReference and libTree.findMember(modName):
0349                         tmpNode = libTree.findMember(modName)
0350                     firstPass = 0
0351                 else:
0352                     #try to locate based on current tmpNode value
0353                     if not tmpNode:
0354                         pass
0355                     elif isinstance(tmpNode, nsNode.nsNode):
0356                         tmpNode = tmpNode.getAnyChild(modName)
0357                     elif isinstance(tmpNode, lexicalTree):
0358                         if tmpNode.members.has_key(modName):
0359                             tmpNode = tmpNode.members[modName]
0360                         else:
0361                             tmpNode = None
0362                     else:
0363                         raise InvalidSourceError("Never should have gotten here")
0364 
0365                 # Determine how to print, if node exists there's a hyperlink          
0366                 if not tmpNode:
0367                     href = "%s"
0368                 elif isinstance(tmpNode, nsNode.nsNode):
0369                     href = "<a href='%s'>%%s</a>" % pathToUrl(tmpNode.getPath())
0370                 elif isinstance(tmpNode, lexicalTree):
0371                     href = "<a href='%s'>%%s</a>" % tmpNode.ref
0372                 else:
0373                     raise InvalidSourceError("Never should have gotten here")
0374                 self.printToken(href)
0375         return tmpNode
0376 
0377     def dottedAsNamesHandler(self, params):
0378         pass
0379     
0380     def importAsNamesHandler(self, params):
0381          pass
0382 
0383     def decoratorHandler(self, params):
0384         ampersand = params[0]
0385         decorator = params[1]
0386         rest = params[2:]
0387         
0388         self.getNextToken("@")
0389         self.printToken()
0390         
0391         tmpNode = self.anyDottedName(decorator)
0392         
0393         map(self.process,rest)
0394         
0395     def importFromHandler(self, params):
0396         """Handler for python 2.4+ ast tress.  Not used in 2.3 and lower"""
0397         importType = params[0][1]
0398         if importType != "from":
0399             raise InvalidSourceError("[%s] Invalid ImportFrom Syntax: %s" % (self.filename, params))
0400         
0401         fromConst = params[0][1]
0402         dottedName = params[1]
0403         importConst = params[2][1]
0404         rest = params [3:]
0405         
0406         self.getNextToken(importType)
0407         self.printToken("<span class='keyword'>%s</span>")
0408        
0409         tmpNode = self.anyDottedName(dottedName)
0410         self.getNextToken(importType)
0411         self.printToken("<span class='keyword'>%s</span>")
0412         
0413         for param in rest:
0414             if param[0] in (token.LPAR, token.RPAR):
0415                 self.getNextToken(param[1])
0416                 self.printToken()
0417             elif param[0] == token.STAR:
0418                 self.getNextToken(param[1])
0419                 self.printToken()
0420                 if tmpNode:
0421                     self.anyChildrenToLexical(self.lexicalScope, tmpNode)
0422             elif param[0] == symbol.import_as_names:
0423                 for namesParam in param[1:]:
0424                     if namesParam[0] == token.COMMA:
0425                         self.getNextToken(namesParam[1])
0426                         self.printToken()
0427                         continue
0428                     name = namesParam[1][1]
0429                     rest = namesParam[2:]
0430                     
0431                     self.getNextToken(name)
0432                     if tmpNode:
0433                         self.anyPrintToken(tmpNode, name)
0434                     else:
0435                         self.printToken()
0436                     if rest:
0437                         self.getNextToken("as")
0438                         self.printToken("<span class='keyword'>%s</span>")
0439                         asName = rest[1][1]
0440                         if tmpNode:
0441                             self.anyChildToLexical(self.lexicalScope, tmpNode, name, asName)
0442                         self.getNextToken(asName)
0443                         self.printToken()
0444                     else:
0445                         if tmpNode:
0446                             self.anyChildToLexical(self.lexicalScope, tmpNode, name)
0447             else:
0448                 raise InvalidSourceError("[%s] Invalid Syntax for import %s" % (self.filename,param))
0449         
0450     def importNameHandler(self, params):
0451         """Handler for python 2.4+ ast tress.  Not used in 2.3 and lower"""
0452         first = params[0]
0453         rest = params[1:]
0454         if first[1] == "import":
0455             self.getNextToken(first[1])
0456             self.printToken("<span class='keyword'>%s</span>")                   
0457 
0458             if rest[0][0] != symbol.dotted_as_names:
0459                 raise InvalidSourceError("[%s] Apparently invalid import: %s" % (self.filename, params))
0460             else:           
0461                 rest = rest[0][1:]
0462                 for param in rest:
0463                     if param[0] == symbol.dotted_as_name:
0464                         dottedName = param[1]
0465                         asAndName = param[2:]
0466                         tmpNode = self.anyDottedName(dottedName)
0467                         
0468                         if asAndName:
0469                             self.getNextToken('as')
0470                             self.printToken("<span class='keyword'>%s</span>")
0471                             asName = param[3][1]
0472                             self.getNextToken(asName)
0473                             self.printToken()
0474                             if tmpNode:
0475                                 self.anyNodeToLexical(self.lexicalScope, tmpNode,asName)
0476                         else:
0477                             if tmpNode:
0478                                 self.anyNodeToLexical(self.lexicalScope, tmpNode)
0479                                 
0480                     elif param[0] == token.COMMA:
0481                         self.getNextToken(param[1])
0482                         self.printToken()
0483                     else:
0484                         raise InvalidSourceError("[%s] Apparently invalid ImportName %s" % (self.filename, params))
0485         else:
0486             raise InvalidSourceError("[%s] invalid import_name statement" % (self.filename, params))
0487         
0488     def importHandler(self, params):
0489         """Legacy handler for pre 2.4 ast trees.  Not used in 2.4+"""
0490         importType = params[0][1]
0491         if importType == "import":
0492             self.getNextToken(importType)
0493             self.printToken("<span class='keyword'>%s</span>")                   
0494             dottedName = []
0495             
0496             for param in params[1:]:
0497                 #self.getNextToken(param[1])
0498                 if param[0] == symbol.dotted_as_name:
0499                     dottedName = param[1]
0500                     rest = param[2:]
0501                     tmpNode = self.anyDottedName(dottedName)
0502                     
0503                     if rest:
0504                         self.getNextToken('as')
0505                         self.printToken("<span class='keyword'>%s</span>")
0506                         asName = param[3][1]
0507                         self.getNextToken(asName)
0508                         self.printToken()
0509                         if tmpNode:
0510                             self.anyNodeToLexical(self.lexicalScope, tmpNode,asName)
0511                     else:
0512                         if tmpNode:
0513                             self.anyNodeToLexical(self.lexicalScope, tmpNode)
0514                 else:
0515                     self.process(param)
0516         elif importType == "from":
0517             fromConst = params[0][1]
0518             dottedName = params[1]
0519             importConst = params[2][1]
0520             rest = params [3:]
0521 
0522             self.getNextToken(importType)
0523             self.printToken("<span class='keyword'>%s</span>")
0524 
0525             tmpNode = self.anyDottedName(dottedName)
0526             self.getNextToken(importType)
0527             self.printToken("<span class='keyword'>%s</span>")
0528 
0529             for x in rest:
0530                 if x[1] == ",":
0531                     self.getNextToken(",")
0532                     self.printToken()
0533                 elif x[1] == "*":
0534                     self.getNextToken("*")
0535                     self.printToken()
0536                     if tmpNode:
0537                         self.anyChildrenToLexical(self.lexicalScope, tmpNode)
0538                 else:
0539                     if x[0] != symbol.import_as_name:
0540                         raise RuntimeError("Invalid Syntax for import %s" % self.filename)
0541                     name = x[1][1]
0542                     rest = x[2:]
0543                     self.getNextToken(name)
0544                     if tmpNode:
0545                         self.anyPrintToken(tmpNode, name)
0546                     else:
0547                         self.printToken()
0548                     if rest:
0549                         self.getNextToken("as")
0550                         self.printToken()
0551                         asName = rest[1][1]
0552                         if tmpNode:
0553                             self.anyChildToLexical(self.lexicalScope, tmpNode, name, asName)
0554                         self.getNextToken(asName)
0555                         self.printToken()
0556                     else:
0557                         if tmpNode:
0558                             self.anyChildToLexical(self.lexicalScope, tmpNode, name)
0559         else:
0560             raise Exception("Invalid Import Syntax: %s" % params)
0561         
0562     def expressionHandler(self,params):
0563         map(self.process, params)
0564         
0565     def stringHandler(self, params):
0566         if len(params) != 1:
0567             raise InvalidSourceError("[%s] string has invalid number of params %s" % (self.filename, params))
0568         self.getNextToken(params[0])
0569         self.printToken("<span class='string'>%s</span>")
0570 
0571     def dottedNameHandler(self, dottedName, rest):
0572 
0573         if dottedName[0] != 'self': #what's the real way to do this?        
0574             currentMember = self.lexicalScope.findMember(dottedName[0])
0575         elif self.lexicalScope.parent:
0576             currentMember = self.lexicalScope.parent
0577         else:
0578             currentMember = "n/a"
0579         if hasattr(currentMember, "getUrl"):
0580             url = currentMember.getUrl()
0581             formatString = "<a href='%s'>%%s</a>" % url
0582         else:
0583             formatString = "%s"
0584             currentMember = None
0585             
0586         self.getNextToken(dottedName[0])    
0587         self.printToken(formatString)
0588         for name in dottedName[1:]:
0589             self.getNextToken(".")
0590             self.printToken("%s")
0591 
0592             if currentMember and currentMember.members.has_key(name):
0593                 currentMember = currentMember.members[name]
0594                 url = currentMember.getUrl()
0595                 formatString = "<a href='%s'>%%s</a>" % url
0596             else:
0597                 currentMember = None
0598                 formatString = "%s"
0599             self.getNextToken(name)
0600             self.printToken(formatString)
0601         map(self.process, rest)
0602         
0603     def powerHandler(self, params):
0604         def getDottedName(params):
0605             if params[0][0] != symbol.atom or params[0][1][0] != token.NAME:
0606                 return None
0607             dottedName = [ params[0][1][1] ]
0608             i = 1
0609             for param in params[1:]:
0610                 if param[0] != symbol.trailer:
0611                     break
0612                 if param[1][0] != token.DOT:
0613                     break
0614                 if param[2][0] != token.NAME:
0615                     break
0616                 dottedName.append(param[2][1])
0617                 i += 1
0618             if i < len(params):
0619                 return dottedName, params[i:]
0620             else:
0621                 return dottedName, []
0622 
0623         name = getDottedName(params)
0624         if name:
0625             self.dottedNameHandler(*name)
0626         else:
0627             map(self.process, params)
0628 
0629     def encodingDeclHandler(self, params):
0630         self.process(params[0])
0631 
0632 if __name__ == "__main__":
0633     x = astToHtml("c:\\python24\\lib\\bsddb\\__init__.py", sys.stdout.write)
0634     x.process()
0635 
0636 

Generated by PyXR 0.9.4
SourceForge.net Logo