Source code for robot.writer.rowsplitter

#  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
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import itertools


[docs]class RowSplitter(object): _comment_mark = '#' _empty_cell_escape = '${EMPTY}' _line_continuation = '...' _setting_table = 'setting' _indented_tables = ('test case', 'keyword') _split_from = ('ELSE', 'ELSE IF', 'AND') def __init__(self, cols=8, split_multiline_doc=True): self._cols = cols self._split_multiline_doc = split_multiline_doc
[docs] def split(self, row, table_type): if not row: return self._split_empty_row() indent = self._get_indent(row, table_type) if self._split_multiline_doc and self._is_doc_row(row, table_type): return self._split_doc_row(row, indent) return self._split_row(row, indent)
def _split_empty_row(self): yield [] def _get_indent(self, row, table_type): indent = self._get_first_non_empty_index(row) min_indent = 1 if table_type in self._indented_tables else 0 return max(indent, min_indent) def _get_first_non_empty_index(self, row, indented=False): ignore = ['', '...'] if indented else [''] return len(list(itertools.takewhile(lambda x: x in ignore, row))) def _is_doc_row(self, row, table_type): if table_type == self._setting_table: return len(row) > 1 and row[0] == 'Documentation' if table_type in self._indented_tables: return len(row) > 2 and row[1] == '[Documentation]' return False def _split_doc_row(self, row, indent): first, rest = self._split_doc(row[indent+1]) yield row[:indent+1] + [first] + row[indent+2:] while rest: current, rest = self._split_doc(rest) row = [current] if current else [] yield self._continue_row(row, indent) def _split_doc(self, doc): if '\\n' not in doc: return doc, '' if '\\n ' in doc: doc = doc.replace('\\n ', '\\n') return doc.split('\\n', 1) def _split_row(self, row, indent): while row: current, row = self._split(row) yield self._escape_last_cell_if_empty(current) if row: row = self._continue_row(row, indent) def _split(self, data): index = min(self._get_possible_split_indices(data)) current, rest = data[:index], data[index:] rest = self._comment_rest_if_needed(current, rest) return current, rest def _get_possible_split_indices(self, data): min_index = self._get_first_non_empty_index(data, indented=True) + 1 for marker in self._split_from: if marker in data[min_index:]: yield data[min_index:].index(marker) + min_index yield self._cols def _comment_rest_if_needed(self, current, rest): if rest and any(c.startswith(self._comment_mark) for c in current) \ and not rest[0].startswith(self._comment_mark): rest = [self._comment_mark + ' ' + rest[0]] + rest[1:] return rest def _escape_last_cell_if_empty(self, row): if row and not row[-1].strip(): row = row[:-1] + [self._empty_cell_escape] return row def _continue_row(self, row, indent): row = [self._line_continuation] + row if indent + 1 < self._cols: row = [''] * indent + row return row