1.1 --- a/viewer.py Tue Oct 10 00:46:32 2006 +0200
1.2 +++ b/viewer.py Sat Oct 14 02:17:40 2006 +0200
1.3 @@ -81,10 +81,144 @@
1.4 self.stream.write("\nSimplified node was:\n\n")
1.5 exc.nodes[0].pprint(stream=self.stream)
1.6
1.7 +# HTML-related output production.
1.8 +
1.9 +html_header = """<?xml version="1.0" encoding="iso-8859-15"?>
1.10 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1.11 +<html xmlns="http://www.w3.org/1999/xhtml">
1.12 +<head>
1.13 + <title>Module</title>
1.14 + <style type="text/css">
1.15 + body {
1.16 + padding-top: 4em; padding-bottom: 4em;
1.17 + font-size: 14pt; font-family: monospace;
1.18 + background-color: black; color: white;
1.19 + }
1.20 +
1.21 + .class { margin-bottom: 1em; }
1.22 + .function { margin-bottom: 1em; }
1.23 + .body { padding-left: 2em; }
1.24 + .keyword { color: yellow; }
1.25 + .comment { color: blue; }
1.26 + .ref { color: cyan; }
1.27 + .ref a { color: cyan; text-decoration: none; }
1.28 +
1.29 + .name {
1.30 + position: relative;
1.31 + }
1.32 +
1.33 + .types {
1.34 + display: none; z-index: 2;
1.35 + position: absolute; top: 3em; left: 0.5em;
1.36 + padding: 0.5em; background-color: #0000FF;
1.37 + }
1.38 +
1.39 + .name:hover > .types
1.40 + {
1.41 + display: block;
1.42 + }
1.43 +
1.44 + </style>
1.45 +</head>
1.46 +<body>
1.47 +"""
1.48 +
1.49 +html_footer = """</body>
1.50 +</html>
1.51 +"""
1.52 +
1.53 +class Browser(ASTVisitor):
1.54 +
1.55 + """
1.56 + A browsing visitor for AST nodes.
1.57 + """
1.58 +
1.59 + def __init__(self, stream):
1.60 + ASTVisitor.__init__(self)
1.61 + self.visitor = self
1.62 + self.stream = stream
1.63 +
1.64 + def process(self, module):
1.65 + self.stream.write(html_header)
1.66 + self.dispatch(module)
1.67 + self.stream.write(html_footer)
1.68 +
1.69 + def visitModule(self, node):
1.70 + self.default(node)
1.71 +
1.72 + def visitPass(self, node):
1.73 + self._keyword("pass")
1.74 +
1.75 + def visitClass(self, node):
1.76 + structure = node._node.expr.types[0].type
1.77 + self.stream.write("<div class='class' id='%s'>\n" % self._url(structure.full_name))
1.78 + self.stream.write("<p>\n")
1.79 + self._keyword("class")
1.80 + self._name(structure)
1.81 + bases = structure.bases
1.82 + if bases:
1.83 + self.stream.write("(\n")
1.84 + first = 1
1.85 + for base in bases:
1.86 + if not first:
1.87 + self.stream.write(",\n")
1.88 + self._name_and_types(base)
1.89 + first = 0
1.90 + self.stream.write(")")
1.91 + self.stream.write(":\n")
1.92 + self._comment(self._text(structure.full_name))
1.93 + self.stream.write("</p>\n")
1.94 +
1.95 + self.stream.write("<div class='body'>\n")
1.96 + self.default(node)
1.97 + self.stream.write("</div>\n")
1.98 + self.stream.write("</div>\n")
1.99 +
1.100 + # Output preparation methods.
1.101 +
1.102 + def _text(self, text):
1.103 + return text.replace("&", "&").replace("<", "<").replace(">", ">")
1.104 +
1.105 + def _attr(self, attr):
1.106 + return self._text(attr).replace("'", "'").replace('"', """)
1.107 +
1.108 + def _url(self, url):
1.109 + return self._attr(url).replace("#", "%23").replace("-", "%2d")
1.110 +
1.111 + def _comment(self, comment):
1.112 + self.stream.write("<span class='comment'># %s</span>\n" % comment)
1.113 +
1.114 + def _keyword(self, kw):
1.115 + self.stream.write("<span class='keyword'>%s</span> " % kw)
1.116 +
1.117 + def _name(self, node):
1.118 + self.stream.write("<span class='name'>%s</span> " % node.name)
1.119 +
1.120 + def _name_and_types(self, node):
1.121 + self.stream.write("<span class='name'>%s\n<div class='types'>\n" % node.name)
1.122 + for type in node.types:
1.123 + fn = type.type.full_name
1.124 + self.stream.write("<div class='ref'>\n")
1.125 + self.stream.write(self._text(fn))
1.126 + self.stream.write("</div>\n")
1.127 + self.stream.write("</div>\n</span>\n")
1.128 +
1.129 # Convenience functions.
1.130
1.131 def view(module, stream=None):
1.132 viewer = Viewer(stream or sys.stdout)
1.133 viewer.process(module.original)
1.134
1.135 +def browse(module, stream=None):
1.136 + browser = Browser(stream or sys.stdout)
1.137 + browser.process(module.original)
1.138 +
1.139 +def makedoc(module, filename):
1.140 + stream = open(filename, "wb")
1.141 + try:
1.142 + browser = Browser(stream)
1.143 + browser.process(module.original)
1.144 + finally:
1.145 + stream.close()
1.146 +
1.147 # vim: tabstop=4 expandtab shiftwidth=4