thirdparty/google_appengine/lib/yaml/examples/yaml-highlight/yaml_hl.py
changeset 109 620f9b141567
equal deleted inserted replaced
108:261778de26ff 109:620f9b141567
       
     1 #!/usr/bin/python
       
     2 
       
     3 import yaml, codecs, sys, os.path, optparse
       
     4 
       
     5 class Style:
       
     6 
       
     7     def __init__(self, header=None, footer=None,
       
     8             tokens=None, events=None, replaces=None):
       
     9         self.header = header
       
    10         self.footer = footer
       
    11         self.replaces = replaces
       
    12         self.substitutions = {}
       
    13         for domain, Class in [(tokens, 'Token'), (events, 'Event')]:
       
    14             if not domain:
       
    15                 continue
       
    16             for key in domain:
       
    17                 name = ''.join([part.capitalize() for part in key.split('-')])
       
    18                 cls = getattr(yaml, '%s%s' % (name, Class))
       
    19                 value = domain[key]
       
    20                 if not value:
       
    21                     continue
       
    22                 start = value.get('start')
       
    23                 end = value.get('end')
       
    24                 if start:
       
    25                     self.substitutions[cls, -1] = start
       
    26                 if end:
       
    27                     self.substitutions[cls, +1] = end
       
    28 
       
    29     def __setstate__(self, state):
       
    30         self.__init__(**state)
       
    31 
       
    32 yaml.add_path_resolver(u'tag:yaml.org,2002:python/object:__main__.Style',
       
    33         [None], dict)
       
    34 yaml.add_path_resolver(u'tag:yaml.org,2002:pairs',
       
    35         [None, u'replaces'], list)
       
    36 
       
    37 class YAMLHighlight:
       
    38 
       
    39     def __init__(self, options):
       
    40         config = yaml.load(file(options.config, 'rb').read())
       
    41         self.style = config[options.style]
       
    42         if options.input:
       
    43             self.input = file(options.input, 'rb')
       
    44         else:
       
    45             self.input = sys.stdin
       
    46         if options.output:
       
    47             self.output = file(options.output, 'wb')
       
    48         else:
       
    49             self.output = sys.stdout
       
    50 
       
    51     def highlight(self):
       
    52         input = self.input.read()
       
    53         if input.startswith(codecs.BOM_UTF16_LE):
       
    54             input = unicode(input, 'utf-16-le')
       
    55         elif input.startswith(codecs.BOM_UTF16_BE):
       
    56             input = unicode(input, 'utf-16-be')
       
    57         else:
       
    58             input = unicode(input, 'utf-8')
       
    59         substitutions = self.style.substitutions
       
    60         tokens = yaml.scan(input)
       
    61         events = yaml.parse(input)
       
    62         markers = []
       
    63         number = 0
       
    64         for token in tokens:
       
    65             number += 1
       
    66             if token.start_mark.index != token.end_mark.index:
       
    67                 cls = token.__class__
       
    68                 if (cls, -1) in substitutions:
       
    69                     markers.append([token.start_mark.index, +2, number, substitutions[cls, -1]])
       
    70                 if (cls, +1) in substitutions:
       
    71                     markers.append([token.end_mark.index, -2, number, substitutions[cls, +1]])
       
    72         number = 0
       
    73         for event in events:
       
    74             number += 1
       
    75             cls = event.__class__
       
    76             if (cls, -1) in substitutions:
       
    77                 markers.append([event.start_mark.index, +1, number, substitutions[cls, -1]])
       
    78             if (cls, +1) in substitutions:
       
    79                 markers.append([event.end_mark.index, -1, number, substitutions[cls, +1]])
       
    80         markers.sort()
       
    81         markers.reverse()
       
    82         chunks = []
       
    83         position = len(input)
       
    84         for index, weight1, weight2, substitution in markers:
       
    85             if index < position:
       
    86                 chunk = input[index:position]
       
    87                 for substring, replacement in self.style.replaces:
       
    88                     chunk = chunk.replace(substring, replacement)
       
    89                 chunks.append(chunk)
       
    90                 position = index
       
    91             chunks.append(substitution)
       
    92         chunks.reverse()
       
    93         result = u''.join(chunks)
       
    94         if self.style.header:
       
    95             self.output.write(self.style.header)
       
    96         self.output.write(result.encode('utf-8'))
       
    97         if self.style.footer:
       
    98             self.output.write(self.style.footer)
       
    99 
       
   100 if __name__ == '__main__':
       
   101     parser = optparse.OptionParser()
       
   102     parser.add_option('-s', '--style', dest='style', default='ascii',
       
   103             help="specify the highlighting style", metavar='STYLE')
       
   104     parser.add_option('-c', '--config', dest='config',
       
   105             default=os.path.join(os.path.dirname(sys.argv[0]), 'yaml_hl.cfg'),
       
   106             help="set an alternative configuration file", metavar='CONFIG')
       
   107     parser.add_option('-i', '--input', dest='input', default=None,
       
   108             help="set the input file (default: stdin)", metavar='FILE')
       
   109     parser.add_option('-o', '--output', dest='output', default=None,
       
   110             help="set the output file (default: stdout)", metavar='FILE')
       
   111     (options, args) = parser.parse_args()
       
   112     hl = YAMLHighlight(options)
       
   113     hl.highlight()
       
   114