Kirill Simonov avatar Kirill Simonov committed 0c63bdc

Remake the YAML highlighting example.

Comments (0)

Files changed (4)

examples/yaml-hl/yaml_hl.cfg

+%YAML 1.1
+---
+
+ascii:
+
+    header: "\e[0;1;30;40m"
+
+    footer: "\e[0m"
+
+    tokens:
+        stream-start:
+        stream-end:
+        directive:              { start: "\e[35m", end: "\e[0;1;30;40m" }
+        document-start:         { start: "\e[35m", end: "\e[0;1;30;40m" }
+        document-end:           { start: "\e[35m", end: "\e[0;1;30;40m" }
+        block-sequence-start:
+        block-mapping-start:
+        block-end:
+        flow-sequence-start:    { start: "\e[33m", end: "\e[0;1;30;40m" }
+        flow-mapping-start:     { start: "\e[33m", end: "\e[0;1;30;40m" }
+        flow-sequence-end:      { start: "\e[33m", end: "\e[0;1;30;40m" }
+        flow-mapping-end:       { start: "\e[33m", end: "\e[0;1;30;40m" }
+        key:                    { start: "\e[33m", end: "\e[0;1;30;40m" }
+        value:                  { start: "\e[33m", end: "\e[0;1;30;40m" }
+        block-entry:            { start: "\e[33m", end: "\e[0;1;30;40m" }
+        flow-entry:             { start: "\e[33m", end: "\e[0;1;30;40m" }
+        alias:                  { start: "\e[32m", end: "\e[0;1;30;40m" }
+        anchor:                 { start: "\e[32m", end: "\e[0;1;30;40m" }
+        tag:                    { start: "\e[32m", end: "\e[0;1;30;40m" }
+        scalar:                 { start: "\e[36m", end: "\e[0;1;30;40m" }
+
+    replaces:
+        - "\r\n":   "\n"
+        - "\r":     "\n"
+        - "\n":     "\n"
+        - "\x85":   "\n"
+        - "\u2028": "\n"
+        - "\u2029": "\n"
+
+html: &html
+
+    tokens:
+        stream-start:
+        stream-end:
+        directive:              { start: <code class="directive_token">, end: </code> }
+        document-start:         { start: <code class="document_start_token">, end: </code> }
+        document-end:           { start: <code class="document_end_token">, end: </code> }
+        block-sequence-start:
+        block-mapping-start:
+        block-end:
+        flow-sequence-start:    { start: <code class="delimiter_token">, end: </code> }
+        flow-mapping-start:     { start: <code class="delimiter_token">, end: </code> }
+        flow-sequence-end:      { start: <code class="delimiter_token">, end: </code> }
+        flow-mapping-end:       { start: <code class="delimiter_token">, end: </code> }
+        key:                    { start: <code class="delimiter_token">, end: </code> }
+        value:                  { start: <code class="delimiter_token">, end: </code> }
+        block-entry:            { start: <code class="delimiter_token">, end: </code> }
+        flow-entry:             { start: <code class="delimiter_token">, end: </code> }
+        alias:                  { start: <code class="anchor_token">, end: </code> }
+        anchor:                 { start: <code class="anchor_token">, end: </code> }
+        tag:                    { start: <code class="tag_token">, end: </code> }
+        scalar:                 { start: <code class="scalar_token">, end: </code> }
+
+    events:
+        stream-start:   { start: <pre class="yaml_stream"> }
+        stream-end:     { end: </pre> }
+        document-start: { start: <span class="document"> }
+        document-end:   { end: </span> }
+        sequence-start: { start: <span class="sequence"> }
+        sequence-end:   { end: </span> }
+        mapping-start:  { start: <span class="mapping"> }
+        mapping-end:    { end: </span> }
+        scalar:         { start: <span class="scalar">, end: </span> }
+
+    replaces:
+        - "\r\n":   "\n"
+        - "\r":     "\n"
+        - "\n":     "\n"
+        - "\x85":   "\n"
+        - "\u2028": "\n"
+        - "\u2029": "\n"
+        - "&":      "&amp;"
+        - "<":      "&lt;"
+        - ">":      "&gt;"
+
+html-page:
+
+    header: |
+        <html>
+        <head>
+        <title>A YAML stream</title>
+        <style type="text/css">
+            .document { background: #FFF }
+            .sequence { background: #EEF }
+            .mapping { background: #EFE }
+            .scalar { background: #FEE }
+            .directive_token { color: #C0C }
+            .document_start_token { color: #C0C; font-weight: bold }
+            .document_end_token { color: #C0C; font-weight: bold }
+            .delimiter_token { color: #600; font-weight: bold }
+            .anchor_token { color: #090 }
+            .tag_token { color: #090 }
+            .scalar_token { color: #000 }
+            .yaml_stream { color: #999 }
+        </style>
+        <body>
+
+    footer: |
+        </body>
+        </html>
+
+    <<: *html
+
+
+# vim: ft=yaml

examples/yaml-hl/yaml_hl.py

 
 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 Style:
+
+    def __init__(self, header=None, footer=None,
+            tokens=None, events=None, replaces=None):
+        self.header = header
+        self.footer = footer
+        self.replaces = replaces
+        self.substitutions = {}
+        for domain, Class in [(tokens, 'Token'), (events, 'Event')]:
+            if not domain:
+                continue
+            for key in domain:
+                name = ''.join([part.capitalize() for part in key.split('-')])
+                cls = getattr(yaml, '%s%s' % (name, Class))
+                value = domain[key]
+                if not value:
+                    continue
+                start = value.get('start')
+                end = value.get('end')
+                if start:
+                    self.substitutions[cls, -1] = start
+                if end:
+                    self.substitutions[cls, +1] = end
+
+    def __setstate__(self, state):
+        self.__init__(**state)
+
+yaml.add_path_resolver(u'tag:yaml.org,2002:python/object:__main__.Style',
+        [None], dict)
+yaml.add_path_resolver(u'tag:yaml.org,2002:pairs',
+        [None, u'replaces'], list)
 
 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 __init__(self, options):
+        config = yaml.load(file(options.config, 'rb').read())
+        self.style = config[options.style]
+        if options.input:
+            self.input = file(options.input, 'rb')
+        else:
+            self.input = sys.stdin
+        if options.output:
+            self.output = file(options.output, 'wb')
+        else:
+            self.output = sys.stdout
 
-    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')
+    def highlight(self):
+        if self.style.header:
+            self.output.write(self.style.header)
+        input = self.input.read()
+        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')
+        substitutions = self.style.substitutions
         tokens = yaml.scan(input)
         events = yaml.parse(input)
         markers = []
             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]])
+                if (cls, -1) in substitutions:
+                    markers.append([token.start_mark.index, +2, number, substitutions[cls, -1]])
+                if (cls, +1) in substitutions:
+                    markers.append([token.end_mark.index, -2, number, 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]])
+            if (cls, -1) in substitutions:
+                markers.append([event.start_mark.index, +1, number, substitutions[cls, -1]])
+            if (cls, +1) in substitutions:
+                markers.append([event.end_mark.index, -1, number, substitutions[cls, +1]])
         markers.sort()
         markers.reverse()
         chunks = []
         for index, weight1, weight2, substitution in markers:
             if index < position:
                 chunk = input[index:position]
-                for substring, replacement in self.replaces:
+                for substring, replacement in self.style.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')
+        self.output.write(result.encode('utf-8'))
+        if self.style.footer:
+            self.output.write(self.style.footer)
 
 if __name__ == '__main__':
     parser = optparse.OptionParser()
-    parser.add_option('-c', '--config', dest='config', default='yaml_hl_ascii.cfg', metavar='CONFIG')
+    parser.add_option('-s', '--style', dest='style', default='ascii',
+            help="specify the highlighting style", metavar='STYLE')
+    parser.add_option('-c', '--config', dest='config', default='yaml_hl.cfg',
+            help="set an alternative configuration file", metavar='CONFIG')
+    parser.add_option('-i', '--input', dest='input', default=None,
+            help="set the input file (default: stdin)", metavar='FILE')
+    parser.add_option('-o', '--output', dest='output', default=None,
+            help="set the output file (default: stdout)", metavar='FILE')
     (options, args) = parser.parse_args()
-    hl = YAMLHighlight(file(options.config))
-    sys.stdout.write(hl.highlight(sys.stdin.read()))
+    hl = YAMLHighlight(options)
+    hl.highlight()
 

examples/yaml-hl/yaml_hl_ascii.cfg

-%YAML 1.1
----
-tokens:
-    stream-start:
-    stream-end:
-    directive:              { start: "\e[35m", end: "\e[0;1;30;40m" }
-    document-start:         { start: "\e[35m", end: "\e[0;1;30;40m" }
-    document-end:           { start: "\e[35m", end: "\e[0;1;30;40m" }
-    block-sequence-start:
-    block-mapping-start:
-    block-end:
-    flow-sequence-start:    { start: "\e[33m", end: "\e[0;1;30;40m" }
-    flow-mapping-start:     { start: "\e[33m", end: "\e[0;1;30;40m" }
-    flow-sequence-end:      { start: "\e[33m", end: "\e[0;1;30;40m" }
-    flow-mapping-end:       { start: "\e[33m", end: "\e[0;1;30;40m" }
-    key:                    { start: "\e[33m", end: "\e[0;1;30;40m" }
-    value:                  { start: "\e[33m", end: "\e[0;1;30;40m" }
-    block-entry:            { start: "\e[33m", end: "\e[0;1;30;40m" }
-    flow-entry:             { start: "\e[33m", end: "\e[0;1;30;40m" }
-    alias:                  { start: "\e[32m", end: "\e[0;1;30;40m" }
-    anchor:                 { start: "\e[32m", end: "\e[0;1;30;40m" }
-    tag:                    { start: "\e[32m", end: "\e[0;1;30;40m" }
-    scalar:                 { start: "\e[36m", end: "\e[0;1;30;40m" }
-
-events:
-    stream-start:   { start: "\e[0;1;30;40m" }
-    stream-end:     { end: "\e[0m" }
-    document-start:
-    document-end:
-    sequence-start:
-    sequence-end:
-    mapping-start:
-    mapping-end:
-    scalar:
-
-replaces: !!pairs
-    - "\r\n":   "\n"
-    - "\r":     "\n"
-    - "\n":     "\n"
-    - "\x85":   "\n"
-    - "\u2028": "\n"
-    - "\u2029": "\n"
-
-# vim: ft=yaml

examples/yaml-hl/yaml_hl_html.cfg

-
-tokens:
-    stream-start:
-    stream-end:
-    directive:              { start: <code class="directive-token">, end: </code> }
-    document-start:         { start: <code class="document-start-token">, end: </code> }
-    document-end:           { start: <code class="document-end-token">, end: </code> }
-    block-sequence-start:
-    block-mapping-start:
-    block-end:
-    flow-sequence-start:    { start: <code class="delimiter-token">, end: </code> }
-    flow-mapping-start:     { start: <code class="delimiter-token">, end: </code> }
-    flow-sequence-end:      { start: <code class="delimiter-token">, end: </code> }
-    flow-mapping-end:       { start: <code class="delimiter-token">, end: </code> }
-    key:                    { start: <code class="delimiter-token">, end: </code> }
-    value:                  { start: <code class="delimiter-token">, end: </code> }
-    block-entry:            { start: <code class="delimiter-token">, end: </code> }
-    flow-entry:             { start: <code class="delimiter-token">, end: </code> }
-    alias:                  { start: <code class="anchor-token">, end: </code> }
-    anchor:                 { start: <code class="anchor-token">, end: </code> }
-    tag:                    { start: <code class="tag-token">, end: </code> }
-    scalar:                 { start: <code class="scalar-token">, end: </code> }
-
-events:
-    stream-start:   { start: <pre class="yaml-stream"> }
-    stream-end:     { end: </pre> }
-    document-start: { start: <span class="document"> }
-    document-end:   { end: </span> }
-    sequence-start: { start: <span class="sequence"> }
-    sequence-end:   { end: </span> }
-    mapping-start:  { start: <span class="mapping"> }
-    mapping-end:    { end: </span> }
-    scalar:         { start: <span class="scalar">, end: </span> }
-
-replaces: !!pairs
-    - "\r\n":   "\n"
-    - "\r":     "\n"
-    - "\n":     "\n"
-    - "\x85":   "\n"
-    - "\u2028": "\n"
-    - "\u2029": "\n"
-    - "<":      "&lt;"
-    - ">":      "&gt;"
-    - "&":      "&amp;"
-
-# vim: ft=yaml
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.