Following the question:
I want to visualize the tree table (hierarchical structure) in PDF using Cairo and Python.
I have modified the code as follows:
import uuid
import cairo
def sanitize_id(id):
    return id.strip().replace(" ", "")
(_ADD, _DELETE, _INSERT) = range(3)
(_ROOT, _DEPTH, _WIDTH) = range(3)
class Node:
    def __init__(self, name, identifier=None, expanded=True):
    self.__identifier = (str(uuid.uuid1()) if identifier is None else
                         sanitize_id(str(identifier)))
    self.name = name
    self.expanded = expanded
    self.__bpointer = None
    self.__fpointer = []
    @property
    def identifier(self):
    return self.__identifier
    @property
    def bpointer(self):
    return self.__bpointer
    @bpointer.setter
    def bpointer(self, value):
    if value is not None:
        self.__bpointer = sanitize_id(value)
    @property
    def fpointer(self):
    return self.__fpointer
    def update_fpointer(self, identifier, mode=_ADD):
    if mode is _ADD:
        self.__fpointer.append(sanitize_id(identifier))
    elif mode is _DELETE:
        self.__fpointer.remove(sanitize_id(identifier))
    elif mode is _INSERT:
        self.__fpointer = [sanitize_id(identifier)]
class Tree(object):
    def __init__(self, cr):
    self._context = cr
    self._colx = 50.0
    self._coly = 50.0
    self.textW = 128.0
    self.textH = 20.0
    self.nodes = []
    def get_index(self, position):
    for index, node in enumerate(self.nodes):
        if node.identifier == position:
            break
    return index
    def create_node(self, name, identifier=None, parent=None):
    node = Node(name, identifier)
    self.nodes.append(node)
    self.__update_fpointer(parent, node.identifier, _ADD)
    node.bpointer = parent
    return node
    def ShowText(self, x, y, st):
    self._context.move_to(x, y)
    self._context.show_text(st)
    self._context.stroke()
    def ShowRectText(self, x, y, w, h, st):
    self.ShowText(x, y, st)
    self._context.rectangle(x - 5, y - self.textH, w, h)
    self._context.stroke()
    def show(self, position, level=_ROOT):
    queue = self[position].fpointer
    h = self.textH*self.__len__()
    if level == _ROOT:
        s1 = "{0} [{1}]".format(self[position].name,
                                self[position].identifier)
        self.ShowRectText(self._colx, self._coly, self.textW, h, s1)
        self._coly = self._coly + self.textH
    else:
        s2 = "{0} [{1}]".format(self[position].name, self[position].identifier)
        self._colx = self._colx + self.textW * level
        self.ShowRectText(self._colx, self._coly, self.textW, h, s2)
        self._coly = self._coly + self.textH
        self._colx = self._colx - self.textW * level
        self._context.stroke()
    if self[position].expanded:
        level += 1
        for element in queue:
            self.show(element, level)  # recursive call
    def expand_tree(self, position, mode=_DEPTH):
    # Python generator. Loosly based on an algorithm from 'Essential LISP' by
    # John R. Anderson, Albert T. Corbett, and Brian J. Reiser, page 239-241
    yield position
    queue = self[position].fpointer
    while queue:
        yield queue[0]
        expansion = self[queue[0]].fpointer
        if mode is _DEPTH:
            queue = expansion + queue[1:]  # depth-first
        elif mode is _WIDTH:
            queue = queue[1:] + expansion  # width-first
    def is_branch(self, position):
    return self[position].fpointer
    def __update_fpointer(self, position, identifier, mode):
    if position is None:
        return
    else:
        self[position].update_fpointer(identifier, mode)
    def __update_bpointer(self, position, identifier):
    self[position].bpointer = identifier
    def __getitem__(self, key):
    return self.nodes[self.get_index(key)]
    def __setitem__(self, key, item):
    self.nodes[self.get_index(key)] = item
    def __len__(self):
    return len(self.nodes)
    def __contains__(self, identifier):
    return [node.identifier for node in self.nodes
            if node.identifier is identifier]
if __name__ == "__main__":
    surface = cairo.PDFSurface("cairo_tree_table_show.pdf", 1000, 800)
    context = cairo.Context(surface)
    tree = Tree(context)
    tree.create_node("Harry", "harry")  # root node
    tree.create_node("Jane", "jane", parent="harry")
    tree.create_node("Bill", "bill", parent="harry")
    tree.create_node("Joe", "joe", parent="jane")
    tree.create_node("Diane", "diane", parent="jane")
    tree.create_node("George", "george", parent="diane")
    tree.create_node("Mary", "mary", parent="diane")
    tree.create_node("Jill", "jill", parent="george")
    tree.create_node("Carol", "carol", parent="jill")
    tree.create_node("Grace", "grace", parent="bill")
    tree.create_node("Mark", "mark", parent="jane")
    tree.show("harry")
It gives me this:
but I want as:
If I can get level number of the tree leaf in the loop,I set the rectangle height = "(this level's leaf)*textH" ,draw the table.


 
    