00001 from silme.core.entity import EntityList, Entity
00002 from structure import *
00003 import re
00004
00005 class PropertiesParser():
00006 patterns = {}
00007 patterns['entity'] = re.compile('^[ \t]*([^#!\s\n][^=:\n]*?)[ \t]*[:=][ \t]*(.*?)(?<!\\\)(?=\n|\Z)',re.S|re.M)
00008 patterns['comment'] = re.compile('^(#[^\n]*\n?)+',re.M|re.S)
00009
00010
00011 @classmethod
00012 def parse(cls, text, code='default'):
00013 prop = PropertiesStructure()
00014 cls.build_element_list(text, prop, code=code)
00015 prop.fallback = code
00016 return prop
00017
00018
00019 @classmethod
00020 def parse_to_entitylist(cls, text, code='default'):
00021 entitylist = EntityList()
00022 text = cls.patterns['comment'].sub('', text)
00023 matchlist = cls.patterns['entity'].findall(text)
00024 for match in matchlist:
00025 entitylist.add_entity(Entity(match[0], match[1], code))
00026 return entitylist
00027
00028 @classmethod
00029 def parse_entity(cls, text, code='default'):
00030 match = self.patterns['entity'].match(text)
00031 if not match:
00032 raise Exception()
00033 entity = Entity(match.group(1))
00034 entity.set_value(match.group(2), code=code)
00035 return entity
00036
00037 @classmethod
00038 def build_element_list (cls, text, object, type='comment', code='default', pointer=0, end=None):
00039 cls.split_comments(text, object, code=code)
00040
00041 @classmethod
00042 def split_comments(cls, text, object, code='default', pointer=0, end=None):
00043 pattern = cls.patterns['comment']
00044 if end:
00045 match = pattern.search(text, pointer, end)
00046 else:
00047 match = pattern.search(text, pointer)
00048 while match:
00049 st0 = match.start(0)
00050 if st0 > pointer:
00051 cls.split_entities(text, object, code=code, pointer=pointer, end=st0)
00052 groups = match.groups()
00053 comment = Comment()
00054 cls.split_entities(match.group(0)[1:].replace('\n#','\n'), comment, code=code)
00055 object.append(comment)
00056 pointer = match.end(0)
00057 if end:
00058 match = pattern.search(text, pointer, end)
00059 else:
00060 match = pattern.search(text, pointer)
00061 if (not end or (end > pointer)) and len(text) > pointer:
00062 cls.split_entities(text, object, code=code, pointer=pointer)
00063
00064 @classmethod
00065 def split_entities(cls, text, object, code='default', pointer=0, end=None):
00066 pattern = cls.patterns['entity']
00067 if end:
00068 match = pattern.search(text, pointer, end)
00069 else:
00070 match = pattern.search(text, pointer)
00071 while match:
00072 st0 = match.start(0)
00073 if st0 > pointer:
00074 object.append(text[pointer:st0])
00075 groups = match.groups()
00076 entity = Entity(groups[0])
00077 entity.set_value(groups[1], code)
00078 entity.params['source'] = {'type':'properties',
00079 'string':match.group(0),
00080 'valpos':match.start(2)-st0}
00081 object.append(entity)
00082 pointer = match.end(0)
00083 if end:
00084 match = pattern.search(text, pointer, end)
00085 else:
00086 match = pattern.search(text, pointer)
00087 if (not end or (end > pointer)) and len(text) > pointer:
00088 if end:
00089 object.append(text[pointer:end])
00090 else:
00091 object.append(text[pointer:])