4
4
5
5
This includes:
6
6
7
- IPython3Lexer
8
- Lexer for pure IPython (python + magic/shell commands)
7
+ IPythonLexer, IPython3Lexer
8
+ Lexers for pure IPython (python + magic/shell commands)
9
9
10
10
IPythonPartialTracebackLexer, IPythonTracebackLexer
11
- The partial traceback lexer reads everything but the Python code
12
- appearing in a traceback.
13
- The full lexer combines the partial lexer with the IPython3Lexer .
11
+ Supports 2.x and 3.x via keyword `python3`. The partial traceback
12
+ lexer reads everything but the Python code appearing in a traceback.
13
+ The full lexer combines the partial lexer with an IPython lexer .
14
14
15
15
IPythonConsoleLexer
16
16
A lexer for IPython console sessions, with support for tracebacks.
35
35
36
36
# Third party
37
37
from pygments .lexers import (
38
- BashLexer ,
39
- HtmlLexer ,
40
- JavascriptLexer ,
41
- RubyLexer ,
42
- PerlLexer ,
43
- Python3Lexer ,
44
- TexLexer ,
45
- )
38
+ BashLexer , HtmlLexer , JavascriptLexer , RubyLexer , PerlLexer , PythonLexer ,
39
+ Python3Lexer , TexLexer )
46
40
from pygments .lexer import (
47
- Lexer ,
48
- DelegatingLexer ,
49
- RegexLexer ,
50
- do_insertions ,
51
- bygroups ,
52
- using ,
53
- inherit ,
41
+ Lexer , DelegatingLexer , RegexLexer , do_insertions , bygroups , using ,
54
42
)
55
43
from pygments .token import (
56
44
Generic , Keyword , Literal , Name , Operator , Other , Text , Error ,
61
49
62
50
line_re = re .compile ('.*?\n ' )
63
51
64
- __all__ = [
65
- "IPython3Lexer" ,
66
- "IPythonPartialTracebackLexer" ,
67
- "IPythonTracebackLexer" ,
68
- "IPythonConsoleLexer" ,
69
- "IPyLexer" ,
70
- ]
52
+ __all__ = ['build_ipy_lexer' , 'IPython3Lexer' , 'IPythonLexer' ,
53
+ 'IPythonPartialTracebackLexer' , 'IPythonTracebackLexer' ,
54
+ 'IPythonConsoleLexer' , 'IPyLexer' ]
71
55
72
56
73
- class IPython3Lexer ( Python3Lexer ):
74
- """IPython3 Lexer"""
57
+ def build_ipy_lexer ( python3 ):
58
+ """Builds IPython lexers depending on the value of `python3`.
75
59
76
- name = "IPython3"
77
- aliases = ["ipython3" ]
60
+ The lexer inherits from an appropriate Python lexer and then adds
61
+ information about IPython specific keywords (i.e. magic commands,
62
+ shell commands, etc.)
78
63
79
- tokens = {
80
- "root" : [
81
- (
82
- r"(?s)(\s*)(%%capture)([^\n]*\n)(.*)" ,
83
- bygroups (Text , Operator , Text , using (Python3Lexer )),
84
- ),
85
- (
86
- r"(?s)(\s*)(%%debug)([^\n]*\n)(.*)" ,
87
- bygroups (Text , Operator , Text , using (Python3Lexer )),
88
- ),
89
- (
90
- r"(?is)(\s*)(%%html)([^\n]*\n)(.*)" ,
91
- bygroups (Text , Operator , Text , using (HtmlLexer )),
92
- ),
93
- (
94
- r"(?s)(\s*)(%%javascript)([^\n]*\n)(.*)" ,
95
- bygroups (Text , Operator , Text , using (JavascriptLexer )),
96
- ),
97
- (
98
- r"(?s)(\s*)(%%js)([^\n]*\n)(.*)" ,
99
- bygroups (Text , Operator , Text , using (JavascriptLexer )),
100
- ),
101
- (
102
- r"(?s)(\s*)(%%latex)([^\n]*\n)(.*)" ,
103
- bygroups (Text , Operator , Text , using (TexLexer )),
104
- ),
105
- (
106
- r"(?s)(\s*)(%%perl)([^\n]*\n)(.*)" ,
107
- bygroups (Text , Operator , Text , using (PerlLexer )),
108
- ),
109
- (
110
- r"(?s)(\s*)(%%prun)([^\n]*\n)(.*)" ,
111
- bygroups (Text , Operator , Text , using (Python3Lexer )),
112
- ),
113
- (
114
- r"(?s)(\s*)(%%pypy)([^\n]*\n)(.*)" ,
115
- bygroups (Text , Operator , Text , using (Python3Lexer )),
116
- ),
117
- (
118
- r"(?s)(\s*)(%%python)([^\n]*\n)(.*)" ,
119
- bygroups (Text , Operator , Text , using (Python3Lexer )),
120
- ),
121
- (
122
- r"(?s)(\s*)(%%python3)([^\n]*\n)(.*)" ,
123
- bygroups (Text , Operator , Text , using (Python3Lexer )),
124
- ),
125
- (
126
- r"(?s)(\s*)(%%ruby)([^\n]*\n)(.*)" ,
127
- bygroups (Text , Operator , Text , using (RubyLexer )),
128
- ),
129
- (
130
- r"(?s)(\s*)(%%time)([^\n]*\n)(.*)" ,
131
- bygroups (Text , Operator , Text , using (Python3Lexer )),
132
- ),
133
- (
134
- r"(?s)(\s*)(%%timeit)([^\n]*\n)(.*)" ,
135
- bygroups (Text , Operator , Text , using (Python3Lexer )),
136
- ),
137
- (
138
- r"(?s)(\s*)(%%writefile)([^\n]*\n)(.*)" ,
139
- bygroups (Text , Operator , Text , using (Python3Lexer )),
140
- ),
141
- (
142
- r"(?s)(\s*)(%%file)([^\n]*\n)(.*)" ,
143
- bygroups (Text , Operator , Text , using (Python3Lexer )),
144
- ),
145
- (r"(?s)(\s*)(%%)(\w+)(.*)" , bygroups (Text , Operator , Keyword , Text )),
146
- (
147
- r"(?s)(^\s*)(%%!)([^\n]*\n)(.*)" ,
148
- bygroups (Text , Operator , Text , using (BashLexer )),
149
- ),
150
- (r"(%%?)(\w+)(\?\??)$" , bygroups (Operator , Keyword , Operator )),
151
- (r"\b(\?\??)(\s*)$" , bygroups (Operator , Text )),
152
- (
153
- r"(%)(sx|sc|system)(.*)(\n)" ,
154
- bygroups (Operator , Keyword , using (BashLexer ), Text ),
155
- ),
156
- (r"(%)(\w+)(.*\n)" , bygroups (Operator , Keyword , Text )),
157
- (r"^(!!)(.+)(\n)" , bygroups (Operator , using (BashLexer ), Text )),
158
- (r"(!)(?!=)(.+)(\n)" , bygroups (Operator , using (BashLexer ), Text )),
159
- (r"^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)" , bygroups (Text , Operator , Text )),
160
- (r"(\s*%{0,2}[\w\.\*]*)(\?\??)(\s*)$" , bygroups (Text , Operator , Text )),
161
- inherit ,
162
- ]
163
- }
64
+ Parameters
65
+ ----------
66
+ python3 : bool
67
+ If `True`, then build an IPython lexer from a Python 3 lexer.
68
+
69
+ """
70
+ # It would be nice to have a single IPython lexer class which takes
71
+ # a boolean `python3`. But since there are two Python lexer classes,
72
+ # we will also have two IPython lexer classes.
73
+ if python3 :
74
+ PyLexer = Python3Lexer
75
+ name = 'IPython3'
76
+ aliases = ['ipython3' ]
77
+ doc = """IPython3 Lexer"""
78
+ else :
79
+ PyLexer = PythonLexer
80
+ name = 'IPython'
81
+ aliases = ['ipython2' , 'ipython' ]
82
+ doc = """IPython Lexer"""
83
+
84
+ ipython_tokens = [
85
+ (r'(?s)(\s*)(%%capture)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
86
+ (r'(?s)(\s*)(%%debug)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
87
+ (r'(?is)(\s*)(%%html)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (HtmlLexer ))),
88
+ (r'(?s)(\s*)(%%javascript)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (JavascriptLexer ))),
89
+ (r'(?s)(\s*)(%%js)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (JavascriptLexer ))),
90
+ (r'(?s)(\s*)(%%latex)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (TexLexer ))),
91
+ (r'(?s)(\s*)(%%perl)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PerlLexer ))),
92
+ (r'(?s)(\s*)(%%prun)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
93
+ (r'(?s)(\s*)(%%pypy)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
94
+ (r'(?s)(\s*)(%%python)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
95
+ (r'(?s)(\s*)(%%python2)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PythonLexer ))),
96
+ (r'(?s)(\s*)(%%python3)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (Python3Lexer ))),
97
+ (r'(?s)(\s*)(%%ruby)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (RubyLexer ))),
98
+ (r'(?s)(\s*)(%%time)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
99
+ (r'(?s)(\s*)(%%timeit)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
100
+ (r'(?s)(\s*)(%%writefile)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
101
+ (r'(?s)(\s*)(%%file)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (PyLexer ))),
102
+ (r"(?s)(\s*)(%%)(\w+)(.*)" , bygroups (Text , Operator , Keyword , Text )),
103
+ (r'(?s)(^\s*)(%%!)([^\n]*\n)(.*)' , bygroups (Text , Operator , Text , using (BashLexer ))),
104
+ (r"(%%?)(\w+)(\?\??)$" , bygroups (Operator , Keyword , Operator )),
105
+ (r"\b(\?\??)(\s*)$" , bygroups (Operator , Text )),
106
+ (r'(%)(sx|sc|system)(.*)(\n)' , bygroups (Operator , Keyword ,
107
+ using (BashLexer ), Text )),
108
+ (r'(%)(\w+)(.*\n)' , bygroups (Operator , Keyword , Text )),
109
+ (r'^(!!)(.+)(\n)' , bygroups (Operator , using (BashLexer ), Text )),
110
+ (r'(!)(?!=)(.+)(\n)' , bygroups (Operator , using (BashLexer ), Text )),
111
+ (r'^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)' , bygroups (Text , Operator , Text )),
112
+ (r'(\s*%{0,2}[\w\.\*]*)(\?\??)(\s*)$' , bygroups (Text , Operator , Text )),
113
+ ]
114
+
115
+ tokens = PyLexer .tokens .copy ()
116
+ tokens ['root' ] = ipython_tokens + tokens ['root' ]
117
+
118
+ attrs = {'name' : name , 'aliases' : aliases , 'filenames' : [],
119
+ '__doc__' : doc , 'tokens' : tokens }
120
+
121
+ return type (name , (PyLexer ,), attrs )
122
+
123
+
124
+ IPython3Lexer = build_ipy_lexer (python3 = True )
125
+ IPythonLexer = build_ipy_lexer (python3 = False )
164
126
165
127
166
128
class IPythonPartialTracebackLexer (RegexLexer ):
@@ -222,9 +184,9 @@ class IPythonTracebackLexer(DelegatingLexer):
222
184
this is the line which lists the File and line number.
223
185
224
186
"""
225
-
226
- # The lexer inherits from DelegatingLexer. The "root" lexer is the
227
- # IPython3 lexer. First, we parse with the partial IPython traceback lexer.
187
+ # The lexer inherits from DelegatingLexer. The "root" lexer is an
188
+ # appropriate IPython lexer, which depends on the value of the boolean
189
+ # `python3`. First, we parse with the partial IPython traceback lexer.
228
190
# Then, any code marked with the "Other" token is delegated to the root
229
191
# lexer.
230
192
#
@@ -239,9 +201,19 @@ def __init__(self, **options):
239
201
# note we need a __init__ doc, as otherwise it inherits the doc from the super class
240
202
# which will fail the documentation build as it references section of the pygments docs that
241
203
# do not exists when building IPython's docs.
204
+ self .python3 = get_bool_opt (options , 'python3' , False )
205
+ if self .python3 :
206
+ self .aliases = ['ipython3tb' ]
207
+ else :
208
+ self .aliases = ['ipython2tb' , 'ipythontb' ]
242
209
243
- super ().__init__ (IPython3Lexer , IPythonPartialTracebackLexer , ** options )
210
+ if self .python3 :
211
+ IPyLexer = IPython3Lexer
212
+ else :
213
+ IPyLexer = IPythonLexer
244
214
215
+ DelegatingLexer .__init__ (self , IPyLexer ,
216
+ IPythonPartialTracebackLexer , ** options )
245
217
246
218
class IPythonConsoleLexer (Lexer ):
247
219
"""
@@ -283,8 +255,8 @@ class IPythonConsoleLexer(Lexer):
283
255
# continuation = ' .D.: '
284
256
# template = 'Out[#]: '
285
257
#
286
- # Where '#' is the 'prompt number' or 'execution count' and 'D'
287
- # D is a number of dots matching the width of the execution count
258
+ # Where '#' is the 'prompt number' or 'execution count' and 'D'
259
+ # D is a number of dots matching the width of the execution count
288
260
#
289
261
in1_regex = r'In \[[0-9]+\]: '
290
262
in2_regex = r' \.\.+\.: '
@@ -298,6 +270,9 @@ def __init__(self, **options):
298
270
299
271
Parameters
300
272
----------
273
+ python3 : bool
274
+ If `True`, then the console inputs are parsed using a Python 3
275
+ lexer. Otherwise, they are parsed using a Python 2 lexer.
301
276
in1_regex : RegexObject
302
277
The compiled regular expression used to detect the start
303
278
of inputs. Although the IPython configuration setting may have a
@@ -313,7 +288,11 @@ def __init__(self, **options):
313
288
then the default output prompt is assumed.
314
289
315
290
"""
316
- self .aliases = ["ipython3console" ]
291
+ self .python3 = get_bool_opt (options , 'python3' , False )
292
+ if self .python3 :
293
+ self .aliases = ['ipython3console' ]
294
+ else :
295
+ self .aliases = ['ipython2console' , 'ipythonconsole' ]
317
296
318
297
in1_regex = options .get ('in1_regex' , self .in1_regex )
319
298
in2_regex = options .get ('in2_regex' , self .in2_regex )
@@ -339,8 +318,15 @@ def __init__(self, **options):
339
318
340
319
Lexer .__init__ (self , ** options )
341
320
342
- self .pylexer = IPython3Lexer (** options )
343
- self .tblexer = IPythonTracebackLexer (** options )
321
+ if self .python3 :
322
+ pylexer = IPython3Lexer
323
+ tblexer = IPythonTracebackLexer
324
+ else :
325
+ pylexer = IPythonLexer
326
+ tblexer = IPythonTracebackLexer
327
+
328
+ self .pylexer = pylexer (** options )
329
+ self .tblexer = tblexer (** options )
344
330
345
331
self .reset ()
346
332
@@ -526,16 +512,20 @@ class IPyLexer(Lexer):
526
512
def __init__ (self , ** options ):
527
513
"""
528
514
Create a new IPyLexer instance which dispatch to either an
529
- IPythonConsoleLexer (if In prompts are present) or and IPython3Lexer (if
515
+ IPythonCOnsoleLexer (if In prompts are present) or and IPythonLexer (if
530
516
In prompts are not present).
531
517
"""
532
518
# init docstring is necessary for docs not to fail to build do to parent
533
519
# docs referenceing a section in pygments docs.
534
- self .aliases = ["ipy3" ]
520
+ self .python3 = get_bool_opt (options , 'python3' , False )
521
+ if self .python3 :
522
+ self .aliases = ['ipy3' ]
523
+ else :
524
+ self .aliases = ['ipy2' , 'ipy' ]
535
525
536
526
Lexer .__init__ (self , ** options )
537
527
538
- self .IPythonLexer = IPython3Lexer (** options )
528
+ self .IPythonLexer = IPythonLexer (** options )
539
529
self .IPythonConsoleLexer = IPythonConsoleLexer (** options )
540
530
541
531
def get_tokens_unprocessed (self , text ):
@@ -547,3 +537,4 @@ def get_tokens_unprocessed(self, text):
547
537
lex = self .IPythonLexer
548
538
for token in lex .get_tokens_unprocessed (text ):
549
539
yield token
540
+
0 commit comments