[telepathy-spec/master] Support nested <tp:section> tags.
Davyd Madeley
davyd at madeley.id.au
Thu Mar 26 19:55:09 PDT 2009
---
doc/templates/index.html | 45 +++++++++++++-----------
tools/specparser.py | 83 +++++++++++++++++++++++++--------------------
2 files changed, 70 insertions(+), 58 deletions(-)
diff --git a/doc/templates/index.html b/doc/templates/index.html
index 4679ae4..e7e5667 100644
--- a/doc/templates/index.html
+++ b/doc/templates/index.html
@@ -24,30 +24,33 @@
<a name="interfaces"></a>
<h3>Interfaces</h3>
<ul>
- #for ($chapter, $interfaces) in $spec.group_by_chapters()
- #if $chapter is not None
- <li class="chapter">$chapter.short_name</li>
- $chapter.get_docstring()
- <ul>
- #end if
- #for $interface in $interfaces
- #if $interface.causes_havoc
- <li class="causes-havoc">
- #elif $interface.deprecated
- <li class="deprecated">
+ #def output($items)
+ #for $item in $items
+ #if $item.__class__.__name__ == 'Section'
+ <li class="chapter">$item.short_name</li>
+ $item.get_docstring()
+ <ul>
+ $output($item.items)
+ </ul>
#else
- <li>
- #end if
- <a href="$interface.get_url()">$interface.name</a>
- #if $interface.causes_havoc
- (unstable)
- #elif $interface.deprecated
- (deprecated)
+ #if $item.causes_havoc
+ <li class="causes-havoc">
+ #elif $item.deprecated
+ <li class="deprecated">
+ #else
+ <li>
#end if
- </li>
+ <a href="$item.get_url()">$item.name</a>
+ #if $item.causes_havoc
+ (unstable)
+ #elif $item.deprecated
+ (deprecated)
+ #end if
+ </li>
+ #end if
#end for
- #if $chapter: </ul>
- #end for
+ #end def
+ $output($spec.items)
</ul>
<a name="other"></a>
diff --git a/tools/specparser.py b/tools/specparser.py
index 0caab84..4ad4226 100644
--- a/tools/specparser.py
+++ b/tools/specparser.py
@@ -24,7 +24,6 @@
import sys
import xml.dom.minidom
-from itertools import groupby
import xincludator
@@ -217,10 +216,6 @@ class Base(object):
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.name)
-class Chapter(Base):
- def get_root_namespace(self):
- return None
-
class PossibleError(Base):
def __init__(self, parent, namespace, dom):
super(PossibleError, self).__init__(parent, namespace, dom)
@@ -396,19 +391,6 @@ class External(object):
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.name)
-def get_chapter_node (dom):
- """Walk up the DOM tree until we hit either tp:chapter (at which point
- we return the chapter node) or tp:spec (at which point we return None).
- """
-
- if dom.parentNode.namespaceURI == XMLNS_TP:
- if dom.parentNode.localName == 'chapter':
- return dom.parentNode
- elif dom.parentNode.localName == 'spec':
- return None
-
- return get_chapter_node(dom.parentNode)
-
class Interface(Base):
def __init__(self, parent, namespace, dom):
super(Interface, self).__init__(parent, namespace, dom)
@@ -437,9 +419,6 @@ class Interface(Base):
self.requires = map(lambda n: n.getAttribute('interface'),
getChildrenByName(dom, XMLNS_TP, 'requires'))
- # find out if this interface is part of a chapter
- self.chapter = get_chapter_node(dom)
-
def get_interface(self):
return self
@@ -649,7 +628,43 @@ class Flags(EnumLike):
dom.getElementsByTagNameNS(XMLNS_TP, 'flag'))
self.flags = self.values # in case you're looking for it
-class Spec(object):
+class SectionBase(object):
+ """A SectionBase is an abstract base class for any type of node that can
+ contain a <tp:section>, which means the top-level Spec object, or any
+ Section object.
+
+ It should not be instantiated directly.
+ """
+
+ def __init__(self, dom):
+
+ self.items = []
+
+ def recurse(nodes):
+ # iterate through the list of child nodes
+ for node in nodes:
+ if node.nodeType != node.ELEMENT_NODE: continue
+
+ if node.tagName == 'node':
+ # recurse into this level for interesting items
+ recurse(node.childNodes)
+ elif node.namespaceURI == XMLNS_TP and \
+ node.localName == 'section':
+ self.items.append(Section(self, None, node))
+ elif node.tagName == 'interface':
+ self.items.append(Interface(self, None, node))
+
+ recurse(dom.childNodes)
+
+class Section(Base, SectionBase):
+ def __init__(self, parent, namespace, dom):
+ Base.__init__(self, parent, namespace, dom)
+ SectionBase.__init__(self, dom)
+
+ def get_root_namespace(self):
+ return None
+
+class Spec(SectionBase):
def __init__(self, dom):
# build a dictionary of errors in this spec
try:
@@ -666,9 +681,16 @@ class Spec(object):
dom.getElementsByTagNameNS(XMLNS_TP, 'generic-types')),
[])
+ # create a top-level section for this Spec
+ SectionBase.__init__(self, dom.documentElement)
+
# build a list of interfaces in this spec
- self.interfaces = build_list(self, Interface, None,
- dom.getElementsByTagName('interface'))
+ self.interfaces = []
+ def recurse(items):
+ for item in items:
+ if isinstance(item, Section): recurse(item.items)
+ elif isinstance(item, Interface): self.interfaces.append(item)
+ recurse(self.items)
# build a giant dictionary of everything (interfaces, methods, signals
# and properties); also build a dictionary of types
@@ -718,19 +740,6 @@ class Spec(object):
def get_spec(self):
return self
- def group_by_chapters(self):
- """Group consecutive interfaces that are part of the same chapter.
- """
- spec = self.get_spec()
-
- def chapter(dom):
- # ignore None elements
- if dom is not None: return Chapter(spec, None, dom)
- else: return None
-
- return [ (chapter(c), list(i))
- for (c, i) in groupby(self.interfaces, key=lambda i: i.chapter) ]
-
def lookup(self, name, namespace=None):
key = build_name(namespace, name)
return self.everything[key]
--
1.5.6.5
More information about the telepathy-commits
mailing list