# vim: fileencoding=utf-8 # from .base_format import BaseFormat from collections import OrderedDict from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\ OneOrMore, alphanums, ParseException, restOfLine,\ pyparsing_unicode, Group, Optional class CompizFormat(BaseFormat): def __init__(self, document_text: str, ignore_comments=False): processing_methods = [self._parse_comment_line, self._parse_section_line, self._parse_parameter_line, self._parse_to_delete_line] super().__init__(processing_methods) self._ignore_comments = ignore_comments self._comments_processing = True self._need_finish = True self._format = 'compiz' self._current_section = OrderedDict() self._current_section_name = '' self._last_comments_list = [] self._initialize_parser() if document_text == '': self._document_dictionary = OrderedDict() else: document_lines = self._get_list_of_logic_lines(document_text) self._lines_to_dictionary(document_lines) def _initialize_parser(self): section_name = originalTextFor( OneOrMore(Word(alphanums+'_')) ) action_symbols = (Literal('!') | Literal('-')) self._section_line = (Literal('[').suppress() + Optional(action_symbols, default='')('action') + section_name('name') + Literal(']').suppress())('section_name') parameter_name = originalTextFor( OneOrMore(Word(printables, excludeChars='=')) ) parameter_value = Word(printables) self._parameter_line = (Group(Optional(action_symbols, default='')('action') + parameter_name('name') )('parameter_name') + Literal('=').suppress() + parameter_value('parameter_value')) self._parameter_to_delete = (action_symbols('action') + parameter_name('name') + restOfLine.suppress())('parameter_name') self._comment_line = originalTextFor( Literal('#') + ZeroOrMore(Word(printables + pyparsing_unicode.alphanums)) )('comment') def _parse_section_line(self, line): try: self._item_to_add = OrderedDict() parsing_result = self._section_line.parseString(line) self._match = True if self._current_section_name != '': if self._current_section_name in \ self._document_dictionary.keys(): self._document_dictionary[self._current_section_name].\ update(self._current_section) self._current_section = OrderedDict() else: self._item_to_add[self._current_section_name] = \ self._current_section self._current_section = OrderedDict() self._ready_to_update = True self._current_section_name = tuple( parsing_result.section_name.asList() ) if self._last_comments_list != []: self._current_section['#'] = self._last_comments_list self._last_comments_list = [] except ParseException: return def _parse_parameter_line(self, line): try: parsing_result = self._parameter_line.parseString(line) self._match = True key_value = tuple(parsing_result.parameter_name.asList()) parameter_value = parsing_result.parameter_value parameter_value = self._last_comments_list + [parameter_value] self._last_comments_list = [] self._current_section[key_value] = parameter_value except ParseException: return def _parse_to_delete_line(self, line): try: parsing_result = self._parameter_to_delete.parseString(line) self._match = True if parsing_result.action == '-': return key_value = tuple(parsing_result.parameter_name.asList()) parameter_value = self._last_comments_list self._last_comments_list = [] self._current_section[key_value] = parameter_value except ParseException: return def _parse_comment_line(self, line): try: parsing_result = self._comment_line.parseString(line) self._match = True if not self._ignore_comments: self._last_comments_list.append(parsing_result.comment) except ParseException: return def _finish_method(self): if self._current_section_name in self._document_dictionary.keys(): self._document_dictionary[self._current_section_name].update( self._current_section ) else: self._item_to_add[self._current_section_name] =\ self._current_section self._document_dictionary.update(self._item_to_add) self._current_section = OrderedDict()