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

guido at codespeak.net guido at codespeak.net
Tue Feb 6 14:19:19 CET 2007


Author: guido
Date: Tue Feb  6 14:19:16 2007
New Revision: 38005

Modified:
   py/trunk/py/apigen/apigen.py
   py/trunk/py/apigen/html.py
   py/trunk/py/apigen/htmlgen.py
   py/trunk/py/apigen/style.css
   py/trunk/py/apigen/testing/test_apigen_functional.py
   py/trunk/py/apigen/testing/test_htmlgen.py
Log:
Made that source snippets are now shown in two tables, to allow selecting
the source without the line numbers, decreased font size a bit, made that the
Page class can be passed in from the outside (build() method) to more easily
allow customization of the layout and pages.


Modified: py/trunk/py/apigen/apigen.py
==============================================================================
--- py/trunk/py/apigen/apigen.py	(original)
+++ py/trunk/py/apigen/apigen.py	Tue Feb  6 14:19:16 2007
@@ -12,6 +12,8 @@
 from py.__.apigen import project
 from py.__.apigen.tracer.docstorage import pkg_to_dict
 
+from layout import LayoutPage
+
 def get_documentable_items_pkgdir(pkgdir):
     """ get all documentable items from an initpkg pkgdir
     
@@ -31,20 +33,27 @@
     return pkgname, pkgdict
 
 def build(pkgdir, dsa, capture):
+    # create a linker (link database) for cross-linking
     l = linker.Linker()
+
+    # create a project.Project instance to contain the LayoutPage instances
     proj = project.Project()
 
+    # output dir
     if 'APIGEN_TARGET' in os.environ:
         targetdir = py.path.local(os.environ['APIGEN_TARGET'])
     else:
         targetdir = pkgdir.dirpath().join('apigen')
     targetdir.ensure(dir=True)
 
+    # find out what to build
     all_names = dsa._get_names(filter=lambda x, y: True)
     namespace_tree = htmlgen.create_namespace_tree(all_names)
+
+    # and build it
     apb = htmlgen.ApiPageBuilder(targetdir, l, dsa, pkgdir, namespace_tree,
-                                 capture)
-    spb = htmlgen.SourcePageBuilder(targetdir, l, pkgdir, capture)
+                                 capture, LayoutPage)
+    spb = htmlgen.SourcePageBuilder(targetdir, l, pkgdir, capture, LayoutPage)
 
     capture.err.writeorg('preparing namespace pages\n')
     ns_data = apb.prepare_namespace_pages()

Modified: py/trunk/py/apigen/html.py
==============================================================================
--- py/trunk/py/apigen/html.py	(original)
+++ py/trunk/py/apigen/html.py	Tue Feb  6 14:19:16 2007
@@ -4,7 +4,8 @@
 # HTML related stuff
 class H(html):
     class Content(html.div):
-        pass # style = html.Style(margin_left='15em')
+        def __init__(self, *args):
+            super(H.Content, self).__init__(id='apigen-content', *args)
 
     class Description(html.div):
         pass
@@ -88,12 +89,29 @@
             if href:
                 link = H.a(text, href=href)
             super(H.SourceSnippet, self).__init__(
-                link, H.div(class_='code', *sourceels))
+                link, H.div(*sourceels))
     
     class SourceDef(html.div):
         def __init__(self, *sourceels):
             super(H.SourceDef, self).__init__(
-                H.div(class_='code', *sourceels))
+                H.div(*sourceels))
+
+    class SourceCode(html.div):
+        style = html.Style(margin_top='1em', margin_bottom='1em')
+        def __init__(self):
+            self.linenotable = lntable = H.table(style='float: left')
+            self.linenotbody = lntbody = H.tbody()
+            lntable.append(lntbody)
+
+            self.linetable = ltable = H.table()
+            self.linetbody = ltbody = H.tbody()
+            ltable.append(ltbody)
+            
+            super(H.SourceCode, self).__init__(lntable, ltable)
+
+        def add_line(self, lineno, els):
+            self.linenotbody.append(H.tr(H.td(lineno, class_='lineno')))
+            self.linetbody.append(H.tr(H.td(class_='code', *els)))
 
     class NonPythonSource(html.pre):
         pass # style = html.Style(margin_left='15em')

Modified: py/trunk/py/apigen/htmlgen.py
==============================================================================
--- py/trunk/py/apigen/htmlgen.py	(original)
+++ py/trunk/py/apigen/htmlgen.py	Tue Feb  6 14:19:16 2007
@@ -115,32 +115,65 @@
                 ret[ns].append(itempath)
     return ret
 
-def wrap_page(project, title, contentel, navel, relbase, basepath):
-    page = LayoutPage(project, title, nav=navel, encoding='UTF-8',
+def wrap_page(project, title, contentel, navel, relbase, basepath,
+              pageclass):
+    page = pageclass(project, title, nav=navel, encoding='UTF-8',
                       relpath=relbase)
     page.set_content(contentel)
     page.setup_scripts_styles(basepath)
     return page
 
+def enumerate_and_color(codelines, firstlineno, enc):
+    snippet = H.SourceCode()
+    tokenizer = source_color.Tokenizer(source_color.PythonSchema)
+    for i, line in enumerate(codelines):
+        try:
+            snippet.add_line(i + firstlineno + 1,
+                             source_html.prepare_line([line], tokenizer, enc))
+        except py.error.ENOENT:
+            # error reading source code, giving up
+            snippet = org
+            break
+    return snippet
+
+def get_obj(pkg, dotted_name):
+    full_dotted_name = '%s.%s' % (pkg.__name__, dotted_name)
+    if dotted_name == '':
+        return pkg
+    path = dotted_name.split('.')
+    ret = pkg
+    for item in path:
+        marker = []
+        ret = getattr(ret, item, marker)
+        if ret is marker:
+            raise NameError('can not access %s in %s' % (item,
+                                                         full_dotted_name))
+    return ret
+
 # the PageBuilder classes take care of producing the docs (using the stuff
 # above)
 class AbstractPageBuilder(object):
+    pageclass = LayoutPage
+    
     def write_page(self, title, reltargetpath, project, tag, nav):
         targetpath = self.base.join(reltargetpath)
         relbase= relpath('%s%s' % (targetpath.dirpath(), targetpath.sep),
                          self.base.strpath + '/')
-        page = wrap_page(project, title, tag, nav, relbase, self.base)
+        page = wrap_page(project, title, tag, nav, relbase, self.base,
+                         self.pageclass)
         content = self.linker.call_withbase(reltargetpath, page.unicode)
         targetpath.ensure()
         targetpath.write(content.encode("utf8"))
 
 class SourcePageBuilder(AbstractPageBuilder):
     """ builds the html for a source docs page """
-    def __init__(self, base, linker, projroot, capture=None):
+    def __init__(self, base, linker, projroot, capture=None,
+                 pageclass=LayoutPage):
         self.base = base
         self.linker = linker
         self.projroot = projroot
         self.capture = capture
+        self.pageclass = pageclass
     
     def build_navigation(self, fspath):
         nav = H.Navigation(class_='sidebar')
@@ -191,7 +224,7 @@
         source = fspath.read()
         sep = get_linesep(source)
         colored = enumerate_and_color(source.split(sep), 0, enc)
-        tag = H.SourceDef(*colored)
+        tag = H.SourceDef(colored)
         nav = self.build_navigation(fspath)
         return tag, nav
 
@@ -260,38 +293,10 @@
                                                                 '/')
             self.write_page(title, reltargetpath, project, tag, nav)
 
-def enumerate_and_color(codelines, firstlineno, enc):
-    tokenizer = source_color.Tokenizer(source_color.PythonSchema)
-    colored = []
-    for i, line in enumerate(codelines):
-        try:
-            colored.append(H.span('%04s: ' % (i + firstlineno + 1)))
-            colored.append(source_html.prepare_line([line], tokenizer, enc))
-            colored.append('\n')
-        except py.error.ENOENT:
-            # error reading source code, giving up
-            colored = org
-            break
-    return colored
-
-def get_obj(pkg, dotted_name):
-    full_dotted_name = '%s.%s' % (pkg.__name__, dotted_name)
-    if dotted_name == '':
-        return pkg
-    path = dotted_name.split('.')
-    ret = pkg
-    for item in path:
-        marker = []
-        ret = getattr(ret, item, marker)
-        if ret is marker:
-            raise NameError('can not access %s in %s' % (item,
-                                                         full_dotted_name))
-    return ret
-
 class ApiPageBuilder(AbstractPageBuilder):
     """ builds the html for an api docs page """
     def __init__(self, base, linker, dsa, projroot, namespace_tree,
-                 capture=None):
+                 capture=None, pageclass=LayoutPage):
         self.base = base
         self.linker = linker
         self.dsa = dsa
@@ -299,6 +304,7 @@
         self.projpath = py.path.local(projroot)
         self.namespace_tree = namespace_tree
         self.capture = capture
+        self.pageclass = pageclass
 
         pkgname = self.dsa.get_module_name().split('/')[-1]
         self.pkg = __import__(pkgname)
@@ -327,7 +333,7 @@
             firstlineno = func.func_code.co_firstlineno
             sep = get_linesep(callable_source)
             org = callable_source.split(sep)
-            colored = enumerate_and_color(org, firstlineno, enc)
+            colored = [enumerate_and_color(org, firstlineno, enc)]
             text = 'source: %s' % (sourcefile,)
             if is_in_pkg:
                 href = self.linker.get_lazyhref(sourcefile)
@@ -657,11 +663,12 @@
                 else:
                     enc = 'latin-1'
                     sourcelink = H.div(linktext)
-                colored = enumerate_and_color(mangled, frame.firstlineno, enc)
+                colored = [enumerate_and_color(mangled,
+                                               frame.firstlineno, enc)]
             else:
                 sourcelink = H.div('source unknown (%s)' % (sourcefile,))
                 colored = mangled[:]
             tbdiv.append(sourcelink)
-            tbdiv.append(H.div(class_='code', *colored))
+            tbdiv.append(H.div(*colored))
         return tbdiv
 

Modified: py/trunk/py/apigen/style.css
==============================================================================
--- py/trunk/py/apigen/style.css	(original)
+++ py/trunk/py/apigen/style.css	Tue Feb  6 14:19:16 2007
@@ -1,5 +1,10 @@
+#apigen-content {
+  font-size: 0.8em;
+}
+
 div.sidebar {
   font-family: Verdana, Helvetica, Arial, sans-serif;
+  font-size: 0.9em;
   width: 155px;
   vertical-align: top;
   margin-top: 0.5em;

Modified: py/trunk/py/apigen/testing/test_apigen_functional.py
==============================================================================
--- py/trunk/py/apigen/testing/test_apigen_functional.py	(original)
+++ py/trunk/py/apigen/testing/test_apigen_functional.py	Tue Feb  6 14:19:16 2007
@@ -26,6 +26,14 @@
             def get_somevar(self):
                 " get_somevar docstring "
                 return self.somevar
+            
+            def get_some_source(self):
+                ret = py.code.Source('''\\
+                    def foo():
+                      return 'bar'
+                ''')
+                return ret
+
     """))
     temp.ensure('pak/sometestsubclass.py').write(py.code.Source("""\
         from sometestclass import SomeTestClass

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	Tue Feb  6 14:19:16 2007
@@ -47,13 +47,54 @@
     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">"bar"</span>\n'
-                   '</div>')
+    print repr(div)
+    assert div == (u'<div>'
+                    '<table style="float: left">'
+                    '<tbody>'
+                    '<tr><td class="lineno">1</td></tr>'
+                    '<tr><td class="lineno">2</td></tr>'
+                    '</tbody>'
+                    '</table>'
+                    '<table>'
+                    '<tbody>'
+                    '<tr><td class="code">'
+                    '<span class="alt_keyword">def</span> foo():'
+                    '</td></tr>'
+                    '<tr><td class="code">'
+                    '  <span class="keyword">print</span>'
+                    ' <span class="string">"bar"</span>'
+                    '</td></tr>'
+                    '</tbody>'
+                    '</table>'
+                    '</div>')
+
+def test_enumerate_and_color_multiline():
+    colored = htmlgen.enumerate_and_color(['code = """\\', 'foo bar', '"""'],
+                                          0, 'ascii')
+    div = py.xml.html.div(*colored).unicode(indent=0)
+    print repr(div)
+    assert div == (u'<div>'
+                    '<table style="float: left">'
+                    '<tbody>'
+                    '<tr><td class="lineno">1</td></tr>'
+                    '<tr><td class="lineno">2</td></tr>'
+                    '<tr><td class="lineno">3</td></tr>'
+                    '</tbody>'
+                    '</table>'
+                    '<table>'
+                    '<tbody>'
+                    '<tr><td class="code">'
+                    'code = <span class="string">"""\\</span>'
+                    '</td></tr>'
+                    '<tr><td class="code">'
+                    '<span class="string">foo bar</span>'
+                    '</td></tr>'
+                    '<tr><td class="code">'
+                    '<span class="string">"""</span>'
+                    '</td></tr>'
+                    '</tbody>'
+                    '</table>'
+                    '</div>')
 
 def test_show_property():
     assert htmlgen.show_property('foo')



More information about the pytest-commit mailing list