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