Source code for logilab.common.ureports.html_writer

# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
#
# logilab-common is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License,
# or (at your option) any later version.
#
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with logilab-common.  If not, see <http://www.gnu.org/licenses/>.
"""HTML formatting drivers for ureports"""
__docformat__ = "restructuredtext en"


from logilab.common.ureports import BaseWriter
from logilab.common.ureports.nodes import (
    Section,
    Title,
    Table,
    List,
    Paragraph,
    Link,
    VerbatimText,
    Text,
)
from typing import Any


[docs]class HTMLWriter(BaseWriter): """format layouts as HTML""" def __init__(self, snippet: int = None) -> None: super(HTMLWriter, self).__init__() self.snippet = snippet
[docs] def handle_attrs(self, layout: Any) -> str: """get an attribute string from layout member attributes""" attrs = "" klass = getattr(layout, "klass", None) if klass: attrs += f' class="{klass}"' nid = getattr(layout, "id", None) if nid: attrs += f' id="{nid}"' return attrs
[docs] def begin_format(self, layout: Any) -> None: """begin to format a layout""" super(HTMLWriter, self).begin_format(layout) if self.snippet is None: self.writeln("<html>") self.writeln("<body>")
[docs] def end_format(self, layout: Any) -> None: """finished to format a layout""" if self.snippet is None: self.writeln("</body>") self.writeln("</html>")
[docs] def visit_section(self, layout: Section) -> None: """display a section as html, using div + h[section level]""" self.section += 1 self.writeln(f"<div{self.handle_attrs(layout)}>") self.format_children(layout) self.writeln("</div>") self.section -= 1
[docs] def visit_title(self, layout: Title) -> None: """display a title using <hX>""" self.write(f"<h{self.section}{self.handle_attrs(layout)}>") self.format_children(layout) self.writeln(f"</h{self.section}>")
[docs] def visit_table(self, layout: Table) -> None: """display a table as html""" self.writeln(f"<table{self.handle_attrs(layout)}>") table_content = self.get_table_content(layout) for i in range(len(table_content)): row = table_content[i] if i == 0 and layout.rheaders: self.writeln('<tr class="header">') elif i + 1 == len(table_content) and layout.rrheaders: self.writeln('<tr class="header">') else: self.writeln('<tr class="%s">' % (i % 2 and "even" or "odd")) for j in range(len(row)): cell = row[j] or "&#160;" if ( (layout.rheaders and i == 0) or (layout.cheaders and j == 0) or (layout.rrheaders and i + 1 == len(table_content)) or (layout.rcheaders and j + 1 == len(row)) ): self.writeln(f"<th>{cell}</th>") else: self.writeln(f"<td>{cell}</td>") self.writeln("</tr>") self.writeln("</table>")
[docs] def visit_list(self, layout: List) -> None: """display a list as html""" self.writeln(f"<ul{self.handle_attrs(layout)}>") for row in list(self.compute_content(layout)): self.writeln(f"<li>{row}</li>") self.writeln("</ul>")
[docs] def visit_paragraph(self, layout: Paragraph) -> None: """display links (using <p>)""" self.write("<p>") self.format_children(layout) self.write("</p>")
[docs] def visit_span(self, layout): """display links (using <p>)""" self.write(f"<span{self.handle_attrs(layout)}>") self.format_children(layout) self.write("</span>")
[docs] def visit_verbatimtext(self, layout: VerbatimText) -> None: """display verbatim text (using <pre>)""" self.write("<pre>") self.write(layout.data.replace("&", "&amp;").replace("<", "&lt;")) self.write("</pre>")
[docs] def visit_text(self, layout: Text) -> None: """add some text""" data = layout.data if layout.escaped: data = data.replace("&", "&amp;").replace("<", "&lt;") self.write(data)