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