Source code for robot.writer.htmlformatter

#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  See the License for the specific language governing permissions and
#  limitations under the License.

import re

from robot import utils

from .formatters import _DataFileFormatter

[docs]class HtmlFormatter(_DataFileFormatter): _split_multiline_doc = False def _format_row(self, row, table=None): row = self._pad(self._escape_consecutive_whitespace(row), table) if self._is_documentation_row(row): return self._create_documentation_row(row) first_cell = self._create_first_cell(row[0], table) if self._is_indented_documentation_row(row[1:], table): return self._create_indented_documentation_row(first_cell, row[1:]) return [first_cell] + [HtmlCell(c) for c in row[1:]] def _is_documentation_row(self, row): return row[0] == 'Documentation' def _create_documentation_row(self, row): return [NameCell(row[0]), DocumentationCell(row[1], span=self._column_count-1)] def _is_indented_documentation_row(self, cells, table): return self._is_indented_table(table) and cells and \ cells[0] == '[Documentation]' def _create_indented_documentation_row(self, first_cell, cells): start = [first_cell, HtmlCell(cells[0])] if any(c.startswith('#') for c in cells): return start + [HtmlCell(c) for c in cells[1:]] return start + [DocumentationCell(cells[1], self._column_count-2)] def _create_first_cell(self, cell, table): if self._is_indented_table(table) and cell: return AnchorNameCell(cell, 'keyword' if table.type == 'keyword' else 'test') return NameCell(cell)
[docs] def format_header(self, table): if not self._should_align_columns(table) or len(table.header) == 1: return [HeaderCell(table.header[0], self._column_count)] headers = self._pad_header(table) return [HeaderCell(hdr) for hdr in headers]
def _pad_header(self, table): header = table.header return header + [''] * (self._get_column_count(table) - len(header)) def _pad(self, row, table): return row + [''] * (self._get_column_count(table) - len(row)) def _get_column_count(self, table): if table is None or len(table.header) == 1 \ or not self._is_indented_table(table): return self._column_count return max(self._max_column_count(table), len(table.header)) def _max_column_count(self, table): count = 0 for item in table: for child in item: count = max(count, len(child.as_list()) + 1) return count
[docs]class HtmlCell(object): _backslash_matcher = re.compile(r'(\\+)n ?') def __init__(self, content='', attributes=None, tag='td', escape=True): if escape: content = utils.html_escape(content) self.content = self._replace_newlines(content) self.attributes = attributes or {} self.tag = tag def _replace_newlines(self, content): def replacer(match): backslash_count = len( if backslash_count % 2 == 1: return '%sn<br>\n' % return return self._backslash_matcher.sub(replacer, content)
[docs]class NameCell(HtmlCell): def __init__(self, name='', attributes=None): HtmlCell.__init__(self, name, {'class': 'name'})
[docs]class AnchorNameCell(HtmlCell): def __init__(self, name, type_): HtmlCell.__init__(self, self._link_from_name(name, type_), {'class': 'name'}, escape=False) def _link_from_name(self, name, type_): return '<a name="%s_%s">%s</a>' % (type_, utils.attribute_escape(name), utils.html_escape(name))
[docs]class DocumentationCell(HtmlCell): def __init__(self, content, span): HtmlCell.__init__(self, content, {'class': 'colspan%d' % span, 'colspan': '%d' % span})
[docs]class HeaderCell(HtmlCell): def __init__(self, name, span=1): HtmlCell.__init__(self, name, {'class': 'name', 'colspan': '%d' % span}, tag='th')