import operator from prettytoml import tokens from prettytoml.prettifier import common from prettytoml.elements import traversal as t, factory as element_factory from prettytoml.elements.array import ArrayElement from prettytoml.elements.atomic import AtomicElement from prettytoml.elements.inlinetable import InlineTableElement from prettytoml.elements.table import TableElement from functools import * MAXIMUM_LINE_LENGTH = 120 def line_length_limiter(toml_file_elements): """ Rule: Lines whose lengths exceed 120 characters whose values are strings, arrays should have the array or string value broken onto multiple lines """ return tuple(_fixed_table(e) if isinstance(e, TableElement) else e for e in toml_file_elements) def _fixed_table(table_element): """ Returns a new TableElement. """ assert isinstance(table_element, TableElement) lines = tuple(common.lines(table_element.sub_elements)) fixed_lines = tuple(_fixed_line(l) if _line_length(l) > MAXIMUM_LINE_LENGTH else l for l in lines) return TableElement(sub_elements=tuple(reduce(operator.concat, fixed_lines))) def _line_length(line_elements): """ Returns the character length of the serialized elements of the given line. """ return sum(len(e.serialized()) for e in line_elements) def _fixed_line(line_elements): def line_value_index(): # Returns index of value element in the line key_index = t.find_following(line_elements, t.predicates.non_metadata) return t.find_following(line_elements, t.predicates.non_metadata, key_index) def multiline_equivalent(element): if isinstance(element, AtomicElement) and tokens.is_string(element.first_token): return element_factory.create_multiline_string(element.value, MAXIMUM_LINE_LENGTH) elif isinstance(element, ArrayElement): element.turn_into_multiline() return element else: return element line_elements = tuple(line_elements) value_index = line_value_index() if value_index >= 0: return line_elements[:value_index] + (multiline_equivalent(line_elements[value_index]),) + \ line_elements[value_index+1:] else: return line_elements