summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2005-03-05 15:53:45 +0000
committerwiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2005-03-05 15:53:45 +0000
commitcb57e80d4b9d16aed07b08408f9e7ac527833bd1 (patch)
treeccfa7cb0889c2fe05a2e5fe2fea1db1859ceba99
parentfb848ff48742947b27a9fc5f57058f9f9e28cba6 (diff)
downloaddocutils-cb57e80d4b9d16aed07b08408f9e7ac527833bd1.tar.gz
added Node.has_children() and Node.next_node()
git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk/docutils@3007 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
-rw-r--r--docutils/nodes.py38
-rwxr-xr-xtest/test_nodes.py38
2 files changed, 76 insertions, 0 deletions
diff --git a/docutils/nodes.py b/docutils/nodes.py
index 2cb04300c..51bcb583d 100644
--- a/docutils/nodes.py
+++ b/docutils/nodes.py
@@ -161,6 +161,40 @@ class Node:
category='nodes.Node.walkabout')
visitor.dispatch_departure(self)
+ def has_children(self):
+ """Return true if this node has children."""
+ return 0
+
+ def next_node(self, descend=1, ascend=1, cond=lambda e: 1):
+ """
+ Return the next node in tree traversal order for which the
+ condition cond(node) is true.
+
+ If descend is true, traverse children as well. If ascend is
+ true, go up in the tree if there is no direct next sibling.
+ Return None if there is no next node.
+ """
+ node = self
+ while 1:
+ if descend and node.has_children():
+ r = node[0]
+ elif node.parent is not None:
+ # Index of the next sibling.
+ index = node.parent.index(node) + 1
+ if index < len(node.parent):
+ r = node.parent[index]
+ elif ascend:
+ r = node.parent.next_node(descend=0, ascend=1)
+ else:
+ return None
+ else:
+ return None
+ if cond(r):
+ return r
+ else:
+ # Get r.next_node(...), avoiding recursion.
+ node = r
+
class Text(Node, UserString):
@@ -505,6 +539,10 @@ class Element(Node):
"""Return this element's children."""
return self.children
+ def has_children(self):
+ """Return true if this node has children."""
+ return len(self.children) > 0
+
def copy(self):
return self.__class__(**self.attributes)
diff --git a/test/test_nodes.py b/test/test_nodes.py
index fe8f0420f..fee03ffe2 100755
--- a/test/test_nodes.py
+++ b/test/test_nodes.py
@@ -10,6 +10,8 @@
Test module for nodes.py.
"""
+from __future__ import nested_scopes
+
import unittest
from types import ClassType
from DocutilsTestSupport import nodes, utils
@@ -108,6 +110,42 @@ class MiscTests(unittest.TestCase):
normed = nodes.make_id(input)
self.assertEquals(normed, output)
+ def test_has_children(self):
+ self.assert_(not nodes.Text('some text').has_children())
+ self.assert_(not nodes.Node().has_children())
+ e = nodes.TextElement()
+ self.assert_(not e.has_children())
+ e += nodes.Text('some text')
+ self.assert_(e.has_children())
+ self.assert_(not e[0].has_children())
+
+ def test_next_node(self):
+ def getlist(n, **kwargs):
+ r = []
+ while n is not None:
+ n = n.next_node(**kwargs)
+ r.append(n)
+ return r[:-1]
+ e = nodes.Element()
+ e += nodes.Element()
+ e[0] += nodes.Element()
+ e[0] += nodes.Element()
+ e[0][1] += nodes.Text('some text')
+ e += nodes.Element()
+ e += nodes.Element()
+ i = e
+ l = []
+ self.assertEquals(getlist(e),
+ [e[0], e[0][0], e[0][1], e[0][1][0], e[1], e[2]])
+ self.assertEquals(getlist(e, descend=0), [])
+ self.assertEquals(getlist(e[0], descend=0), [e[1], e[2]])
+ self.assertEquals(getlist(e[0][0], descend=0), [e[0][1], e[1], e[2]])
+ self.assertEquals(getlist(e, ascend=0),
+ [e[0], e[0][0], e[0][1], e[0][1][0]])
+ self.assertEquals(getlist(e[0][0], descend=0, ascend=0), [e[0][1]])
+ self.assertEquals(getlist(e, cond=lambda x: x not in e[0:2]),
+ [e[0][0], e[0][1], e[0][1][0], e[2]])
+
class TreeCopyVisitorTests(unittest.TestCase):