Используя более одного цвета подсветки в фрагментах
Я использую фрагменты для выделения строк из файла, но хочу выделить разные строки разными цветами.
Примечание. Когда я писал этот вопрос, я пробовал разные вещи, пока не нашел то, что выглядит как достойное решение, которое решает мою проблему. Я опубликую это в ответах.
Моя первая попытка изменить желтый по умолчанию (который очень бледный) была:
HIGHLIGHT_COLOR = '#F4E004'
formatter = HtmlFormatter(linenos='inline', hl_lines=hl_lines, lineanchors='foo')
style = formatter.get_style_defs()
with open(the_xml_fullpath) as f:
highlighted = highlight(f.read(), XmlLexer(), formatter)
# make the yellow more ...yellow
_style = re.sub(r'background-color: \#.+ ', 'background-color: {} '.format(HIGHLIGHT_COLOR), style)
Теперь я полностью осознаю опасности использования регулярного выражения для разбора HTML, но я подумал, что единственной альтернативой было использование noclasses=True
вариант highlight()
который не использует CSS классы встроенного CSS, а затем перебирает весь файл и заменяет цвет фона строк, которые я хочу.
Итак, мой вопрос: как я могу выделить другой набор линий, используя фрагменты с разными цветами?
1 ответ
Мое решение подкласс HtmlFormatter
Класс, как предлагается в документации, как это:
class MyFormatter(HtmlFormatter):
"""Overriding formatter to highlight more than one kind of lines"""
def __init__(self, **kwargs):
super(MyFormatter, self).__init__(**kwargs)
# a list of [ (highlight_colour, [lines]) ]
self.highlight_groups = kwargs.get('highlight_groups', [])
def wrap(self, source, outfile):
return self._wrap_code(source)
# generator: returns 0, html if it's not a source line; 1, line if it is
def _wrap_code(self, source):
_prefix = ''
if self.cssclass is not None:
_prefix += '<div class="highlight">'
if self.filename is not None:
_prefix += '<span class="filename">{}</span>'.format(self.filename)
yield 0, _prefix + '<pre>'
for count, _t in enumerate(source):
i, t = _t
if i == 1:
# it's a line of formatted code
for highlight_group in self.highlight_groups:
col, lines = highlight_group
# count starts from 0...
if (count + 1) in lines:
# it's a highlighted line - set the colour
_row = '<span style="background-color:{}">{}</span>'.format(col, t)
t = _row
yield i, t
# close open things
_postfix = ''
if self.cssclass is not None:
_postfix += '</div>'
yield 0, '</pre>' + _postfix
Чтобы использовать это:
# dark yellow
HIGHLIGHT_COLOUR = '#F4E004'
# pinkish
DEPRECATED_COLOUR = '#FF4ED1'
formatter = MyFormatter(
linenos='inline',
# no need to highlight lines - we take care of it in the formatter
# hl_lines=hl_lines,
filename="sourcefile",
# a list of tuples (color, [lines]) indicating which colur to use
highlight_groups=[
(HIGHLIGHT_COLOR, hl_lines),
(DEPRECATED_COLOR, deprecated_lines),
]
)