0001 # Copyright 2003, Grant T. Olson, see License.txt for details 0002 from __future__ import generators 0003 import ConfigParser, sys, os 0004 0005 from releases import version, minorMinorVersion, minorMinorDate 0006 0007 keywords = ["and", "del", "for", "is", "raise", "assert", "elif", "from", 0008 "lambda", "return", "break", "else", "global", "not", "try", 0009 "class", "except", "if", "or", "while", "continue", "exec", 0010 "import", "pass", "yield", "def", "finally", "in", "print"] 0011 0012 operators = ['+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', '|', '^', '~', 0013 '<', '>', '<=', '>=', '==', '!=', '<>', '(', ')', '[', ']', '{', '}', 0014 ',', ':', '.', '`', '=', ';', '+=', '-=', '*=', '/=', '//=', '%=', 0015 '&=', '|=', '^=', '>>=', '<<=', '**=' ] 0016 0017 import os 0018 0019 if os.name == "nt": 0020 def pathToUrl(path): 0021 path = path.replace("\\", "/") 0022 if not os.path.isdir(path): 0023 path += ".html" 0024 return virtualLocation + "/" + path[0] + path[2:] 0025 0026 def urlToPath(url): 0027 if not url.startswith(virtualLocation): 0028 raise RuntimeError("Invalid url translation %s" % url) 0029 url = url[len(virtualLocation):] 0030 url = url.replace("/", "\\") 0031 if url.endswith(".html"): 0032 url = url[:-5] 0033 return url[1] + ":" + url[2:] 0034 0035 else: 0036 def pathToUrl(path): 0037 if not os.path.isdir(path): 0038 path += ".html" 0039 return "%s%s" % (virtualLocation, path) 0040 def urlToPath(url): 0041 if not url.startswith(virtualLocation): 0042 raise RuntimeError("Invalid url translation %s" % url) 0043 if url.endswith(".html"): 0044 url = url[:-5] 0045 return url[len(virtualLocation):] 0046 import sys 0047 0048 def sourceDirList(paths=None): 0049 if not paths: paths=pythonpath 0050 import os, stat 0051 def sourceFiles(currentPath, files): 0052 return [os.path.join(currentPath, x) for x in files if x[-3:] == ".py"] 0053 def packages(currentPath, files): 0054 for aFile in files: 0055 fileName = os.path.join(currentPath, aFile) 0056 mode = os.stat(fileName)[stat.ST_MODE] 0057 if stat.S_ISDIR(mode): 0058 if os.path.exists( os.path.join(fileName, "__init__.py")): 0059 yield fileName 0060 while paths: 0061 path = paths[0] 0062 paths = paths[1:] 0063 0064 yield path 0065 if os.path.exists(path) and os.path.isdir(path): 0066 filesInPath = os.listdir(path) 0067 else: 0068 print >> sys.stderr, "\nDirectory '%s' does not exist. Skipping" % path 0069 filesInPath = [] 0070 paths += packages(path, filesInPath) 0071 0072 0073 def sourceFileList(paths=None): 0074 if not paths: paths=pythonpath 0075 import os, stat 0076 def sourceFiles(currentPath, files): 0077 return [os.path.join(currentPath, x) for x in files if x[-3:] == ".py"] 0078 def packages(currentPath, files): 0079 for aFile in files: 0080 fileName = os.path.join(currentPath, aFile) 0081 mode = os.stat(fileName)[stat.ST_MODE] 0082 if stat.S_ISDIR(mode): 0083 if os.path.exists( os.path.join(fileName, "__init__.py")): 0084 yield fileName 0085 while paths: 0086 path = paths[0] 0087 paths = paths[1:] 0088 0089 if os.path.exists(path) and os.path.isdir(path): 0090 filesInPath = os.listdir(path) 0091 else: 0092 print >> sys.stderr, "\nDirectory '%s' does not exist, skipping" % path 0093 filesInPath = [] 0094 0095 for fil in sourceFiles(path, filesInPath): 0096 yield fil 0097 for package in packages(path, filesInPath): 0098 paths = [package] + paths # pop to front so everything is in order 0099 0100 def pathToFileName(path): 0101 """ For our caching system """ 0102 path = path.replace(":", "") 0103 return path 0104 0105 verbose = 0 0106 0107 # 0108 # Test for universal newlines 0109 # 0110 0111 if hasattr(file, 'newlines'): 0112 def openPythonFile(filename): 0113 "We have Universal newlines" 0114 return file(filename, "rU") 0115 else: 0116 def openPythonFile(filename): 0117 "We don't have Universal newlines" 0118 return file(filename, "r") 0119 # 0120 # init from settings.cfg 0121 # 0122 0123 if __name__ != "__main__": 0124 cfgFile = os.path.split(__file__) 0125 cfgFile = os.path.join("settings.cfg") 0126 else: 0127 cfgFile = "settings.cfg" 0128 0129 cfg = ConfigParser.ConfigParser() 0130 try: 0131 cfg.read([cfgFile]) 0132 cacheLocation = cfg.get("web","baseDirectory") 0133 virtualLocation = cfg.get("web", "baseUrl") 0134 indexPage = cfg.get("web", "indexPage") 0135 0136 if cfg.getint("pythonpath", "usePythonpath"): 0137 pythonpath = [x for x in sys.path[1:] if os.path.exists(x) and os.path.isdir(x)] 0138 # shouldn't check it's own path, or include nonexistanf dirs such as python23.zip 0139 else: 0140 pythonpath = [] 0141 except ConfigParser.ParsingError: 0142 raise 0143 except ConfigParser.NoSectionError: 0144 print "Couldn't find valid config file. Did you read the readme?" 0145 sys.exit() 0146 except: 0147 print "UNKNOWN ERROR PARSING CONFIG FILE" 0148 raise 0149 0150 0151 includeDirs = [x for x in cfg.get("pythonpath", "include").split(";") if x and os.path.exists(x) and os.path.isdir(x)] 0152 excludeDirs = [x for x in cfg.get("pythonpath", "exclude").split(";") if x and os.path.exists(x) and os.path.isdir(x)] 0153 0154 for dir in includeDirs: 0155 if dir in pythonpath: 0156 print "Can't add %s to pythonpath, it's already there" % dir 0157 else: 0158 pythonpath.append(dir) 0159 0160 0161 for dir in excludeDirs: 0162 if dir in pythonpath: 0163 pythonpath.remove(dir) 0164 else: 0165 print "Can't remove %s from pythonpath, it doesn't exist" % dir 0166 0167 #0.8.1 Options 0168 0169 try: 0170 skipInvalidFiles = cfg.getint("options", "skipInvalidFiles") 0171 except: 0172 print """Invalid config file. Possibly a pre 0.8.1 config file. 0173 0174 If so, add: 0175 [options] 0176 skipInvalidFiles=0 0177 0178 to patch. 0179 0180 This option can be set to 1 if you want to continue processing when you 0181 hit a file with invalid python syntax. 0182 """ 0183 sys.exit() 0184 0185 #0.9 Options 0186 try: 0187 useLibraryReference = cfg.getint("libraryReference", "useLibraryReference") 0188 libDirectory = cfg.get("libraryReference", "libDirectory") 0189 libUrl = cfg.get("libraryReference", "libUrl") 0190 except: 0191 print """Invalid config file. Possibly a pre 0.9 config file. 0192 0193 If so, add: 0194 [libraryReference] 0195 useLibraryReference = 1 0196 libDirectory = c:\python22\doc\lib\ 0197 libUrl = c:\python22\doc\lib\ 0198 0199 to patch. 0200 0201 libDirectory should point to the physical path of your python documentation's lib directory. 0202 libUrl should point to the href. 0203 """ 0204 sys.exit() 0205 0206 #0.9.2 Options 0207 # Style colors 0208 # will default to my preferred style if no keys exits 0209 0210 def setOption(section, option, default): 0211 if cfg.has_option(section, option): 0212 return cfg.get(section, option,raw=True) 0213 else: 0214 return default 0215 0216 class Styles: 0217 """ 0218 Make stylesheets based on config file settings.cfg 0219 Really just put it in a class to clean up the namespace 0220 """ 0221 def __init__(self): 0222 self.body = setOption("style", "body", "font-family:sans-serif;background-color:white;color:black;") 0223 self.keyword = setOption("style", "keyword", "color:navy;font-weight:bold;") 0224 self.comment = setOption("style", "comment", "color:green;") 0225 self.operator = setOption("style", "operator", "font-weight:bold;") 0226 self.funcdef = setOption("style", "funcdef", "color:red;font-weight:bold;") 0227 self.classdef = setOption("style", "classdef", "color:red;font-weight:bold;") 0228 self.string_ = setOption("style", "string", "color:blue;") 0229 self.lineNumber = setOption("style", "lineNumber", "color:black;font-weight:bold;") 0230 self.funcname = setOption("style", "funcname", "color:blue;font-weight:bold;") 0231 self.pythonName = setOption("style", "pythonName", "color:green;") 0232 self.link = setOption("style", "link", "color:blue;") 0233 self.visited = setOption("style", "visisted", "color:blue;") 0234 self.hover = setOption("style", "hover", "color:red;") 0235 self.stylesheet = """<style> 0236 body{%s} 0237 .keyword{%s} 0238 .comment{%s} 0239 .operator{%s} 0240 .funcdef{%s} 0241 .classdef{%s} 0242 .string{%s} 0243 .lineNumber{%s} 0244 .funcname{%s} 0245 .pythonName(%s) 0246 0247 A:link{%s} 0248 A:visited{%s} 0249 A:hover{%s} 0250 </style> 0251 """ % (self.body, self.keyword, self.comment, self.operator, self.funcdef, self.classdef, 0252 self.string_, self.lineNumber,self.funcname, self.pythonName, self.link, self.visited, 0253 self.hover) 0254 #new in 0.9.4 0255 # custom header/footer 0256 headFootVars = {'home':virtualLocation, 0257 'plugLink':'http://pyxr.sourceforge.net/', 0258 'version':version} 0259 self.header = setOption("style", "header", "<h1><a href='%(home)s'>PyXR</a></h1>") 0260 self.header = self.header % headFootVars 0261 self.footer = setOption("style", "footer", 0262 "<p><i>Generated by <a href='%(plugLink)s'>PyXR %(version)s</a></i></p>") 0263 self.footer = self.footer % headFootVars 0264 styles = Styles() 0265 0266 class InvalidSourceError(RuntimeError): 0267 pass 0268 0269
Generated by PyXR 0.9.4