[py-svn] r37837 - in py/trunk/py/apigen: . testing

guido at codespeak.net guido at codespeak.net
Sat Feb 3 00:29:05 CET 2007


Author: guido
Date: Sat Feb  3 00:29:01 2007
New Revision: 37837

Modified:
   py/trunk/py/apigen/html.py
   py/trunk/py/apigen/htmlgen.py
   py/trunk/py/apigen/testing/test_apigen_example.py
   py/trunk/py/apigen/testing/test_htmlgen.py
Log:
A bit of cleanup of the HTML generation: some of the layout related stuff is
moved to the classes in the H namespace. This hopefully (when done, more can
definitely be done later) seperates the HTML generation better from the
presentation-related code.


Modified: py/trunk/py/apigen/html.py
==============================================================================
--- py/trunk/py/apigen/html.py	(original)
+++ py/trunk/py/apigen/html.py	Sat Feb  3 00:29:01 2007
@@ -31,10 +31,22 @@
         pass
 
     class FunctionDescription(Description):
-        pass
+        def __init__(self, localname, argdesc, docstring, valuedesc, csource,
+                     callstack):
+            fd = H.FunctionDef(localname, argdesc)
+            ds = H.Docstring(docstring or '*no docstring available*')
+            fi = H.FunctionInfo(valuedesc, csource, callstack)
+            super(H.FunctionDescription, self).__init__(fd, ds, fi)
 
     class FunctionDef(html.h2):
-        pass
+        def __init__(self, name, argdesc):
+            super(H.FunctionDef, self).__init__('def %s%s:' % (name, argdesc))
+
+    class FunctionInfo(html.div):
+        def __init__(self, valuedesc, csource, callstack):
+            super(H.FunctionInfo, self).__init__(
+                H.Hideable('funcinfo', 'funcinfo', valuedesc, csource,
+                           callstack))
 
     class ParameterDescription(html.div):
         pass
@@ -49,11 +61,26 @@
         pass
 
     class NavigationItem(html.div):
-        pass
+        def __init__(self, linker, linkid, name, indent, selected):
+            href = linker.get_lazyhref(linkid)
+            super(H.NavigationItem, self).__init__((indent * 2 * u'\xa0'),
+                                                 H.a(name, href=href))
+            if selected:
+                self.attr.class_ = 'selected'
 
     class BaseDescription(html.a):
         pass
 
+    class SourceSnippet(html.div):
+        def __init__(self, text, href, sourceels=None):
+            if sourceels is None:
+                sourceels = []
+            link = text
+            if href:
+                link = H.a(text, href=href)
+            super(H.SourceSnippet, self).__init__(
+                link, H.div(class_='code', *sourceels))
+    
     class SourceDef(html.div):
         pass
 
@@ -74,8 +101,24 @@
         pass
 
     class CallStackDescription(Description):
-        pass
+        def __init__(self, callstackdiv):
+            super(H.CallStackDescription, self).__init__(
+                H.Hideable('callsites', 'callsites', csdiv))
 
     class CallStackItem(html.div):
-        class_ = 'callstackitem'
+        def __init__(self, filename, lineno, traceback):
+            super(H.CallStackItem, self).__init__(
+                H.Hideable("stack trace %s - line %s" % (filename, lineno),
+                           'callstackitem', traceback))
+
+    class Hideable(html.div):
+        def __init__(self, name, class_, *content):
+            super(H.Hideable, self).__init__(
+                H.div(H.a('show/hide %s' % (name,),
+                          href='#',
+                          onclick=('showhideel(getnextsibling(this));'
+                                   'return false;')),
+                      H.div(style='display: none',
+                            class_=class_,
+                            *content)))
 

Modified: py/trunk/py/apigen/htmlgen.py
==============================================================================
--- py/trunk/py/apigen/htmlgen.py	(original)
+++ py/trunk/py/apigen/htmlgen.py	Sat Feb  3 00:29:01 2007
@@ -50,14 +50,7 @@
     """ get the html for the parameters of a function """
     import inspect
     # XXX copy and modify formatargspec to produce html
-    return H.em(inspect.formatargspec(*inspect.getargspec(func)))
-
-def build_navitem_html(linker, name, linkid, indent, selected):
-    href = linker.get_lazyhref(linkid)
-    navitem = H.NavigationItem((indent * 2 * u'\xa0'), H.a(name, href=href))
-    if selected:
-        navitem.attr.class_ = 'selected'
-    return navitem
+    return inspect.formatargspec(*inspect.getargspec(func))
 
 # some helper functionality
 def source_dirs_files(fspath):
