source: pyyaml/trunk/examples/yaml-hl/yaml_hl.py @ 136

Revision 136, 3.2 KB checked in by xi, 8 years ago (diff)

Major refactoring.

  • Property svn:executable set to *
Line 
1#!/usr/bin/python
2
3import yaml, codecs, sys, optparse
4
5
6
7yaml.add_resolver(u'!Config', [])
8yaml.add_resolver(u'!TokensConfig', [u'tokens'])
9yaml.add_resolver(u'!EventsConfig', [u'events'])
10yaml.add_resolver(u'!StartEndConfig', [u'tokens', None])
11yaml.add_resolver(u'!StartEndConfig', [u'events', None])
12
13class YAMLHighlight:
14
15    def __init__(self, config):
16        parameters = yaml.load_document(config)
17        self.replaces = parameters['replaces']
18        self.substitutions = {}
19        for domain, items in [('Token', parameters['tokens']),
20                    ('Event', parameters['events'])]:
21            for code in items:
22                name = ''.join([part.capitalize() for part in code.split('-')]+[domain])
23                cls = getattr(yaml, name)
24                value = items[code]
25                if value:
26                    if 'start' in value:
27                        self.substitutions[cls, -1] = value['start']
28                    if 'end' in value:
29                        self.substitutions[cls, +1] = value['end']
30
31    def highlight(self, input):
32        if isinstance(input, str):
33            if input.startswith(codecs.BOM_UTF16_LE):
34                input = unicode(input, 'utf-16-le')
35            elif input.startswith(codecs.BOM_UTF16_BE):
36                input = unicode(input, 'utf-16-be')
37            else:
38                input = unicode(input, 'utf-8')
39        tokens = yaml.parse(input, Parser=iter)
40        events = yaml.parse(input)
41        markers = []
42        number = 0
43        for token in tokens:
44            number += 1
45            if token.start_mark.index != token.end_mark.index:
46                cls = token.__class__
47                if (cls, -1) in self.substitutions:
48                    markers.append([token.start_mark.index, +2, number, self.substitutions[cls, -1]])
49                if (cls, +1) in self.substitutions:
50                    markers.append([token.end_mark.index, -2, number, self.substitutions[cls, +1]])
51        number = 0
52        for event in events:
53            number += 1
54            cls = event.__class__
55            if (cls, -1) in self.substitutions:
56                markers.append([event.start_mark.index, +1, number, self.substitutions[cls, -1]])
57            if (cls, +1) in self.substitutions:
58                markers.append([event.end_mark.index, -1, number, self.substitutions[cls, +1]])
59        markers.sort()
60        markers.reverse()
61        chunks = []
62        position = len(input)
63        for index, weight1, weight2, substitution in markers:
64            if index < position:
65                chunk = input[index:position]
66                for substring, replacement in self.replaces:
67                    chunk = chunk.replace(substring, replacement)
68                chunks.append(chunk)
69                position = index
70            chunks.append(substitution)
71        chunks.reverse()
72        result = u''.join(chunks)
73        return result.encode('utf-8')
74
75if __name__ == '__main__':
76    parser = optparse.OptionParser()
77    parser.add_option('-c', '--config', dest='config', default='yaml_hl_ascii.cfg', metavar='CONFIG')
78    (options, args) = parser.parse_args()
79    hl = YAMLHighlight(file(options.config))
80    sys.stdout.write(hl.highlight(sys.stdin.read()))
81
Note: See TracBrowser for help on using the repository browser.