| OLD | NEW | 
|    1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |    1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. | 
|    2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |    2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr | 
|    3 # |    3 # | 
|    4 # This file is part of logilab-common. |    4 # This file is part of logilab-common. | 
|    5 # |    5 # | 
|    6 # logilab-common is free software: you can redistribute it and/or modify it unde
     r |    6 # logilab-common is free software: you can redistribute it and/or modify it unde
     r | 
|    7 # the terms of the GNU Lesser General Public License as published by the Free |    7 # the terms of the GNU Lesser General Public License as published by the Free | 
|    8 # Software Foundation, either version 2.1 of the License, or (at your option) an
     y |    8 # Software Foundation, either version 2.1 of the License, or (at your option) an
     y | 
|    9 # later version. |    9 # later version. | 
|   10 # |   10 # | 
|   11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT |   11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT | 
|   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
|   13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more |   13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more | 
|   14 # details. |   14 # details. | 
|   15 # |   15 # | 
|   16 # You should have received a copy of the GNU Lesser General Public License along |   16 # You should have received a copy of the GNU Lesser General Public License along | 
|   17 # with logilab-common.  If not, see <http://www.gnu.org/licenses/>. |   17 # with logilab-common.  If not, see <http://www.gnu.org/licenses/>. | 
|   18 """HTML formatting drivers for ureports""" |   18 """HTML formatting drivers for ureports""" | 
|   19 __docformat__ = "restructuredtext en" |   19 __docformat__ = "restructuredtext en" | 
|   20  |   20  | 
|   21 from cgi import escape |   21 from cgi import escape | 
|   22  |   22  | 
 |   23 from six.moves import range | 
 |   24  | 
