##// END OF EJS Templates
Fix, ansi2latex style-less code support...
Jonathan Frederic -
Show More
@@ -1,145 +1,155 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 'remove_ansi',
24 24 'ansi2html',
25 25 'single_ansi2latex',
26 26 'ansi2latex'
27 27 ]
28 28
29 29 def remove_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.iteritems():
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 colcode = getattr(coloransi.TermColors,color[0])
114
115 #Make sure to get the color code (which is a part of the overall style)
116 # i.e. 0;31 is valid
117 # 31 is also valid, and means the same thing
118 #coloransi.color_templates stores the longer of the two formats %d;%d
119 #Get the short format so we can parse that too. Short format only exist
120 #if no other formating is applied (the other number must be a 0)!
121 style_code = getattr(coloransi.TermColors, color[0])
122 color_code = style_code.split(';')[1]
123 is_normal = style_code.split(';')[0] == '0'
124
115 125 # regular fonts
116 if code == colcode:
126 if (code == style_code) or (is_normal and code == color_code):
117 127 return '\\'+color[0].lower()+'{', 1
118 128 # bold fonts
119 if code == colcode[:3]+str(1)+colcode[3:]:
129 if code == style_code[:3]+str(1)+style_code[3:]:
120 130 return '\\textbf{\\textcolor{'+color[0].lower()+'}{', 2
121 131 return '', 0
122 132
123 133 def ansi2latex(text):
124 134 """Converts ansi formated text to latex version
125 135
126 136 based on https://bitbucket.org/birkenfeld/sphinx-contrib/ansi.py
127 137 """
128 138 color_pattern = re.compile('\x1b\\[([^m]+)m')
129 139 last_end = 0
130 140 openbrack = 0
131 141 outstring = ''
132 142 for match in color_pattern.finditer(text):
133 143 head = text[last_end:match.start()]
134 144 outstring += head
135 145 if openbrack:
136 146 outstring += '}'*openbrack
137 147 openbrack = 0
138 148 if match.group() <> coloransi.TermColors.Normal and not openbrack:
139 149 texform, openbrack = single_ansi2latex(match.group())
140 150 outstring += texform
141 151 last_end = match.end()
142 152 if openbrack:
143 153 outstring += '}'*openbrack
144 154 outstring += text[last_end:]
145 155 return outstring.strip()
General Comments 0
You need to be logged in to leave comments. Login now