1 """Universal report objects and some formatting drivers.
2
3 A way to create simple reports using python objects, primarily designed to be
4 formatted as text and html.
5
6 :copyright:
7 2004-2008 `LOGILAB S.A. <http://www.logilab.fr>`_ (Paris, FRANCE),
8 all rights reserved.
9
10 :contact:
11 http://www.logilab.org/project/logilab-common --
12 mailto:python-projects@logilab.org
13
14 :license:
15 `General Public License version 2
16 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>`_
17 """
18 from __future__ import generators
19 __docformat__ = "restructuredtext en"
20
21 import sys
22 from cStringIO import StringIO
23 from StringIO import StringIO as UStringIO
24
25 from logilab.common.textutils import linesep
26
27
29 """return an iterator on all children node of the given klass"""
30 for child in node.children:
31 if isinstance(child, klass):
32 yield child
33
34 for grandchild in get_nodes(child, klass):
35 yield grandchild
36
38 """try to return the layout's title as string, return None if not found
39 """
40 for child in layout.children:
41 if isinstance(child, Title):
42 return ' '.join([node.data for node in get_nodes(child, Text)])
43
45 """make a summary for the report, including X level"""
46 assert level > 0
47 level -= 1
48 summary = List(klass='summary')
49 for child in layout.children:
50 if not isinstance(child, Section):
51 continue
52 label = layout_title(child)
53 if not label and not child.id:
54 continue
55 if not child.id:
56 child.id = label.replace(' ', '-')
57 node = Link('#'+child.id, label=label or child.id)
58
59
60
61
62 if level and [n for n in child.children if isinstance(n, Section)]:
63 node = Paragraph([node, build_summary(child, level)])
64 summary.append(node)
65
66
67
68 return summary
69
70
72 """base class for ureport writers"""
73
91
98
100 """write a line in the output buffer"""
101 self.write(string + linesep)
102
103 - def write(self, string):
104 """write a string in the output buffer"""
105 try:
106 self.out.write(string)
107 except UnicodeEncodeError:
108 self.out.write(string.encode(self.encoding))
109
113
116
117 - def get_table_content(self, table):
118 """trick to get table content without actually writing it
119
120 return an aligned list of lists containing table cells values as string
121 """
122 result = [[]]
123 cols = table.cols
124 for cell in self.compute_content(table):
125 if cols == 0:
126 result.append([])
127 cols = table.cols
128 cols -= 1
129 result[-1].append(cell)
130
131 while len(result[-1]) < cols:
132 result[-1].append('')
133 return result
134
135 - def compute_content(self, layout):
136 """trick to compute the formatting of children layout before actually
137 writing it
138
139 return an iterator on strings (one for each child element)
140 """
141
142 def write(data):
143 try:
144 stream.write(data)
145 except UnicodeEncodeError:
146 stream.write(data.encode(self.encoding))
147 def writeln(data=''):
148 try:
149 stream.write(data+linesep)
150 except UnicodeEncodeError:
151 stream.write(data.encode(self.encoding)+linesep)
152 self.write = write
153 self.writeln = writeln
154 self.__compute_funcs.append((write, writeln))
155 for child in layout.children:
156 stream = UStringIO()
157 child.accept(self)
158 yield stream.getvalue()
159 self.__compute_funcs.pop()
160 try:
161 self.write, self.writeln = self.__compute_funcs[-1]
162 except IndexError:
163 del self.write
164 del self.writeln
165
166
167 from logilab.common.ureports.nodes import *
168 from logilab.common.ureports.text_writer import TextWriter
169 from logilab.common.ureports.html_writer import HTMLWriter
170