1 """Text formatting drivers for ureports.
2
3 :copyright:
4 2004-2008 `LOGILAB S.A. <http://www.logilab.fr>`_ (Paris, FRANCE),
5 all rights reserved.
6
7 :contact:
8 http://www.logilab.org/project/logilab-common --
9 mailto:python-projects@logilab.org
10
11 :license:
12 `General Public License version 2
13 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>`_
14 """
15 __docformat__ = "restructuredtext en"
16
17 from logilab.common.textutils import linesep
18 from logilab.common.ureports import BaseWriter
19
20
21 TITLE_UNDERLINES = ['', '=', '-', '`', '.', '~', '^']
22 BULLETS = ['*', '-']
23
24 -class TextWriter(BaseWriter):
25 """format layouts as text
26 (ReStructured inspiration but not totally handled yet)
27 """
32
33 - def visit_section(self, layout):
34 """display a section as text
35 """
36 self.section += 1
37 self.writeln()
38 self.format_children(layout)
39 if self.pending_urls:
40 self.writeln()
41 for label, url in self.pending_urls:
42 self.writeln('.. _`%s`: %s' % (label, url))
43 self.pending_urls = []
44 self.section -= 1
45 self.writeln()
46
47 - def visit_title(self, layout):
48 title = ''.join(list(self.compute_content(layout)))
49 self.writeln(title)
50 try:
51 self.writeln(TITLE_UNDERLINES[self.section] * len(title))
52 except IndexError:
53 print "FIXME TITLE TOO DEEP. TURNING TITLE INTO TEXT"
54
55 - def visit_paragraph(self, layout):
56 """enter a paragraph"""
57 self.format_children(layout)
58 self.writeln()
59
60 - def visit_span(self, layout):
61 """enter a span"""
62 self.format_children(layout)
63
64 - def visit_table(self, layout):
65 """display a table as text"""
66 table_content = self.get_table_content(layout)
67
68 cols_width = [0]*len(table_content[0])
69 for row in table_content:
70 for index in range(len(row)):
71 col = row[index]
72 cols_width[index] = max(cols_width[index], len(col))
73 if layout.klass == 'field':
74 self.field_table(layout, table_content, cols_width)
75 else:
76 self.default_table(layout, table_content, cols_width)
77 self.writeln()
78
79 - def default_table(self, layout, table_content, cols_width):
80 """format a table"""
81 cols_width = [size+1 for size in cols_width]
82 format_strings = ' '.join(['%%-%ss'] * len(cols_width))
83 format_strings = format_strings % tuple(cols_width)
84 format_strings = format_strings.split(' ')
85 table_linesep = '\n+' + '+'.join(['-'*w for w in cols_width]) + '+\n'
86 headsep = '\n+' + '+'.join(['='*w for w in cols_width]) + '+\n'
87
88 self.write(table_linesep)
89 for i in range(len(table_content)):
90 self.write('|')
91 line = table_content[i]
92 for j in range(len(line)):
93 self.write(format_strings[j] % line[j])
94 self.write('|')
95 if i == 0 and layout.rheaders:
96 self.write(headsep)
97 else:
98 self.write(table_linesep)
99
100 - def field_table(self, layout, table_content, cols_width):
101 """special case for field table"""
102 assert layout.cols == 2
103 format_string = '%s%%-%ss: %%s' % (linesep, cols_width[0])
104 for field, value in table_content:
105 self.write(format_string % (field, value))
106
107
108 - def visit_list(self, layout):
109 """display a list layout as text"""
110 bullet = BULLETS[self.list_level % len(BULLETS)]
111 indent = ' ' * self.list_level
112 self.list_level += 1
113 for child in layout.children:
114 self.write('%s%s%s ' % (linesep, indent, bullet))
115 child.accept(self)
116 self.list_level -= 1
117
118 - def visit_link(self, layout):
119 """add a hyperlink"""
120 if layout.label != layout.url:
121 self.write('`%s`_' % layout.label)
122 self.pending_urls.append( (layout.label, layout.url) )
123 else:
124 self.write(layout.url)
125
126 - def visit_verbatimtext(self, layout):
127 """display a verbatim layout as text (so difficult ;)
128 """
129 self.writeln('::\n')
130 for line in layout.data.splitlines():
131 self.writeln(' ' + line)
132 self.writeln()
133
134 - def visit_text(self, layout):
135 """add some text"""
136 self.write(layout.data)
137