Package logilab :: Package common :: Module html
[frames] | no frames]

Source Code for Module logilab.common.html

  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   
10 -def render_HTML_tree(tree, selected_node=None, render_node=None, caption=None):
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 # helper function that build a matrix from the tree, like: 30 # +------+-----------+-----------+ 31 # | root | child_1_1 | child_2_1 | 32 # | root | child_1_1 | child_2_2 | 33 # | root | child_1_2 | | 34 # | root | child_1_3 | child_2_3 | 35 # | root | child_1_3 | child_2_4 | 36 # +------+-----------+-----------+ 37 # from: 38 # root -+- child_1_1 -+- child_2_1 39 # | | 40 # | +- child_2_2 41 # +- child_1_2 42 # | 43 # +- child1_3 -+- child_2_3 44 # | 45 # +- child_2_2 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 # make all lines in the matrix have the same number of columns 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 # We build the matrix of link types (between 2 cells on a line of the matrix) 66 # link types are : 67 link_types = {(True, True, True ): 1, # T 68 (False, False, True ): 2, # | 69 (False, True, True ): 3, # + (actually, vert. bar with horiz. bar on the right) 70 (False, True, False): 4, # L 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 # We can now generate the HTML code for the <table> 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">&nbsp;</td>' 104 s += '<td class="tree_cell_%d_1">&nbsp;</td>' % link_cell 105 s += '<td class="tree_cell_%d_2">&nbsp;</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">&nbsp;</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">&nbsp;</td>' % link_cell 121 s += '<td class="tree_cell_%d_4">&nbsp;</td>' % link_cell 122 s += '</tr>\n' 123 124 s += '</table>' 125 return s 126