|   23 from logilab.common.ureports import BaseWriter |   25 from logilab.common.ureports import BaseWriter | 
|   24  |   26  | 
|   25  |   27  | 
|   26 class HTMLWriter(BaseWriter): |   28 class HTMLWriter(BaseWriter): | 
|   27     """format layouts as HTML""" |   29     """format layouts as HTML""" | 
|   28  |   30  | 
|   29     def __init__(self, snippet=None): |   31     def __init__(self, snippet=None): | 
|   30         super(HTMLWriter, self).__init__() |   32         super(HTMLWriter, self).__init__() | 
|   31         self.snippet = snippet |   33         self.snippet = snippet | 
|   32  |   34  | 
|   33     def handle_attrs(self, layout): |   35     def handle_attrs(self, layout): | 
|   34         """get an attribute string from layout member attributes""" |   36         """get an attribute string from layout member attributes""" | 
|   35         attrs = '' |   37         attrs = u'' | 
|   36         klass = getattr(layout, 'klass', None) |   38         klass = getattr(layout, 'klass', None) | 
|   37         if klass: |   39         if klass: | 
|   38             attrs += ' class="%s"' % klass |   40             attrs += u' class="%s"' % klass | 
|   39         nid = getattr(layout, 'id', None) |   41         nid = getattr(layout, 'id', None) | 
|   40         if nid: |   42         if nid: | 
|   41             attrs += ' id="%s"' % nid |   43             attrs += u' id="%s"' % nid | 
|   42         return attrs |   44         return attrs | 
|   43  |   45  | 
|   44     def begin_format(self, layout): |   46     def begin_format(self, layout): | 
|   45         """begin to format a layout""" |   47         """begin to format a layout""" | 
|   46         super(HTMLWriter, self).begin_format(layout) |   48         super(HTMLWriter, self).begin_format(layout) | 
|   47         if self.snippet is None: |   49         if self.snippet is None: | 
|   48             self.writeln('<html>') |   50             self.writeln(u'<html>') | 
|   49             self.writeln('<body>') |   51             self.writeln(u'<body>') | 
|   50  |   52  | 
|   51     def end_format(self, layout): |   53     def end_format(self, layout): | 
|   52         """finished to format a layout""" |   54         """finished to format a layout""" | 
|   53         if self.snippet is None: |   55         if self.snippet is None: | 
|   54             self.writeln('</body>') |   56             self.writeln(u'</body>') | 
|   55             self.writeln('</html>') |   57             self.writeln(u'</html>') | 
|   56  |   58  | 
|   57  |   59  | 
|   58     def visit_section(self, layout): |   60     def visit_section(self, layout): | 
|   59         """display a section as html, using div + h[section level]""" |   61         """display a section as html, using div + h[section level]""" | 
|   60         self.section += 1 |   62         self.section += 1 | 
|   61         self.writeln('<div%s>' % self.handle_attrs(layout)) |   63         self.writeln(u'<div%s>' % self.handle_attrs(layout)) | 
|   62         self.format_children(layout) |   64         self.format_children(layout) | 
|   63         self.writeln('</div>') |   65         self.writeln(u'</div>') | 
|   64         self.section -= 1 |   66         self.section -= 1 | 
|   65  |   67  | 
|   66     def visit_title(self, layout): |   68     def visit_title(self, layout): | 
|   67         """display a title using <hX>""" |   69         """display a title using <hX>""" | 
|   68         self.write('<h%s%s>' % (self.section, self.handle_attrs(layout))) |   70         self.write(u'<h%s%s>' % (self.section, self.handle_attrs(layout))) | 
|   69         self.format_children(layout) |   71         self.format_children(layout) | 
|   70         self.writeln('</h%s>' % self.section) |   72         self.writeln(u'</h%s>' % self.section) | 
|   71  |   73  | 
|   72     def visit_table(self, layout): |   74     def visit_table(self, layout): | 
|   73         """display a table as html""" |   75         """display a table as html""" | 
|   74         self.writeln('<table%s>' % self.handle_attrs(layout)) |   76         self.writeln(u'<table%s>' % self.handle_attrs(layout)) | 
|   75         table_content = self.get_table_content(layout) |   77         table_content = self.get_table_content(layout) | 
|   76         for i in range(len(table_content)): |   78         for i in range(len(table_content)): | 
|   77             row = table_content[i] |   79             row = table_content[i] | 
|   78             if i == 0 and layout.rheaders: |   80             if i == 0 and layout.rheaders: | 
|   79                 self.writeln('<tr class="header">') |   81                 self.writeln(u'<tr class="header">') | 
|   80             elif i+1 == len(table_content) and layout.rrheaders: |   82             elif i+1 == len(table_content) and layout.rrheaders: | 
|   81                 self.writeln('<tr class="header">') |   83                 self.writeln(u'<tr class="header">') | 
|   82             else: |   84             else: | 
|   83                 self.writeln('<tr class="%s">' % (i%2 and 'even' or 'odd')) |   85                 self.writeln(u'<tr class="%s">' % (i%2 and 'even' or 'odd')) | 
|   84             for j in range(len(row)): |   86             for j in range(len(row)): | 
|   85                 cell = row[j] or ' ' |   87                 cell = row[j] or u' ' | 
|   86                 if (layout.rheaders and i == 0) or \ |   88                 if (layout.rheaders and i == 0) or \ | 
|   87                    (layout.cheaders and j == 0) or \ |   89                    (layout.cheaders and j == 0) or \ | 
|   88                    (layout.rrheaders and i+1 == len(table_content)) or \ |   90                    (layout.rrheaders and i+1 == len(table_content)) or \ | 
|   89                    (layout.rcheaders and j+1 == len(row)): |   91                    (layout.rcheaders and j+1 == len(row)): | 
|   90                     self.writeln('<th>%s</th>' % cell) |   92                     self.writeln(u'<th>%s</th>' % cell) | 
|   91                 else: |   93                 else: | 
|   92                     self.writeln('<td>%s</td>' % cell) |   94                     self.writeln(u'<td>%s</td>' % cell) | 
|   93             self.writeln('</tr>') |   95             self.writeln(u'</tr>') | 
|   94         self.writeln('</table>') |   96         self.writeln(u'</table>') | 
|   95  |   97  | 
|   96     def visit_list(self, layout): |   98     def visit_list(self, layout): | 
|   97         """display a list as html""" |   99         """display a list as html""" | 
|   98         self.writeln('<ul%s>' % self.handle_attrs(layout)) |  100         self.writeln(u'<ul%s>' % self.handle_attrs(layout)) | 
|   99         for row in list(self.compute_content(layout)): |  101         for row in list(self.compute_content(layout)): | 
|  100             self.writeln('<li>%s</li>' % row) |  102             self.writeln(u'<li>%s</li>' % row) | 
|  101         self.writeln('</ul>') |  103         self.writeln(u'</ul>') | 
|  102  |  104  | 
|  103     def visit_paragraph(self, layout): |  105     def visit_paragraph(self, layout): | 
|  104         """display links (using <p>)""" |  106         """display links (using <p>)""" | 
|  105         self.write('<p>') |  107         self.write(u'<p>') | 
|  106         self.format_children(layout) |  108         self.format_children(layout) | 
|  107         self.write('</p>') |  109         self.write(u'</p>') | 
|  108  |  110  | 
|  109     def visit_span(self, layout): |  111     def visit_span(self, layout): | 
|  110         """display links (using <p>)""" |  112         """display links (using <p>)""" | 
|  111         self.write('<span%s>' % self.handle_attrs(layout)) |  113         self.write(u'<span%s>' % self.handle_attrs(layout)) | 
|  112         self.format_children(layout) |  114         self.format_children(layout) | 
|  113         self.write('</span>') |  115         self.write(u'</span>') | 
|  114  |  116  | 
|  115     def visit_link(self, layout): |  117     def visit_link(self, layout): | 
|  116         """display links (using <a>)""" |  118         """display links (using <a>)""" | 
|  117         self.write(' <a href="%s"%s>%s</a>' % (layout.url, |  119         self.write(u' <a href="%s"%s>%s</a>' % (layout.url, | 
|  118                                                self.handle_attrs(layout), |  120                                                 self.handle_attrs(layout), | 
|  119                                                layout.label)) |  121                                                 layout.label)) | 
|  120     def visit_verbatimtext(self, layout): |  122     def visit_verbatimtext(self, layout): | 
|  121         """display verbatim text (using <pre>)""" |  123         """display verbatim text (using <pre>)""" | 
|  122         self.write('<pre>') |  124         self.write(u'<pre>') | 
|  123         self.write(layout.data.replace('&', '&').replace('<', '<')) |  125         self.write(layout.data.replace(u'&', u'&').replace(u'<', u'<')) | 
|  124         self.write('</pre>') |  126         self.write(u'</pre>') | 
|  125  |  127  | 
|  126     def visit_text(self, layout): |  128     def visit_text(self, layout): | 
|  127         """add some text""" |  129         """add some text""" | 
|  128         data = layout.data |  130         data = layout.data | 
|  129         if layout.escaped: |  131         if layout.escaped: | 
|  130             data = data.replace('&', '&').replace('<', '<') |  132             data = data.replace(u'&', u'&').replace(u'<', u'<') | 
|  131         self.write(data) |  133         self.write(data) | 
| OLD | NEW |