1 """render a tree in HTML.
2
3 :copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
4 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
5 :license: General Public License version 2 - http://www.gnu.org/licenses
6 """
7 __docformat__ = "restructuredtext en"
8
9
11 """
12 Generate a pure HTML representation of a tree given as an instance
13 of a logilab.common.tree.Node
14
15 selected_node is the currently selected node (if any) which will
16 have its surrounding <div> have id="selected" (which default
17 to a bold border libe with the default CSS).
18
19 render_node is a function that should take a Node content (Node.id)
20 as parameter and should return a string (what will be displayed
21 in the cell).
22
23 Warning: proper rendering of the generated html code depends on html_tree.css
24 """
25 tree_depth = tree.depth_down()
26 if render_node is None:
27 render_node = str
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 def build_matrix(path, matrix):
47 if path[-1].is_leaf():
48 matrix.append(path[:])
49 else:
50 for child in path[-1].children:
51 build_matrix(path[:] + [child], matrix)
52
53 matrix = []
54 build_matrix([tree], matrix)
55
56
57 for line in matrix:
58 line.extend([None]*(tree_depth-len(line)))
59 for i in range(len(matrix)-1, 0, -1):
60 prev_line, line = matrix[i-1:i+1]
61 for j in range(len(line)):
62 if line[j] == prev_line[j]:
63 line[j] = None
64
65
66
67 link_types = {(True, True, True ): 1,
68 (False, False, True ): 2,
69 (False, True, True ): 3,
70 (False, True, False): 4,
71 (True, True, False): 5,
72 }
73 links = []
74 for i, line in enumerate(matrix):
75 links.append([])
76 for j in range(tree_depth-1):
77 cell_11 = line[j] is not None
78 cell_12 = line[j+1] is not None
79 cell_21 = line[j+1] is not None and line[j+1].next_sibling() is not None
80 link_type = link_types.get((cell_11, cell_12, cell_21), 0)
81 if link_type == 0 and i > 0 and links[i-1][j] in (1, 2, 3):
82 link_type = 2
83 links[-1].append(link_type)
84
85
86
87 s = u'<table class="tree">\n'
88 if caption:
89 s += '<caption>%s</caption>\n' % caption
90
91 for i, link_line in enumerate(links):
92 line = matrix[i]
93
94 s += '<tr>'
95 for j, link_cell in enumerate(link_line):
96 cell = line[j]
97 if cell:
98 if cell.id == selected_node:
99 s += '<td class="tree_cell" rowspan="2"><div class="selected tree_cell">%s</div></td>' % (render_node(cell.id))
100 else:
101 s += '<td class="tree_cell" rowspan="2"><div class="tree_cell">%s</div></td>' % (render_node(cell.id))
102 else:
103 s += '<td rowspan="2"> </td>'
104 s += '<td class="tree_cell_%d_1"> </td>' % link_cell
105 s += '<td class="tree_cell_%d_2"> </td>' % link_cell
106
107 cell = line[-1]
108 if cell:
109 if cell.id == selected_node:
110 s += '<td class="tree_cell" rowspan="2"><div class="selected tree_cell">%s</div></td>' % (render_node(cell.id))
111 else:
112 s += '<td class="tree_cell" rowspan="2"><div class="tree_cell">%s</div></td>' % (render_node(cell.id))
113 else:
114 s += '<td rowspan="2"> </td>'
115
116 s += '</tr>\n'
117 if link_line:
118 s += '<tr>'
119 for j, link_cell in enumerate(link_line):
120 s += '<td class="tree_cell_%d_3"> </td>' % link_cell
121 s += '<td class="tree_cell_%d_4"> </td>' % link_cell
122 s += '</tr>\n'
123
124 s += '</table>'
125 return s
126