diff --git a/httpie/pretty.py b/httpie/pretty.py index 774839d1..1a108d39 100644 --- a/httpie/pretty.py +++ b/httpie/pretty.py @@ -1,12 +1,13 @@ import os import json import pygments +import re from pygments import token from pygments.util import ClassNotFound from pygments.lexers import get_lexer_for_mimetype from pygments.formatters.terminal256 import Terminal256Formatter from pygments.formatters.terminal import TerminalFormatter -from pygments.lexer import RegexLexer, bygroups +from pygments.lexer import include, RegexLexer, bygroups from pygments.styles import get_style_by_name, STYLE_MAP from . import solarized @@ -31,6 +32,68 @@ class HTTPLexer(RegexLexer): (r'(.*?:)(.+)', bygroups(token.Name, token.String)) ]} +# Stolen from https://github.com/orb/pygments-json +class JSONLexer(RegexLexer): + name = 'JSON Lexer' + aliases = ['json'] + filenames = ['*.json'] + mimetypes = [] + + + flags = re.DOTALL + tokens = { + 'whitespace': [ + (r'\s+', token.Text), + ], + + # represents a simple terminal value + 'simplevalue':[ + (r'(true|false|null)\b', token.Keyword.Constant), + (r'-?[0-9]+', token.Number.Integer), + (r'"(\\\\|\\"|[^"])*"', token.String.Double), + ], + + + # the right hand side of an object, after the attribute name + 'objectattribute': [ + include('value'), + (r':', token.Punctuation), + # comma terminates the attribute but expects more + (r',', token.Punctuation, '#pop'), + # a closing bracket terminates the entire object, so pop twice + (r'}', token.Punctuation, ('#pop', '#pop')), + ], + + # a json object - { attr, attr, ... } + 'objectvalue': [ + include('whitespace'), + (r'"(\\\\|\\"|[^"])*"', token.Name.Tag, 'objectattribute'), + (r'}', token.Punctuation, '#pop'), + ], + + # json array - [ value, value, ... } + 'arrayvalue': [ + include('whitespace'), + include('value'), + (r',', token.Punctuation), + (r']', token.Punctuation, '#pop'), + ], + + # a json value - either a simple value or a complex value (object or array) + 'value': [ + include('whitespace'), + include('simplevalue'), + (r'{', token.Punctuation, 'objectvalue'), + (r'\[', token.Punctuation, 'arrayvalue'), + ], + + + # the root of a json document would be a value + 'root': [ + include('value'), + ], + + } class PrettyHttp(object): @@ -52,11 +115,13 @@ class PrettyHttp(object): # Indent JSON content = json.dumps(json.loads(content), sort_keys=True, indent=4) + lexer = JSONLexer() except Exception: pass - try: - lexer = get_lexer_for_mimetype(content_type) - except ClassNotFound: - return content + else: + try: + lexer = get_lexer_for_mimetype(content_type) + except ClassNotFound: + return content content = pygments.highlight(content, lexer, self.formatter) return content