import datetime import functools import six from prettytoml import tokens from prettytoml.tokens import py2toml from prettytoml.elements.atomic import AtomicElement from prettytoml.elements.metadata import PunctuationElement, WhitespaceElement, NewlineElement from prettytoml.elements.tableheader import TableHeaderElement from prettytoml.util import join_with, is_sequence_like def create_element(value, multiline_strings_allowed=True): """ Creates and returns the appropriate elements.Element instance from the given Python primitive, sequence-like, or dict-like value. """ from prettytoml.elements.array import ArrayElement if isinstance(value, (int, float, bool, datetime.datetime, datetime.date) + six.string_types) or value is None: primitive_token = py2toml.create_primitive_token(value, multiline_strings_allowed=multiline_strings_allowed) return AtomicElement((primitive_token,)) elif isinstance(value, (list, tuple)): preamble = [create_operator_element('[')] postable = [create_operator_element(']')] stuffing_elements = [create_element(v) for v in value] spaced_stuffing = join_with(stuffing_elements, separator=[create_operator_element(','), create_whitespace_element()]) return ArrayElement(preamble + spaced_stuffing + postable) elif isinstance(value, dict): return create_inline_table(value, multiline_table=False, multiline_strings_allowed=multiline_strings_allowed) else: raise RuntimeError('Value type unaccounted for: {} of type {}'.format(value, type(value))) def create_inline_table(from_dict, multiline_table=False, multiline_strings_allowed=True): """ Creates an InlineTable element from the given dict instance. """ from prettytoml.elements.inlinetable import InlineTableElement preamble = [create_operator_element('{')] postable = [create_operator_element('}')] stuffing_elements = ( ( create_string_element(k, bare_allowed=True), create_whitespace_element(), create_operator_element('='), create_whitespace_element(), create_element(v, multiline_strings_allowed=False) ) for (k, v) in from_dict.items()) pair_separator = [create_operator_element(','), create_newline_element() if multiline_table else create_whitespace_element()] spaced_elements = join_with(stuffing_elements, separator=pair_separator) return InlineTableElement(preamble + spaced_elements + postable) def create_string_element(value, bare_allowed=False): """ Creates and returns an AtomicElement wrapping a string value. """ return AtomicElement((py2toml.create_string_token(value, bare_allowed),)) def create_operator_element(operator): """ Creates a PunctuationElement instance containing an operator token of the specified type. The operator should be a TOML source str. """ operator_type_map = { ',': tokens.TYPE_OP_COMMA, '=': tokens.TYPE_OP_ASSIGNMENT, '[': tokens.TYPE_OP_SQUARE_LEFT_BRACKET, ']': tokens.TYPE_OP_SQUARE_RIGHT_BRACKET, '[[': tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET, ']]': tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET, '{': tokens.TYPE_OP_CURLY_LEFT_BRACKET, '}': tokens.TYPE_OP_CURLY_RIGHT_BRACKET, } ts = (tokens.Token(operator_type_map[operator], operator),) return PunctuationElement(ts) def create_newline_element(): """ Creates and returns a single NewlineElement. """ ts = (tokens.Token(tokens.TYPE_NEWLINE, '\n'),) return NewlineElement(ts) def create_whitespace_element(length=1, char=' '): """ Creates and returns a WhitespaceElement containing spaces. """ ts = (tokens.Token(tokens.TYPE_WHITESPACE, char),) * length return WhitespaceElement(ts) def create_table_header_element(names): name_elements = [] if isinstance(names, six.string_types): name_elements = [py2toml.create_string_token(names, bare_string_allowed=True)] else: for (i, name) in enumerate(names): name_elements.append(py2toml.create_string_token(name, bare_string_allowed=True)) if i < (len(names)-1): name_elements.append(py2toml.operator_token(tokens.TYPE_OPT_DOT)) return TableHeaderElement( [py2toml.operator_token(tokens.TYPE_OP_SQUARE_LEFT_BRACKET)] + name_elements + [py2toml.operator_token(tokens.TYPE_OP_SQUARE_RIGHT_BRACKET), py2toml.operator_token(tokens.TYPE_NEWLINE)], ) def create_array_of_tables_header_element(name): return TableHeaderElement(( py2toml.operator_token(tokens.TYPE_OP_DOUBLE_SQUARE_LEFT_BRACKET), py2toml.create_string_token(name, bare_string_allowed=True), py2toml.operator_token(tokens.TYPE_OP_DOUBLE_SQUARE_RIGHT_BRACKET), py2toml.operator_token(tokens.TYPE_NEWLINE), )) def create_table(dict_value): """ Creates a TableElement out of a dict instance. """ from prettytoml.elements.table import TableElement if not isinstance(dict_value, dict): raise ValueError('input must be a dict instance.') table_element = TableElement([create_newline_element()]) for k, v in dict_value.items(): table_element[k] = create_element(v) return table_element def create_multiline_string(text, maximum_line_length): return AtomicElement(_tokens=[py2toml.create_multiline_string(text, maximum_line_length)])