pyyaml / examples / yaml-hl / yaml_hl.py

#!/usr/bin/python

import yaml, codecs, sys, optparse

#yaml.add_resolver(u'!Config', [])
#yaml.add_resolver(u'!TokensConfig', [u'tokens'])
#yaml.add_resolver(u'!EventsConfig', [u'events'])
#yaml.add_resolver(u'!StartEndConfig', [u'tokens', None])
#yaml.add_resolver(u'!StartEndConfig', [u'events', None])

class YAMLHighlight:

    def __init__(self, config):
        parameters = yaml.load(config)
        self.replaces = parameters['replaces']
        self.substitutions = {}
        for domain, items in [('Token', parameters['tokens']),
                    ('Event', parameters['events'])]:
            for code in items:
                name = ''.join([part.capitalize() for part in code.split('-')]+[domain])
                cls = getattr(yaml, name)
                value = items[code]
                if value:
                    if 'start' in value:
                        self.substitutions[cls, -1] = value['start']
                    if 'end' in value:
                        self.substitutions[cls, +1] = value['end']

    def highlight(self, input):
        if isinstance(input, str):
            if input.startswith(codecs.BOM_UTF16_LE):
                input = unicode(input, 'utf-16-le')
            elif input.startswith(codecs.BOM_UTF16_BE):
                input = unicode(input, 'utf-16-be')
            else:
                input = unicode(input, 'utf-8')
        tokens = yaml.scan(input)
        events = yaml.parse(input)
        markers = []
        number = 0
        for token in tokens:
            number += 1
            if token.start_mark.index != token.end_mark.index:
                cls = token.__class__
                if (cls, -1) in self.substitutions:
                    markers.append([token.start_mark.index, +2, number, self.substitutions[cls, -1]])
                if (cls, +1) in self.substitutions:
                    markers.append([token.end_mark.index, -2, number, self.substitutions[cls, +1]])
        number = 0
        for event in events:
            number += 1
            cls = event.__class__
            if (cls, -1) in self.substitutions:
                markers.append([event.start_mark.index, +1, number, self.substitutions[cls, -1]])
            if (cls, +1) in self.substitutions:
                markers.append([event.end_mark.index, -1, number, self.substitutions[cls, +1]])
        markers.sort()
        markers.reverse()
        chunks = []
        position = len(input)
        for index, weight1, weight2, substitution in markers:
            if index < position:
                chunk = input[index:position]
                for substring, replacement in self.replaces:
                    chunk = chunk.replace(substring, replacement)
                chunks.append(chunk)
                position = index
            chunks.append(substitution)
        chunks.reverse()
        result = u''.join(chunks)
        return result.encode('utf-8')

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-c', '--config', dest='config', default='yaml_hl_ascii.cfg', metavar='CONFIG')
    (options, args) = parser.parse_args()
    hl = YAMLHighlight(file(options.config))
    sys.stdout.write(hl.highlight(sys.stdin.read()))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.