@@ -139,15 +132,15 @@
                     text = self.projroot.basename
                 else:
                     text = path[i-1]
-                nav.append(build_navitem_html(self.linker, text, abspath,
-                                              indent, False))
+                nav.append(H.NavigationItem(self.linker, abspath, text,
+                                            indent, False))
                 indent += 1
         # build siblings or children and self
         if fspath.check(dir=True):
             # we're a dir, build ourselves and our children
             dirpath = fspath
-            nav.append(build_navitem_html(self.linker, dirpath.basename,
-                                          dirpath.strpath, indent, True))
+            nav.append(H.NavigationItem(self.linker, dirpath.strpath,
+                                        dirpath.basename, indent, True))
             indent += 1
         elif fspath.strpath == self.projroot.strpath:
             dirpath = fspath
@@ -156,13 +149,13 @@
             dirpath = fspath.dirpath()
         diritems, fileitems = source_dirs_files(dirpath)
         for dir in diritems:
-            nav.append(build_navitem_html(self.linker, dir.basename,
-                                          dir.strpath, indent, False))
+            nav.append(H.NavigationItem(self.linker, dir.strpath, dir.basename,
+                                        indent, False))
         for file in fileitems:
             selected = (fspath.check(file=True) and
                         file.basename == fspath.basename)
-            nav.append(build_navitem_html(self.linker, file.basename,
-                                          file.strpath, indent, selected))
+            nav.append(H.NavigationItem(self.linker, file.strpath,
+                                        file.basename, indent, selected))
         return nav
 
     re = py.std.re
@@ -232,6 +225,7 @@
                 except (KeyboardInterrupt, SystemError):
                     raise
                 except: # XXX strange stuff going wrong at times... need to fix
+                    raise
                     exc, e, tb = py.std.sys.exc_info()
                     print '%s - %s' % (exc, e)
                     print
@@ -288,41 +282,26 @@
         callable_source = self.dsa.get_function_source(dotted_name)
         # i assume they're both either available or unavailable(XXX ?)
         is_in_pkg = self.is_in_pkg(sourcefile)
+        href = None
+        text = 'could not get to source file'
+        colored = []
         if sourcefile and callable_source:
             enc = source_html.get_module_encoding(sourcefile)
             tokenizer = source_color.Tokenizer(source_color.PythonSchema)
             firstlineno = func.func_code.co_firstlineno
             org = callable_source.split('\n')
             colored = enumerate_and_color(org, firstlineno, enc)
+            text = 'source: %s' % (sourcefile,)
             if is_in_pkg:
-                slink = H.a('source: %s' % (sourcefile,),
-                            href=self.linker.get_lazyhref(sourcefile))
-            else:
-                slink = H.em('source: %s' % (sourcefile,))
-            csource = H.div(H.br(), slink, H.br(),
-                            H.SourceDef(H.div(class_='code', *colored)))
-        else:
-            csource = H.SourceDef('could not get source file')
+                href = self.linker.get_lazyhref(sourcefile)
 
-        csdiv = H.div(style='display: none')
-        for cs, _ in self.dsa.get_function_callpoints(dotted_name):
-            csdiv.append(self.build_callsite(dotted_name, cs))
-        callstack = H.CallStackDescription(
-            H.a('show/hide call sites',
-                href='#',
-                onclick='showhideel(getnextsibling(this)); return false;'),
-            csdiv,
-        )
-        snippet = H.FunctionDescription(
-            H.FunctionDef('def %s' % (localname,), argdesc),
-            H.Docstring(docstring or '*no docstring available*'),
-            H.div(H.a('show/hide info',
-                      href='#',
-                      onclick=('showhideel(getnextsibling(this));'
-                               'return false;')),
-                  H.div(valuedesc, csource, callstack, style='display: none',
-                        class_='funcinfo')),
-        )
+        csource = H.SourceSnippet(text, href, colored)
+        callstack = self.dsa.get_function_callpoints(dotted_name)
+        csitems = []
+        for cs, _ in callstack:
+            csitems.append(self.build_callsite(dotted_name, cs))
+        snippet = H.FunctionDescription(localname, argdesc, docstring,
+                                        valuedesc, csource, csitems)
         
         return snippet
 
@@ -501,8 +480,8 @@
 
         # top namespace, index.html
         module_name = self.dsa.get_module_name().split('/')[-1]
