Reviewed By: akotulski Differential Revision: D2642187 fb-gh-sync-id: 92fdfdfmaster
parent
88b615d8ab
commit
2ec2858b66
@ -0,0 +1,99 @@
|
|||||||
|
# Copyright (c) 2013 - present Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import codecs
|
||||||
|
try:
|
||||||
|
import pygments
|
||||||
|
import pygments.formatters
|
||||||
|
import pygments.lexers
|
||||||
|
except ImportError:
|
||||||
|
pygments = None
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
BASE_INDENT = 2
|
||||||
|
# how many lines of context around each report
|
||||||
|
SOURCE_CONTEXT = 2
|
||||||
|
|
||||||
|
# syntax highlighting modes
|
||||||
|
PLAIN_FORMATTER = 0
|
||||||
|
TERMINAL_FORMATTER = 1
|
||||||
|
|
||||||
|
|
||||||
|
class Indenter(str):
|
||||||
|
def __init__(self):
|
||||||
|
super(Indenter, self).__init__()
|
||||||
|
self.text = ''
|
||||||
|
self.indent = []
|
||||||
|
|
||||||
|
def indent_get(self):
|
||||||
|
indent = ''
|
||||||
|
for i in self.indent:
|
||||||
|
indent += i
|
||||||
|
return indent
|
||||||
|
|
||||||
|
def indent_push(self, n=1):
|
||||||
|
self.indent.append(n * BASE_INDENT * ' ')
|
||||||
|
|
||||||
|
def indent_pop(self):
|
||||||
|
return self.indent.pop()
|
||||||
|
|
||||||
|
def newline(self):
|
||||||
|
self.text += '\n'
|
||||||
|
|
||||||
|
def add(self, x):
|
||||||
|
if type(x) != unicode:
|
||||||
|
x = x.decode(utils.LOCALE)
|
||||||
|
lines = x.splitlines()
|
||||||
|
indent = self.indent_get()
|
||||||
|
lines = [indent + l for l in lines]
|
||||||
|
self.text += '\n'.join(lines)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return unicode(self).encode(utils.LOCALE)
|
||||||
|
|
||||||
|
|
||||||
|
def build_source_context(source_name, mode, report_line):
|
||||||
|
start_line = max(1, report_line - SOURCE_CONTEXT)
|
||||||
|
# could go beyond last line, checked in the loop
|
||||||
|
end_line = report_line + SOURCE_CONTEXT
|
||||||
|
|
||||||
|
n_length = len(str(end_line))
|
||||||
|
line_number = 1
|
||||||
|
s = ''
|
||||||
|
with codecs.open(source_name, 'r', encoding=utils.LOCALE) as source_file:
|
||||||
|
for line in source_file:
|
||||||
|
if start_line <= line_number <= end_line:
|
||||||
|
num = str(line_number).zfill(n_length)
|
||||||
|
caret = ' '
|
||||||
|
if line_number == report_line:
|
||||||
|
caret = '> '
|
||||||
|
s += u'%s. %s%s' % (num, caret, line)
|
||||||
|
line_number += 1
|
||||||
|
return _syntax_highlighting(source_name, mode, s)
|
||||||
|
|
||||||
|
|
||||||
|
def _syntax_highlighting(source_name, mode, s):
|
||||||
|
if pygments is None or mode == PLAIN_FORMATTER:
|
||||||
|
return s
|
||||||
|
|
||||||
|
lexer = pygments.lexers.get_lexer_for_filename(source_name)
|
||||||
|
formatter = None
|
||||||
|
if mode == TERMINAL_FORMATTER:
|
||||||
|
if not sys.stdout.isatty():
|
||||||
|
return s
|
||||||
|
formatter = pygments.formatters.TerminalFormatter()
|
||||||
|
return pygments.highlight(s, lexer, formatter)
|
Loading…
Reference in new issue