diff options
Diffstat (limited to 'python/pyyaml/examples/yaml-highlight')
-rw-r--r-- | python/pyyaml/examples/yaml-highlight/yaml_hl.cfg | 115 | ||||
-rwxr-xr-x | python/pyyaml/examples/yaml-highlight/yaml_hl.py | 114 |
2 files changed, 229 insertions, 0 deletions
diff --git a/python/pyyaml/examples/yaml-highlight/yaml_hl.cfg b/python/pyyaml/examples/yaml-highlight/yaml_hl.cfg new file mode 100644 index 000000000..69bb84776 --- /dev/null +++ b/python/pyyaml/examples/yaml-highlight/yaml_hl.cfg @@ -0,0 +1,115 @@ +%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" + - "&": "&" + - "<": "<" + - ">": ">" + +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 diff --git a/python/pyyaml/examples/yaml-highlight/yaml_hl.py b/python/pyyaml/examples/yaml-highlight/yaml_hl.py new file mode 100755 index 000000000..d6f7bf4eb --- /dev/null +++ b/python/pyyaml/examples/yaml-highlight/yaml_hl.py @@ -0,0 +1,114 @@ +#!/usr/bin/python + +import yaml, codecs, sys, os.path, optparse + +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, 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 = 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 = 0 + for token in tokens: + number += 1 + if token.start_mark.index != token.end_mark.index: + cls = token.__class__ + 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 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 = [] + position = len(input) + for index, weight1, weight2, substitution in markers: + if index < position: + chunk = input[index:position] + 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) + if self.style.header: + self.output.write(self.style.header) + 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('-s', '--style', dest='style', default='ascii', + help="specify the highlighting style", metavar='STYLE') + parser.add_option('-c', '--config', dest='config', + default=os.path.join(os.path.dirname(sys.argv[0]), '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(options) + hl.highlight() + |