Changeset 97:a6d5014aea9c
- Timestamp:
- 01/22/09 04:39:36 (14 months ago)
- Branch:
- default
- Files:
-
- 1 modified
-
relatorio/templates/opendocument.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
relatorio/templates/opendocument.py
r96 r97 274 274 table_row_tag = '{%s}table-row' % table_namespace 275 275 table_cell_tag = '{%s}table-cell' % table_namespace 276 table_cov_cell_tag = '{%s}covered-table-cell' % table_namespace277 276 table_num_col_attr = '{%s}number-columns-repeated' % table_namespace 278 277 table_name_attr = '{%s}name' % table_namespace 279 table_rowspan_attr = '{%s}number-rows-spanned' % table_namespace280 278 281 279 office_name = '{%s}value' % self.namespaces['office'] … … 284 282 py_namespace = self.namespaces['py'] 285 283 py_attrs_attr = '{%s}attrs' % py_namespace 286 genshi_replace = '{%s}replace' % py_namespace284 py_replace = '{%s}replace' % py_namespace 287 285 288 286 repeat_tag = '{%s}repeat' % self.namespaces['relatorio'] … … 321 319 outermost_c_ancestor = c_ancestors[-1] 322 320 323 # handle horizontal repetition (over columns)321 # handle horizontal repetitions (over columns) 324 322 if directive == "for" and ancestor.tag == table_row_tag: 325 323 self.has_col_loop = True … … 337 335 # operations, but a unique id within the table is required 338 336 # to support nested column repetition 339 a ttr_value = "__reset_col_count(%d)" % loop_id340 ancestor.attrib[py_attrs_attr] = attr_value337 ancestor.attrib[py_attrs_attr] = \ 338 "__relatorio_reset_col_count(%d)" % loop_id 341 339 342 340 # 2) add increment code (through a py:attrs attribute) on … … 345 343 enclosed_cell = outermost_o_ancestor.getnext() 346 344 assert enclosed_cell.tag == table_cell_tag 347 attr_value = "__inc_col_count(%d)" % loop_id348 enclosed_cell.attrib[py_attrs_attr] = attr_value345 enclosed_cell.attrib[py_attrs_attr] = \ 346 "__relatorio_inc_col_count(%d)" % loop_id 349 347 350 348 # 3) add "store count" code as a py:replace node, as the 351 349 # last child of the row 352 attr_value = "__ store_col_count(%d, %r)" % (loop_id,353 table_name)354 replace_node = EtreeElement( '{%s}replace' % py_namespace,350 attr_value = "__relatorio_store_col_count(%d, %r)" \ 351 % (loop_id, table_name) 352 replace_node = EtreeElement(py_replace, 355 353 attrib={'value': attr_value}, 356 354 nsmap=self.namespaces) … … 369 367 370 368 # 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 375 # a_val == "target in iterable" 376 target, iterable = a_val.split(' in ', 1) 377 temp_var = "temp%d" % id(outermost_o_ancestor) 378 # I need to get "temp_iterable = list(iterable)" 379 vars = "%s = list(%s)" % (temp_var, iterable.strip()) 380 # transform a_val to "target in temp_iterable" 381 a_val = "%s in %s" % (target, temp_var) 382 383 with_node = EtreeElement('{%s}with' % py_namespace, 384 attrib={"vars": vars}, 385 nsmap=self.namespaces) 386 387 # if so, we need to replace the corresponding cell on 388 # the next line (a covered-table-cell) by a duplicate 389 # py:for node, delete the covered-table-cell 390 # corresponding to the /for, and move all cells between 391 # them into the py:for node 392 row_node = outermost_o_ancestor.getparent() 393 row_node.addprevious(with_node) 394 rows_to_wrap = [row_node] 395 396 assert row_node.tag == table_row_tag 397 next_rows = row_node.itersiblings(table_row_tag) 398 for row_idx in range(rows_spanned-1): 399 next_row_node = next_rows.next() 400 rows_to_wrap.append(next_row_node) 401 first = next_row_node[opening_pos] 402 last = next_row_node[closing_pos] 403 assert first.tag == table_cov_cell_tag 404 assert last.tag == table_cov_cell_tag 405 406 # execute moves (add a <py:for> node around 407 # the column definitions nodes) 408 tag = '{%s}%s' % (py_namespace, directive) 409 for_node = EtreeElement(tag, 410 attrib={attr: a_val}, 411 nsmap=self.namespaces) 412 wrap_nodes_between(first, last, for_node) 413 414 for node in rows_to_wrap: 415 with_node.append(node) 369 a_val = self._handle_row_spanned_column_loops(parsed, 370 outermost_o_ancestor, opening_pos, closing_pos) 416 371 417 372 # check if this table's headers were already processed … … 427 382 'same columns across all lines.') 428 383 else: 429 # compute splits: we need to split any column header 430 # which is repeated so many times that it encompass 431 # any of the column headers that we need to repeat 384 # compute splits: oo collapses the headers of adjacent 385 # columns which use the same style. We need to split 386 # any column header which is repeated so many times 387 # that it encompasses any of the column headers that 388 # we need to repeat 432 389 to_split = [] 433 390 idx = 0 … … 450 407 table_node[tag_pos:tag_pos+1] = new_tags 451 408 452 # compute moves and deletes: the column headers 453 # corresponding to the opening and closing tags 454 # need to be deleted. The column headers between them 455 # need to be moved to inside the "repeat" tag (which 456 # is to be created later). 409 # recompute the list of column headers as it could 410 # have changed. 457 411 coldefs = list(table_node.iterchildren(table_col_tag)) 412 413 # compute the column header nodes corresponding to 414 # the opening and closing tags. 458 415 first = table_node[opening_pos] 459 416 last = table_node[closing_pos] 460 417 461 # execute moves (add a <relatorio:repeat> node around462 # the column definitions nodes)418 # add a <relatorio:repeat> node around the column 419 # definitions nodes 463 420 attribs = { 464 421 "opening": str(opening_pos), … … 485 442 else: 486 443 # It's not a genshi statement it's a python expression 487 r_node.attrib[ genshi_replace] = expr444 r_node.attrib[py_replace] = expr 488 445 parent = r_node.getparent().getparent() 489 446 if parent is None or parent.tag != table_cell_tag: … … 497 454 parent.attrib.pop(office_valuetype, None) 498 455 parent.attrib.pop(office_name, None) 456 457 def _handle_row_spanned_column_loops(self, parsed, outer_o_node, 458 opening_pos, closing_pos): 459 _, directive, attr, a_val = parsed 460 table_rowspan_attr = '{%s}number-rows-spanned' \ 461 % self.namespaces['table'] 462 rows_spanned = int(outer_o_node.attrib.get(table_rowspan_attr, 1)) 463 464 # checks wether there is a (meaningful) rowspan 465 if rows_spanned == 1: 466 return a_val 467 468 py_namespace = self.namespaces['py'] 469 table_namespace = self.namespaces['table'] 470 table_row_tag = '{%s}table-row' % table_namespace 471 table_cov_cell_tag = '{%s}covered-table-cell' % table_namespace 472 473 # if so, we need to: 474 475 # 1) create a with node to define a temporary variable 476 temp_var = "__relatorio_temp%d" % id(outer_o_node) 477 # a_val == "target in iterable" 478 target, iterable = a_val.split(' in ', 1) 479 vars = "%s = list(%s)" % (temp_var, iterable.strip()) 480 with_node = EtreeElement('{%s}with' % py_namespace, 481 attrib={"vars": vars}, 482 nsmap=self.namespaces) 483 484 # 2) transform a_val to use that temporary variable 485 a_val = "%s in %s" % (target, temp_var) 486 487 # 3) wrap the corresponding cells on the next row(s) 488 # (those should be covered-table-cell) inside a 489 # duplicate py:for node (looping on the temporary 490 # variable). 491 row_node = outer_o_node.getparent() 492 row_node.addprevious(with_node) 493 rows_to_wrap = [row_node] 494 assert row_node.tag == table_row_tag 495 next_rows = row_node.itersiblings(table_row_tag) 496 for row_idx in range(rows_spanned-1): 497 next_row_node = next_rows.next() 498 rows_to_wrap.append(next_row_node) 499 # compute the start and end nodes 500 first = next_row_node[opening_pos] 501 last = next_row_node[closing_pos] 502 assert first.tag == table_cov_cell_tag 503 assert last.tag == table_cov_cell_tag 504 # wrap them 505 tag = '{%s}%s' % (py_namespace, directive) 506 for_node = EtreeElement(tag, 507 attrib={attr: a_val}, 508 nsmap=self.namespaces) 509 wrap_nodes_between(first, last, for_node) 510 511 # 4) wrap all the corresponding rows indide the "with" 512 # node 513 for node in rows_to_wrap: 514 with_node.append(node) 515 return a_val 499 516 500 517 def _handle_images(self, tree): … … 527 544 528 545 counter = ColumnCounter() 529 kwargs['__re set_col_count'] = counter.reset530 kwargs['__ inc_col_count'] = counter.inc531 kwargs['__ store_col_count'] = counter.store546 kwargs['__relatorio_reset_col_count'] = counter.reset 547 kwargs['__relatorio_inc_col_count'] = counter.inc 548 kwargs['__relatorio_store_col_count'] = counter.store 532 549 533 550 stream = super(Template, self).generate(*args, **kwargs)