-        navitems.append(build_navitem_html(self.linker, module_name, '', 0,
-                                           True))
+        navitems.append(H.NavigationItem(self.linker, '', module_name, 0,
+                                         True))
         def build_nav_level(dotted_name, depth=1):
             navitems = []
             path = dotted_name.split('.')[:depth]
@@ -513,8 +492,8 @@
                 sibname = sibpath[-1]
                 if is_private(sibname):
                     continue
-                navitems.append(build_navitem_html(self.linker, sibname,
-                                                   dn, depth, selected))
+                navitems.append(H.NavigationItem(self.linker, dn, sibname,
+                                                 depth, selected))
                 if selected:
                     lastlevel = dn.count('.') == dotted_name.count('.')
                     if not lastlevel:
@@ -581,15 +560,10 @@
         return py.path.local(sourcefile).relto(self.projpath)
 
     def build_callsite(self, functionname, call_site):
+        print 'building callsite for', functionname
         tbtag = self.gen_traceback(functionname, reversed(call_site))
-        tag = H.CallStackItem(
-            H.a("show/hide stack trace %s - line %s" % (
-                    call_site[0].filename, call_site[0].lineno + 1),
-                href='#',
-                onclick="showhideel(getnextsibling(this)); return false;"),
-            H.div(tbtag, style='display: none', class_='callstackitem'),
-        )
-        return tag
+        return H.CallStackItem(call_site[0].filename, call_site[0].lineno + 1,
+                               tbtag)
     
     _reg_source = py.std.re.compile(r'([^>]*)<(.*)>')
     def gen_traceback(self, funcname, call_site):

Modified: py/trunk/py/apigen/testing/test_apigen_example.py
==============================================================================
--- py/trunk/py/apigen/testing/test_apigen_example.py	(original)
+++ py/trunk/py/apigen/testing/test_apigen_example.py	Sat Feb  3 00:29:01 2007
@@ -364,6 +364,16 @@
             '<h2>files</h2>'])
         _checkhtml(html)
 
+    def test_build_source_page(self):
+        data = self.spb.prepare_pages(self.fs_root)
+        self.spb.build_pages(data, self.project, self.fs_root)
+        funcsource = self.base.join('source/pkg/func.py.html')
+        assert funcsource.check(file=True)
+        html = funcsource.read()
+        print html
+        assert ('<span class="alt_keyword">def</span> '
+                '<a href="#func" name="func">func</a>(arg1):') in html
+
     def test_build_navigation_root(self):
         self.spb.prepare_pages(self.fs_root)
         nav = self.spb.build_navigation(self.fs_root.join('pkg'))

Modified: py/trunk/py/apigen/testing/test_htmlgen.py
==============================================================================
--- py/trunk/py/apigen/testing/test_htmlgen.py	(original)
+++ py/trunk/py/apigen/testing/test_htmlgen.py	Sat Feb  3 00:29:01 2007
@@ -19,15 +19,6 @@
                     'pkg': ['pkg.sub', 'pkg.SomeClass',
                             'pkg.SomeSubClass']}
 
-def test_build_navitem_html():
-    l = Linker()
-    l.set_link('spam.eggs.foo', 'foo.html')
-    h = htmlgen.build_navitem_html(l, 'foo', 'spam.eggs.foo', 0, False)
-    assert unicode(h) == u'<div><a href="foo.html">foo</a></div>'
-    h = htmlgen.build_navitem_html(l, 'bar', 'spam.eggs.foo', 1, True)
-    assert unicode(h) == (u'<div class="selected">\xa0\xa0'
-                          u'<a href="foo.html">bar</a></div>')
-
 def test_source_dirs_files():
     temp = py.test.ensuretemp('test_source_dirs_files')
     temp.join('dir').ensure(dir=True)
@@ -52,3 +43,15 @@
     assert htmlgen.deindent('foo\n\n      bar\n    baz\n') == (
         'foo\n\n  bar\nbaz\n')
 
+def test_enumerate_and_color():
+    colored = htmlgen.enumerate_and_color(['def foo():', '  print "bar"'], 0,
+                                          'ascii')
+    div = py.xml.html.div(*colored).unicode(indent=0)
+    assert div == ('<div>'
+                   '<span>   1: </span>'
+                   '<span class="alt_keyword">def</span> foo():\n'
+                   '<span>   2: </span>'
+                   '  <span class="keyword">print</span>'
+                   ' <span class="string">&quot;bar&quot;</span>\n'
+                   '</div>')
+


More information about the py-svn mailing list