Changeset 95:1f15abe2f51a
- Timestamp:
- 01/21/09 07:18:37 (14 months ago)
- Branch:
- default
- Files:
-
- 1 modified
-
relatorio/templates/opendocument.py (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
relatorio/templates/opendocument.py
r94 r95 121 121 122 122 123 def wrap_nodes_between(first, last, new_parent): 124 old_parent = first.getparent() 125 for node in first.itersiblings(): 126 if node is last: 127 break 128 # appending a node to a new parent also 129 # remove it from its previous parent 130 new_parent.append(node) 131 old_parent.replace(first, new_parent) 132 old_parent.remove(last) 133 134 123 135 class Template(MarkupTemplate): 124 136 … … 262 274 table_row_tag = '{%s}table-row' % table_namespace 263 275 table_cell_tag = '{%s}table-cell' % table_namespace 276 table_cov_cell_tag = '{%s}covered-table-cell' % table_namespace 264 277 table_num_col_attr = '{%s}number-columns-repeated' % table_namespace 265 278 table_name_attr = '{%s}name' % table_namespace 279 table_rowspan_attr = '{%s}number-rows-spanned' % table_namespace 266 280 267 281 office_name = '{%s}value' % self.namespaces['office'] … … 298 312 break 299 313 except ValueError: 314 # c_ancestors.index(node) raise ValueError if node is 315 # not a child of c_ancestors 300 316 pass 301 317 o_ancestors.append(node) … … 327 343 # the first cell node after the opening (cell node) 328 344 # ancestor 329 enclosed_cell = outermost_o_ancestor. itersiblings().next()345 enclosed_cell = outermost_o_ancestor.getnext() 330 346 assert enclosed_cell.tag == table_cell_tag 331 347 attr_value = "__inc_col_count(%d)" % loop_id … … 343 359 # find the position in the row of the cells holding the 344 360 # <for> and </for> instructions 361 #XXX: count cells only instead of * 345 362 position_xpath_expr = 'count(preceding-sibling::*)' 346 363 opening_pos = \ … … 351 368 namespaces=self.namespaces)) 352 369 353 # check if this table was already processed 370 # check whether or not the opening tag spans several rows 371 o_node_attrs = outermost_o_ancestor.attrib 372 if table_rowspan_attr in o_node_attrs: 373 rows_spanned = int(o_node_attrs[table_rowspan_attr]) 374 # if so, we need to replace the corresponding cell on 375 # the next line (a covered-table-cell) by a duplicate 376 # py:for node, delete the covered-table-cell 377 # corresponding to the /for, and move all cells between 378 # them into the py:for node 379 row_node = outermost_o_ancestor.getparent() 380 assert row_node.tag == table_row_tag 381 next_rows = row_node.itersiblings(table_row_tag) 382 for row_idx in range(rows_spanned-1): 383 next_row_node = next_rows.next() 384 first = next_row_node[opening_pos] 385 last = next_row_node[closing_pos] 386 assert first.tag == table_cov_cell_tag 387 assert last.tag == table_cov_cell_tag 388 389 # execute moves (add a <py:for> node around 390 # the column definitions nodes) 391 tag = '{%s}%s' % (py_namespace, directive) 392 for_node = EtreeElement(tag, 393 attrib={attr: a_val}, 394 nsmap=self.namespaces) 395 wrap_nodes_between(first, last, for_node) 396 397 # check if this table's headers were already processed 354 398 repeat_node = table_node.find(repeat_tag) 355 399 if repeat_node is not None: … … 391 435 # need to be moved to inside the "repeat" tag (which 392 436 # is to be created later). 393 to_remove = [] 394 to_move = [] 395 coldefs = table_node.iterchildren(table_col_tag) 396 for idx, tag in enumerate(coldefs): 397 if idx in (opening_pos, closing_pos): 398 to_remove.append(tag) 399 if opening_pos < idx < closing_pos: 400 to_move.append(tag) 401 elif idx > closing_pos: 402 break 403 assert len(to_remove) == 2, "failed %d %d" \ 404 % (opening_pos, closing_pos) 405 assert to_move 406 407 # execute deletes 408 for node in to_remove: 409 table_node.remove(node) 437 coldefs = list(table_node.iterchildren(table_col_tag)) 438 first = table_node[opening_pos] 439 last = table_node[closing_pos] 410 440 411 441 # execute moves (add a <relatorio:repeat> node around 412 442 # the column definitions nodes) 413 o_pos, c_pos = str(opening_pos), str(closing_pos)414 repeat_node = EtreeElement(repeat_tag,415 attrib={416 "opening": o_pos,417 "closing": c_pos,418 "table": table_name},443 attribs = { 444 "opening": str(opening_pos), 445 "closing": str(closing_pos), 446 "table": table_name 447 } 448 repeat_node = EtreeElement(repeat_tag, attrib=attribs, 419 449 nsmap=self.namespaces) 420 421 for node in to_move[1:]: 422 table_node.remove(node) 423 repeat_node.append(node) 424 table_node.replace(to_move[0], repeat_node) 425 repeat_node.append(to_move[0]) 450 wrap_nodes_between(first, last, repeat_node) 426 451 427 452 # - we create a <py:xxx> node … … 431 456 nsmap=self.namespaces) 432 457 433 # - we add all the nodes between the opening and closing 434 # statements to this new node 435 for node in outermost_o_ancestor.itersiblings(): 436 if node is outermost_c_ancestor: 437 break 438 genshi_node.append(node) 439 458 # - we move all the nodes between the opening and closing 459 # statements to this new node (append also removes from old 460 # parent) 440 461 # - we replace the opening statement by the <py:xxx> node 441 ancestor.replace(outermost_o_ancestor, genshi_node)442 443 462 # - we delete the closing statement (and its ancestors) 444 ancestor.remove(outermost_c_ancestor) 463 wrap_nodes_between(outermost_o_ancestor, outermost_c_ancestor, 464 genshi_node) 445 465 else: 446 466 # It's not a genshi statement it's a python expression
