##// END OF EJS Templates
fix ansi coloring...
MinRK -
Show More
@@ -1,157 +1,158 b''
1 1 """Filters for processing ANSI colors within Jinja templates.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2013, the IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 import re
16 16 from IPython.utils import coloransi
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Classes and functions
20 20 #-----------------------------------------------------------------------------
21 21
22 22 __all__ = [
23 23 'strip_ansi',
24 24 'ansi2html',
25 25 'single_ansi2latex',
26 26 'ansi2latex'
27 27 ]
28 28
29 29 def strip_ansi(source):
30 30 """
31 31 Remove ansi from text
32 32
33 33 Parameters
34 34 ----------
35 35 source : str
36 36 Source to remove the ansi from
37 37 """
38 38
39 39 return re.sub(r'\033\[(\d|;)+?m', '', source)
40 40
41 41
42 42 def ansi2html(text):
43 43 """
44 44 Conver ansi colors to html colors.
45 45
46 46 Parameters
47 47 ----------
48 48 text : str
49 49 Text containing ansi colors to convert to html
50 50 """
51 51
52 52 ansi_colormap = {
53 53 '30': 'ansiblack',
54 54 '31': 'ansired',
55 55 '32': 'ansigreen',
56 56 '33': 'ansiyellow',
57 57 '34': 'ansiblue',
58 58 '35': 'ansipurple',
59 59 '36': 'ansicyan',
60 60 '37': 'ansigrey',
61 61 '01': 'ansibold',
62 62 }
63 63
64 64 # do ampersand first
65 65 text = text.replace('&', '&')
66 66 html_escapes = {
67 67 '<': '&lt;',
68 68 '>': '&gt;',
69 69 "'": '&apos;',
70 70 '"': '&quot;',
71 71 '`': '&#96;',
72 72 }
73 73
74 74 for c, escape in html_escapes.items():
75 75 text = text.replace(c, escape)
76 76
77 77 ansi_re = re.compile('\x1b' + r'\[([\dA-Fa-f;]*?)m')
78 78 m = ansi_re.search(text)
79 79 opened = False
80 80 cmds = []
81 81 opener = ''
82 82 closer = ''
83 83 while m:
84 84 cmds = m.groups()[0].split(';')
85 85 closer = '</span>' if opened else ''
86 86
87 87 # True if there is there more than one element in cmds, *or*
88 88 # if there is only one but it is not equal to a string of zeroes.
89 89 opened = len(cmds) > 1 or cmds[0] != '0' * len(cmds[0])
90 90 classes = []
91 91 for cmd in cmds:
92 92 if cmd in ansi_colormap:
93 93 classes.append(ansi_colormap.get(cmd))
94 94
95 95 if classes:
96 96 opener = '<span class="%s">' % (' '.join(classes))
97 97 else:
98 98 opener = ''
99 99 text = re.sub(ansi_re, closer + opener, text, 1)
100 100
101 101 m = ansi_re.search(text)
102 102
103 103 if opened:
104 104 text += '</span>'
105 105 return text
106 106
107 107
108 108 def single_ansi2latex(code):
109 109 """Converts single ansi markup to latex format
110 110
111 111 Return latex code and number of open brackets.
112 112 """
113 113 for color in coloransi.color_templates:
114 114
115 115 #Make sure to get the color code (which is a part of the overall style)
116 116 # i.e. 0;31 is valid
117 117 # 31 is also valid, and means the same thing
118 118 #coloransi.color_templates stores the longer of the two formats %d;%d
119 119 #Get the short format so we can parse that too. Short format only exist
120 120 #if no other formating is applied (the other number must be a 0)!
121 121 style_code = getattr(coloransi.TermColors, color[0])
122 122 color_code = style_code.split(';')[1]
123 123 is_normal = style_code.split(';')[0] == '0'
124 124
125 # regular fonts
125 # regular weight
126 126 if (code == style_code) or (is_normal and code == color_code):
127 return '\\'+color[0].lower()+'{', 1
128 # bold fonts
127
128 return r'{\color{'+color[0].lower()+'}', 1
129 # bold
129 130 if code == style_code[:3]+str(1)+style_code[3:]:
130 return '\\textbf{\\textcolor{'+color[0].lower()+'}{', 2
131 return r'\textbf{\color{'+color[0].lower()+'}', 1
131 132 return '', 0
132 133
133 134 def ansi2latex(text):
134 135 """Converts ansi formated text to latex version
135 136
136 137 based on https://bitbucket.org/birkenfeld/sphinx-contrib/ansi.py
137 138 """
138 139 color_pattern = re.compile('\x1b\\[([^m]+)m')
139 140 last_end = 0
140 141 openbrack = 0
141 142 outstring = ''
142 143 for match in color_pattern.finditer(text):
143 144 head = text[last_end:match.start()]
144 145 outstring += head
145 146 if openbrack:
146 147 outstring += '}'*openbrack
147 148 openbrack = 0
148 149 if not (match.group() == coloransi.TermColors.Normal or openbrack):
149 150 texform, openbrack = single_ansi2latex(match.group())
150 151 outstring += texform
151 152 last_end = match.end()
152
153 #Add the remainer of the string and THEN close any remaining color brackets.
153
154 # Add the remainer of the string and THEN close any remaining color brackets.
154 155 outstring += text[last_end:]
155 156 if openbrack:
156 157 outstring += '}'*openbrack
157 158 return outstring.strip()
General Comments 0
You need to be logged in to leave comments. Login now