##// END OF EJS Templates
Merge pull request #8429 from Carreau/backport-notebook-89...
Merge pull request #8429 from Carreau/backport-notebook-89 Backport jupyter/notebook#89

File last commit:

r16980:d2acc300
r21379:78b7cfd9 merge
Show More
ansi.py
166 lines | 4.7 KiB | text/x-python | PythonLexer
Jonathan Frederic
Cleanup and refactor of filters
r10676 """Filters for processing ANSI colors within Jinja templates.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Jonathan Frederic
Post code-review, extended refactor.
r10485 import re
jakobgager
Update imports
r10946 from IPython.utils import coloransi
Thomas Kluyver
Move strip_ansi function to utils
r16980 from IPython.utils.text import strip_ansi
Jonathan Frederic
Post code-review, extended refactor.
r10485
Jonathan Frederic
Cleanup and refactor of filters
r10676 #-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------
Jonathan Frederic
Post code-review, extended refactor.
r10485
Brian E. Granger
Fixing import logic.
r11088 __all__ = [
Jonathan Frederic
Filter names cleanup
r11685 'strip_ansi',
Brian E. Granger
Fixing import logic.
r11088 'ansi2html',
'single_ansi2latex',
'ansi2latex'
]
Paul Ivanov
tiny refactor to nbconvert ansi filter...
r16799 ansi_colormap = {
'30': 'ansiblack',
'31': 'ansired',
'32': 'ansigreen',
'33': 'ansiyellow',
'34': 'ansiblue',
'35': 'ansipurple',
'36': 'ansicyan',
'37': 'ansigrey',
'01': 'ansibold',
}
html_escapes = {
'<': '&lt;',
'>': '&gt;',
"'": '&apos;',
'"': '&quot;',
'`': '&#96;',
}
ansi_re = re.compile('\x1b' + r'\[([\dA-Fa-f;]*?)m')
Jonathan Frederic
Cleanup and refactor of filters
r10676 def ansi2html(text):
"""
Paul Ivanov
tiny refactor to nbconvert ansi filter...
r16799 Convert ansi colors to html colors.
Jonathan Frederic
Cleanup and refactor of filters
r10676
Parameters
----------
text : str
Text containing ansi colors to convert to html
"""
Jonathan Frederic
Post code-review, extended refactor.
r10485
# do ampersand first
Jonathan Frederic
Cleanup and refactor of filters
r10676 text = text.replace('&', '&amp;')
Jonathan Frederic
Fixed all broken references, refactored some stuff here and there,...
r10624
Thomas Kluyver
Fix references to dict.iteritems and dict.itervalues
r13361 for c, escape in html_escapes.items():
Jonathan Frederic
Cleanup and refactor of filters
r10676 text = text.replace(c, escape)
Jonathan Frederic
Post code-review, extended refactor.
r10485
Jonathan Frederic
Cleanup and refactor of filters
r10676 m = ansi_re.search(text)
Jonathan Frederic
Post code-review, extended refactor.
r10485 opened = False
cmds = []
opener = ''
closer = ''
while m:
cmds = m.groups()[0].split(';')
closer = '</span>' if opened else ''
Jonathan Frederic
Fixed all broken references, refactored some stuff here and there,...
r10624
Jonathan Frederic
Post code-review, extended refactor.
r10485 # True if there is there more than one element in cmds, *or*
# if there is only one but it is not equal to a string of zeroes.
opened = len(cmds) > 1 or cmds[0] != '0' * len(cmds[0])
classes = []
for cmd in cmds:
if cmd in ansi_colormap:
Paul Ivanov
tiny refactor to nbconvert ansi filter...
r16799 classes.append(ansi_colormap[cmd])
Jonathan Frederic
Post code-review, extended refactor.
r10485
if classes:
opener = '<span class="%s">' % (' '.join(classes))
else:
opener = ''
Jonathan Frederic
Cleanup and refactor of filters
r10676 text = re.sub(ansi_re, closer + opener, text, 1)
Jonathan Frederic
Post code-review, extended refactor.
r10485
Jonathan Frederic
Cleanup and refactor of filters
r10676 m = ansi_re.search(text)
Jonathan Frederic
Post code-review, extended refactor.
r10485
if opened:
Jonathan Frederic
Cleanup and refactor of filters
r10676 text += '</span>'
return text
jakobgager
move Ansi related filters to ansi.py
r10943
def single_ansi2latex(code):
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 """Converts single ansi markup to latex format.
jakobgager
move Ansi related filters to ansi.py
r10943
Return latex code and number of open brackets.
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215
Accepts codes like '\x1b[1;32m' (bold, red) and the short form '\x1b[32m' (red)
Colors are matched to those defined in coloransi, which defines colors
using the 0, 1 (bold) and 5 (blinking) styles. Styles 1 and 5 are
interpreted as bold. All other styles are mapped to 0. Note that in
coloransi, a style of 1 does not just mean bold; for example, Brown is
"0;33", but Yellow is "1;33". An empty string is returned for unrecognised
codes and the "reset" code '\x1b[m'.
jakobgager
move Ansi related filters to ansi.py
r10943 """
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 components = code.split(';')
if len(components) > 1:
Richard Everson
Use int style instead of string....
r14783 # Style is digits after '['
style = int(components[0].split('[')[-1])
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 color = components[1][:-1]
else:
Richard Everson
Use int style instead of string....
r14783 style = 0
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 color = components[0][-3:-1]
# If the style is not normal (0), bold (1) or blinking (5) then treat it as normal
Richard Everson
Use int style instead of string....
r14783 if style not in [0, 1, 5]:
style = 0
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215
for name, tcode in coloransi.color_templates:
tstyle, tcolor = tcode.split(';')
Richard Everson
Use int style instead of string....
r14783 tstyle = int(tstyle)
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 if tstyle == style and tcolor == color:
break
else:
return '', 0
Richard Everson
Use int style instead of string....
r14783 if style == 5:
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 name = name[5:] # BlinkRed -> Red, etc
name = name.lower()
Richard Everson
Use int style instead of string....
r14783 if style in [1, 5]:
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 return r'\textbf{\color{'+name+'}', 1
else:
return r'{\color{'+name+'}', 1
jakobgager
move Ansi related filters to ansi.py
r10943
def ansi2latex(text):
"""Converts ansi formated text to latex version
based on https://bitbucket.org/birkenfeld/sphinx-contrib/ansi.py
"""
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 color_pattern = re.compile('\x1b\\[([^m]*)m')
jakobgager
move Ansi related filters to ansi.py
r10943 last_end = 0
openbrack = 0
outstring = ''
for match in color_pattern.finditer(text):
head = text[last_end:match.start()]
outstring += head
if openbrack:
outstring += '}'*openbrack
openbrack = 0
Richard Everson
Deal with ansi escape codes when nbconverting to latex...
r14215 code = match.group()
if not (code == coloransi.TermColors.Normal or openbrack):
texform, openbrack = single_ansi2latex(code)
jakobgager
move Ansi related filters to ansi.py
r10943 outstring += texform
last_end = match.end()
MinRK
fix ansi coloring...
r13441
# Add the remainer of the string and THEN close any remaining color brackets.
Jonathan Frederic
Fix ansi2latex color remainer of string.
r11496 outstring += text[last_end:]
jakobgager
move Ansi related filters to ansi.py
r10943 if openbrack:
outstring += '}'*openbrack
return outstring.strip()