home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / gedit-2 / plugins / snippets / SubstitutionParser.py < prev    next >
Encoding:
Python Source  |  2009-04-14  |  7.3 KB  |  203 lines

  1. #    Gedit snippets plugin
  2. #    Copyright (C) 2006-2007  Jesse van den Kieboom <jesse@icecrew.nl>
  3. #
  4. #    This program is free software; you can redistribute it and/or modify
  5. #    it under the terms of the GNU General Public License as published by
  6. #    the Free Software Foundation; either version 2 of the License, or
  7. #    (at your option) any later version.
  8. #
  9. #    This program is distributed in the hope that it will be useful,
  10. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #    GNU General Public License for more details.
  13. #
  14. #    You should have received a copy of the GNU General Public License
  15. #    along with this program; if not, write to the Free Software
  16. #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17.  
  18. import re
  19.  
  20. class ParseError(Exception):
  21.         def __str__(self):
  22.                 return 'Parse error, resume next'
  23.  
  24. class Modifiers:
  25.         def _first_char(s):
  26.                 first = (s != '' and s[0]) or ''
  27.                 rest = (len(s) > 1 and s[1:]) or ''
  28.                 
  29.                 return first, rest
  30.         
  31.         def upper_first(s):
  32.                 first, rest = Modifiers._first_char(s)
  33.  
  34.                 return '%s%s' % (first.upper(), rest)
  35.  
  36.         def upper(s):
  37.                 return s.upper()
  38.  
  39.         def lower_first(s):
  40.                 first, rest = Modifiers._first_char(s)
  41.  
  42.                 return '%s%s' % (first.lower(), rest)
  43.                 
  44.         def lower(s):
  45.                 return s.lower()
  46.                 
  47.         def title(s):
  48.                 return s.title()
  49.         
  50.         upper_first = staticmethod(upper_first)
  51.         upper = staticmethod(upper)
  52.         lower_first = staticmethod(lower_first)
  53.         lower = staticmethod(lower)
  54.         title = staticmethod(title)
  55.         _first_char = staticmethod(_first_char)
  56.  
  57. class SubstitutionParser:
  58.         REG_ID = '[0-9]+'
  59.         REG_NAME = '[a-zA-Z_]+'
  60.         REG_MOD = '[a-zA-Z]+'
  61.         REG_ESCAPE = '\\\\|\\(\\?|,|\\)'
  62.  
  63.         def __init__(self, pattern, groups = {}, modifiers = {}):
  64.                 self.pattern = pattern
  65.                 self.groups = groups
  66.                 
  67.                 self.REG_GROUP = '(?:(%s)|<(%s|%s)(?:,(%s))?>)' % (self.REG_ID, self.REG_ID, self.REG_NAME, self.REG_MOD)
  68.                 self.modifiers = {'u': Modifiers.upper_first,
  69.                                   'U': Modifiers.upper,
  70.                                   'l': Modifiers.lower_first,
  71.                                   'L': Modifiers.lower,
  72.                                   't': Modifiers.title}
  73.                 
  74.                 for k, v in modifiers.items():
  75.                         self.modifiers[k] = v
  76.         
  77.         def parse(self):
  78.                 result, tokens = self._parse(self.pattern, None)
  79.                 
  80.                 return result
  81.         
  82.         def _parse(self, tokens, terminator):
  83.                 result = ''
  84.  
  85.                 while tokens != '':
  86.                         if self._peek(tokens) == '' or self._peek(tokens) == terminator:
  87.                                 tokens = self._remains(tokens)
  88.                                 break
  89.  
  90.                         try:
  91.                                 res, tokens = self._expr(tokens, terminator)
  92.                         except ParseError:
  93.                                 res, tokens = self._text(tokens)
  94.                         
  95.                         result += res
  96.                                 
  97.                 return result, tokens
  98.        
  99.         def _peek(self, tokens, num = 0):
  100.                 return (num < len(tokens) and tokens[num])
  101.         
  102.         def _token(self, tokens):
  103.                 if tokens == '':
  104.                         return '', '';
  105.  
  106.                 return tokens[0], (len(tokens) > 1 and tokens[1:]) or ''
  107.         
  108.         def _remains(self, tokens, num = 1):
  109.                 return (num < len(tokens) and tokens[num:]) or ''
  110.  
  111.         def _expr(self, tokens, terminator):                
  112.                 if tokens == '':
  113.                         return ''
  114.  
  115.                 try:
  116.                         return {'\\': self._escape,
  117.                                 '(': self._condition}[self._peek(tokens)](tokens, terminator)
  118.                 except KeyError:
  119.                         raise ParseError
  120.  
  121.         def _text(self, tokens):
  122.                 return self._token(tokens)
  123.  
  124.         def _substitute(self, group, modifiers = ''):
  125.                 result = (self.groups.has_key(group) and self.groups[group]) or ''
  126.                 
  127.                 for modifier in modifiers:
  128.                         if self.modifiers.has_key(modifier):
  129.                                 result = self.modifiers[modifier](result)
  130.                 
  131.                 return result
  132.                 
  133.         def _match_group(self, tokens):
  134.                 match = re.match('\\\\%s' % self.REG_GROUP, tokens)
  135.                 
  136.                 if not match:
  137.                         return None, tokens
  138.                 
  139.                 return self._substitute(match.group(1) or match.group(2), match.group(3) or ''), tokens[match.end():]
  140.                 
  141.         def _escape(self, tokens, terminator):
  142.                 # Try to match a group
  143.                 result, tokens = self._match_group(tokens)
  144.                 
  145.                 if result != None:
  146.                         return result, tokens
  147.                 
  148.                 s = self.REG_GROUP
  149.                 
  150.                 if terminator:
  151.                         s += '|%s' % re.escape(terminator)
  152.  
  153.                 match = re.match('\\\\(\\\\%s|%s)' % (s, self.REG_ESCAPE), tokens)
  154.  
  155.                 if not match:
  156.                         raise ParseError
  157.                                
  158.                 return match.group(1), tokens[match.end():]  
  159.         
  160.         def _condition_value(self, tokens):
  161.                 match = re.match('\\\\?%s\s*' % self.REG_GROUP, tokens)
  162.                 
  163.                 if not match:
  164.                         return None, tokens
  165.  
  166.                 groups = match.groups()
  167.                 name = groups[0] or groups[1]
  168.  
  169.                 return self.groups.has_key(name) and self.groups[name] != None, tokens[match.end():]        
  170.         
  171.         def _condition(self, tokens, terminator):
  172.                 # Match ? after (
  173.                 if self._peek(tokens, 1) != '?':
  174.                         raise ParseError
  175.                
  176.                 # Remove initial (? token
  177.                 tokens = self._remains(tokens, 2)
  178.                 condition, tokens = self._condition_value(tokens)
  179.                 
  180.                 if condition == None or self._peek(tokens) != ',':
  181.                         raise ParseError
  182.  
  183.                 truepart, tokens = self._parse(self._remains(tokens), ',')
  184.                 
  185.                 if truepart == None:
  186.                         raise ParseError
  187.                         
  188.                 falsepart, tokens = self._parse(tokens, ')')
  189.                 
  190.                 if falsepart == None:
  191.                         raise ParseError
  192.  
  193.                 if condition:
  194.                         return truepart, tokens
  195.                 else:
  196.                         return falsepart, tokens
  197.         
  198.         def escape_substitution(substitution):
  199.                 return re.sub('(%s|%s)' % (self.REG_GROUP, self.REG_ESCAPE), '\\\\\\1', substitution)
  200.                 
  201.         escapesubstitution = staticmethod(escape_substitution)
  202. # ex:ts=8:et:
  203.