##// END OF EJS Templates
Move IPython lexers module to lib...
Thomas Kluyver -
Show More
This diff has been collapsed as it changes many lines, (512 lines changed) Show them Hide them
@@ -0,0 +1,512 b''
1 # -*- coding: utf-8 -*-
2 """
3 Defines a variety of Pygments lexers for highlighting IPython code.
4
5 This includes:
6
7 IPythonLexer, IPython3Lexer
8 Lexers for pure IPython (python + magic/shell commands)
9
10 IPythonPartialTracebackLexer, IPythonTracebackLexer
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
15 IPythonConsoleLexer
16 A lexer for IPython console sessions, with support for tracebacks.
17
18 IPyLexer
19 A friendly lexer which examines the first line of text and from it,
20 decides whether to use an IPython lexer or an IPython console lexer.
21 This is probably the only lexer that needs to be explicitly added
22 to Pygments.
23
24 """
25 #-----------------------------------------------------------------------------
26 # Copyright (c) 2013, the IPython Development Team.
27 #
28 # Distributed under the terms of the Modified BSD License.
29 #
30 # The full license is in the file COPYING.txt, distributed with this software.
31 #-----------------------------------------------------------------------------
32
33 # Standard library
34 import re
35
36 # Third party
37 from pygments.lexers import BashLexer, PythonLexer, Python3Lexer
38 from pygments.lexer import (
39 Lexer, DelegatingLexer, RegexLexer, do_insertions, bygroups, using,
40 )
41 from pygments.token import (
42 Comment, Generic, Keyword, Literal, Name, Operator, Other, Text, Error,
43 )
44 from pygments.util import get_bool_opt
45
46 # Local
47 from IPython.testing.skipdoctest import skip_doctest
48
49 line_re = re.compile('.*?\n')
50
51 __all__ = ['build_ipy_lexer', 'IPython3Lexer', 'IPythonLexer',
52 'IPythonPartialTracebackLexer', 'IPythonTracebackLexer',
53 'IPythonConsoleLexer', 'IPyLexer']
54
55 ipython_tokens = [
56 (r"(?s)(\s*)(%%)(\w+)(.*)", bygroups(Text, Operator, Keyword, Text)),
57 (r'(?s)(^\s*)(%%!)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(BashLexer))),
58 (r"(%%?)(\w+)(\?\??)$", bygroups(Operator, Keyword, Operator)),
59 (r"\b(\?\??)(\s*)$", bygroups(Operator, Text)),
60 (r'(%)(sx|sc|system)(.*)(\n)', bygroups(Operator, Keyword,
61 using(BashLexer), Text)),
62 (r'(%)(\w+)(.*\n)', bygroups(Operator, Keyword, Text)),
63 (r'^(!!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
64 (r'(!)(?!=)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
65 (r'^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)', bygroups(Text, Operator, Text)),
66 ]
67
68 def build_ipy_lexer(python3):
69 """Builds IPython lexers depending on the value of `python3`.
70
71 The lexer inherits from an appropriate Python lexer and then adds
72 information about IPython specific keywords (i.e. magic commands,
73 shell commands, etc.)
74
75 Parameters
76 ----------
77 python3 : bool
78 If `True`, then build an IPython lexer from a Python 3 lexer.
79
80 """
81 # It would be nice to have a single IPython lexer class which takes
82 # a boolean `python3`. But since there are two Python lexer classes,
83 # we will also have two IPython lexer classes.
84 if python3:
85 PyLexer = Python3Lexer
86 clsname = 'IPython3Lexer'
87 name = 'IPython3'
88 aliases = ['ipython3']
89 doc = """IPython3 Lexer"""
90 else:
91 PyLexer = PythonLexer
92 clsname = 'IPythonLexer'
93 name = 'IPython'
94 aliases = ['ipython2', 'ipython']
95 doc = """IPython Lexer"""
96
97 tokens = PyLexer.tokens.copy()
98 tokens['root'] = ipython_tokens + tokens['root']
99
100 attrs = {'name': name, 'aliases': aliases, 'filenames': [],
101 '__doc__': doc, 'tokens': tokens}
102
103 return type(name, (PyLexer,), attrs)
104
105
106 IPython3Lexer = build_ipy_lexer(python3=True)
107 IPythonLexer = build_ipy_lexer(python3=False)
108
109
110 class IPythonPartialTracebackLexer(RegexLexer):
111 """
112 Partial lexer for IPython tracebacks.
113
114 Handles all the non-python output. This works for both Python 2.x and 3.x.
115
116 """
117 name = 'IPython Partial Traceback'
118
119 tokens = {
120 'root': [
121 # Tracebacks for syntax errors have a different style.
122 # For both types of tracebacks, we mark the first line with
123 # Generic.Traceback. For syntax errors, we mark the filename
124 # as we mark the filenames for non-syntax tracebacks.
125 #
126 # These two regexps define how IPythonConsoleLexer finds a
127 # traceback.
128 #
129 ## Non-syntax traceback
130 (r'^(\^C)?(-+\n)', bygroups(Error, Generic.Traceback)),
131 ## Syntax traceback
132 (r'^( File)(.*)(, line )(\d+\n)',
133 bygroups(Generic.Traceback, Name.Namespace,
134 Generic.Traceback, Literal.Number.Integer)),
135
136 # (Exception Identifier)(Whitespace)(Traceback Message)
137 (r'(?u)(^[^\d\W]\w*)(\s*)(Traceback.*?\n)',
138 bygroups(Name.Exception, Generic.Whitespace, Text)),
139 # (Module/Filename)(Text)(Callee)(Function Signature)
140 # Better options for callee and function signature?
141 (r'(.*)( in )(.*)(\(.*\)\n)',
142 bygroups(Name.Namespace, Text, Name.Entity, Name.Tag)),
143 # Regular line: (Whitespace)(Line Number)(Python Code)
144 (r'(\s*?)(\d+)(.*?\n)',
145 bygroups(Generic.Whitespace, Literal.Number.Integer, Other)),
146 # Emphasized line: (Arrow)(Line Number)(Python Code)
147 # Using Exception token so arrow color matches the Exception.
148 (r'(-*>?\s?)(\d+)(.*?\n)',
149 bygroups(Name.Exception, Literal.Number.Integer, Other)),
150 # (Exception Identifier)(Message)
151 (r'(?u)(^[^\d\W]\w*)(:.*?\n)',
152 bygroups(Name.Exception, Text)),
153 # Tag everything else as Other, will be handled later.
154 (r'.*\n', Other),
155 ],
156 }
157
158
159 class IPythonTracebackLexer(DelegatingLexer):
160 """
161 IPython traceback lexer.
162
163 For doctests, the tracebacks can be snipped as much as desired with the
164 exception to the lines that designate a traceback. For non-syntax error
165 tracebacks, this is the line of hyphens. For syntax error tracebacks,
166 this is the line which lists the File and line number.
167
168 """
169 # The lexer inherits from DelegatingLexer. The "root" lexer is an
170 # appropriate IPython lexer, which depends on the value of the boolean
171 # `python3`. First, we parse with the partial IPython traceback lexer.
172 # Then, any code marked with the "Other" token is delegated to the root
173 # lexer.
174 #
175 name = 'IPython Traceback'
176 aliases = ['ipythontb']
177
178 def __init__(self, **options):
179 self.python3 = get_bool_opt(options, 'python3', False)
180 if self.python3:
181 self.aliases = ['ipython3tb']
182 else:
183 self.aliases = ['ipython2tb', 'ipythontb']
184
185 if self.python3:
186 IPyLexer = IPython3Lexer
187 else:
188 IPyLexer = IPythonLexer
189
190 DelegatingLexer.__init__(self, IPyLexer,
191 IPythonPartialTracebackLexer, **options)
192
193 @skip_doctest
194 class IPythonConsoleLexer(Lexer):
195 """
196 An IPython console lexer for IPython code-blocks and doctests, such as:
197
198 .. code-block:: rst
199
200 .. code-block:: ipythonconsole
201
202 In [1]: a = 'foo'
203
204 In [2]: a
205 Out[2]: 'foo'
206
207 In [3]: print a
208 foo
209
210 In [4]: 1 / 0
211
212
213 Support is also provided for IPython exceptions:
214
215 .. code-block:: rst
216
217 .. code-block:: ipythonconsole
218
219 In [1]: raise Exception
220
221 ---------------------------------------------------------------------------
222 Exception Traceback (most recent call last)
223 <ipython-input-1-fca2ab0ca76b> in <module>()
224 ----> 1 raise Exception
225
226 Exception:
227
228 """
229 name = 'IPython console session'
230 aliases = ['ipythonconsole']
231 mimetypes = ['text/x-ipython-console']
232
233 # The regexps used to determine what is input and what is output.
234 # The default prompts for IPython are:
235 #
236 # c.PromptManager.in_template = 'In [\#]: '
237 # c.PromptManager.in2_template = ' .\D.: '
238 # c.PromptManager.out_template = 'Out[\#]: '
239 #
240 in1_regex = r'In \[[0-9]+\]: '
241 in2_regex = r' \.\.+\.: '
242 out_regex = r'Out\[[0-9]+\]: '
243
244 #: The regex to determine when a traceback starts.
245 ipytb_start = re.compile(r'^(\^C)?(-+\n)|^( File)(.*)(, line )(\d+\n)')
246
247 def __init__(self, **options):
248 """Initialize the IPython console lexer.
249
250 Parameters
251 ----------
252 python3 : bool
253 If `True`, then the console inputs are parsed using a Python 3
254 lexer. Otherwise, they are parsed using a Python 2 lexer.
255 in1_regex : RegexObject
256 The compiled regular expression used to detect the start
257 of inputs. Although the IPython configuration setting may have a
258 trailing whitespace, do not include it in the regex. If `None`,
259 then the default input prompt is assumed.
260 in2_regex : RegexObject
261 The compiled regular expression used to detect the continuation
262 of inputs. Although the IPython configuration setting may have a
263 trailing whitespace, do not include it in the regex. If `None`,
264 then the default input prompt is assumed.
265 out_regex : RegexObject
266 The compiled regular expression used to detect outputs. If `None`,
267 then the default output prompt is assumed.
268
269 """
270 self.python3 = get_bool_opt(options, 'python3', False)
271 if self.python3:
272 self.aliases = ['ipython3console']
273 else:
274 self.aliases = ['ipython2console', 'ipythonconsole']
275
276 in1_regex = options.get('in1_regex', self.in1_regex)
277 in2_regex = options.get('in2_regex', self.in2_regex)
278 out_regex = options.get('out_regex', self.out_regex)
279
280 # So that we can work with input and output prompts which have been
281 # rstrip'd (possibly by editors) we also need rstrip'd variants. If
282 # we do not do this, then such prompts will be tagged as 'output'.
283 # The reason can't just use the rstrip'd variants instead is because
284 # we want any whitespace associated with the prompt to be inserted
285 # with the token. This allows formatted code to be modified so as hide
286 # the appearance of prompts, with the whitespace included. One example
287 # use of this is in copybutton.js from the standard lib Python docs.
288 in1_regex_rstrip = in1_regex.rstrip() + '\n'
289 in2_regex_rstrip = in2_regex.rstrip() + '\n'
290 out_regex_rstrip = out_regex.rstrip() + '\n'
291
292 # Compile and save them all.
293 attrs = ['in1_regex', 'in2_regex', 'out_regex',
294 'in1_regex_rstrip', 'in2_regex_rstrip', 'out_regex_rstrip']
295 for attr in attrs:
296 self.__setattr__(attr, re.compile(locals()[attr]))
297
298 Lexer.__init__(self, **options)
299
300 if self.python3:
301 pylexer = IPython3Lexer
302 tblexer = IPythonTracebackLexer
303 else:
304 pylexer = IPythonLexer
305 tblexer = IPythonTracebackLexer
306
307 self.pylexer = pylexer(**options)
308 self.tblexer = tblexer(**options)
309
310 self.reset()
311
312 def reset(self):
313 self.mode = 'output'
314 self.index = 0
315 self.buffer = u''
316 self.insertions = []
317
318 def buffered_tokens(self):
319 """
320 Generator of unprocessed tokens after doing insertions and before
321 changing to a new state.
322
323 """
324 if self.mode == 'output':
325 tokens = [(0, Generic.Output, self.buffer)]
326 elif self.mode == 'input':
327 tokens = self.pylexer.get_tokens_unprocessed(self.buffer)
328 else: # traceback
329 tokens = self.tblexer.get_tokens_unprocessed(self.buffer)
330
331 for i, t, v in do_insertions(self.insertions, tokens):
332 # All token indexes are relative to the buffer.
333 yield self.index + i, t, v
334
335 # Clear it all
336 self.index += len(self.buffer)
337 self.buffer = u''
338 self.insertions = []
339
340 def get_mci(self, line):
341 """
342 Parses the line and returns a 3-tuple: (mode, code, insertion).
343
344 `mode` is the next mode (or state) of the lexer, and is always equal
345 to 'input', 'output', or 'tb'.
346
347 `code` is a portion of the line that should be added to the buffer
348 corresponding to the next mode and eventually lexed by another lexer.
349 For example, `code` could be Python code if `mode` were 'input'.
350
351 `insertion` is a 3-tuple (index, token, text) representing an
352 unprocessed "token" that will be inserted into the stream of tokens
353 that are created from the buffer once we change modes. This is usually
354 the input or output prompt.
355
356 In general, the next mode depends on current mode and on the contents
357 of `line`.
358
359 """
360 # To reduce the number of regex match checks, we have multiple
361 # 'if' blocks instead of 'if-elif' blocks.
362
363 # Check for possible end of input
364 in2_match = self.in2_regex.match(line)
365 in2_match_rstrip = self.in2_regex_rstrip.match(line)
366 if (in2_match and in2_match.group().rstrip() == line.rstrip()) or \
367 in2_match_rstrip:
368 end_input = True
369 else:
370 end_input = False
371 if end_input and self.mode != 'tb':
372 # Only look for an end of input when not in tb mode.
373 # An ellipsis could appear within the traceback.
374 mode = 'output'
375 code = u''
376 insertion = (0, Generic.Prompt, line)
377 return mode, code, insertion
378
379 # Check for output prompt
380 out_match = self.out_regex.match(line)
381 out_match_rstrip = self.out_regex_rstrip.match(line)
382 if out_match or out_match_rstrip:
383 mode = 'output'
384 if out_match:
385 idx = out_match.end()
386 else:
387 idx = out_match_rstrip.end()
388 code = line[idx:]
389 # Use the 'heading' token for output. We cannot use Generic.Error
390 # since it would conflict with exceptions.
391 insertion = (0, Generic.Heading, line[:idx])
392 return mode, code, insertion
393
394
395 # Check for input or continuation prompt (non stripped version)
396 in1_match = self.in1_regex.match(line)
397 if in1_match or (in2_match and self.mode != 'tb'):
398 # New input or when not in tb, continued input.
399 # We do not check for continued input when in tb since it is
400 # allowable to replace a long stack with an ellipsis.
401 mode = 'input'
402 if in1_match:
403 idx = in1_match.end()
404 else: # in2_match
405 idx = in2_match.end()
406 code = line[idx:]
407 insertion = (0, Generic.Prompt, line[:idx])
408 return mode, code, insertion
409
410 # Check for input or continuation prompt (stripped version)
411 in1_match_rstrip = self.in1_regex_rstrip.match(line)
412 if in1_match_rstrip or (in2_match_rstrip and self.mode != 'tb'):
413 # New input or when not in tb, continued input.
414 # We do not check for continued input when in tb since it is
415 # allowable to replace a long stack with an ellipsis.
416 mode = 'input'
417 if in1_match_rstrip:
418 idx = in1_match_rstrip.end()
419 else: # in2_match
420 idx = in2_match_rstrip.end()
421 code = line[idx:]
422 insertion = (0, Generic.Prompt, line[:idx])
423 return mode, code, insertion
424
425 # Check for traceback
426 if self.ipytb_start.match(line):
427 mode = 'tb'
428 code = line
429 insertion = None
430 return mode, code, insertion
431
432 # All other stuff...
433 if self.mode in ('input', 'output'):
434 # We assume all other text is output. Multiline input that
435 # does not use the continuation marker cannot be detected.
436 # For example, the 3 in the following is clearly output:
437 #
438 # In [1]: print 3
439 # 3
440 #
441 # But the following second line is part of the input:
442 #
443 # In [2]: while True:
444 # print True
445 #
446 # In both cases, the 2nd line will be 'output'.
447 #
448 mode = 'output'
449 else:
450 mode = 'tb'
451
452 code = line
453 insertion = None
454
455 return mode, code, insertion
456
457 def get_tokens_unprocessed(self, text):
458 self.reset()
459 for match in line_re.finditer(text):
460 line = match.group()
461 mode, code, insertion = self.get_mci(line)
462
463 if mode != self.mode:
464 # Yield buffered tokens before transitioning to new mode.
465 for token in self.buffered_tokens():
466 yield token
467 self.mode = mode
468
469 if insertion:
470 self.insertions.append((len(self.buffer), [insertion]))
471 self.buffer += code
472 else:
473 for token in self.buffered_tokens():
474 yield token
475
476 class IPyLexer(Lexer):
477 """
478 Primary lexer for all IPython-like code.
479
480 This is a simple helper lexer. If the first line of the text begins with
481 "In \[[0-9]+\]:", then the entire text is parsed with an IPython console
482 lexer. If not, then the entire text is parsed with an IPython lexer.
483
484 The goal is to reduce the number of lexers that are registered
485 with Pygments.
486
487 """
488 name = 'IPy session'
489 aliases = ['ipy']
490
491 def __init__(self, **options):
492 self.python3 = get_bool_opt(options, 'python3', False)
493 if self.python3:
494 self.aliases = ['ipy3']
495 else:
496 self.aliases = ['ipy2', 'ipy']
497
498 Lexer.__init__(self, **options)
499
500 self.IPythonLexer = IPythonLexer(**options)
501 self.IPythonConsoleLexer = IPythonConsoleLexer(**options)
502
503 def get_tokens_unprocessed(self, text):
504 # Search for the input prompt anywhere...this allows code blocks to
505 # begin with comments as well.
506 if re.match(r'.*(In \[[0-9]+\]:)', text.strip(), re.DOTALL):
507 lex = self.IPythonConsoleLexer
508 else:
509 lex = self.IPythonLexer
510 for token in lex.get_tokens_unprocessed(text):
511 yield token
512
@@ -1,135 +1,135 b''
1 """
1 """
2 Module containing filter functions that allow code to be highlighted
2 Module containing filter functions that allow code to be highlighted
3 from within Jinja templates.
3 from within Jinja templates.
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 # pygments must not be imported at the module level
9 # pygments must not be imported at the module level
10 # because errors should be raised at runtime if it's actually needed,
10 # because errors should be raised at runtime if it's actually needed,
11 # not import time, when it may not be needed.
11 # not import time, when it may not be needed.
12
12
13 from IPython.nbconvert.utils.base import NbConvertBase
13 from IPython.nbconvert.utils.base import NbConvertBase
14 from warnings import warn
14 from warnings import warn
15
15
16 MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
16 MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
17
17
18 __all__ = [
18 __all__ = [
19 'Highlight2HTML',
19 'Highlight2HTML',
20 'Highlight2Latex'
20 'Highlight2Latex'
21 ]
21 ]
22
22
23 class Highlight2HTML(NbConvertBase):
23 class Highlight2HTML(NbConvertBase):
24 def __init__(self, pygments_lexer=None, **kwargs):
24 def __init__(self, pygments_lexer=None, **kwargs):
25 self.pygments_lexer = pygments_lexer or 'ipython3'
25 self.pygments_lexer = pygments_lexer or 'ipython3'
26 super(Highlight2HTML, self).__init__(**kwargs)
26 super(Highlight2HTML, self).__init__(**kwargs)
27
27
28 def _default_language_changed(self, name, old, new):
28 def _default_language_changed(self, name, old, new):
29 warn('Setting default_language in config is deprecated, '
29 warn('Setting default_language in config is deprecated, '
30 'please use language_info metadata instead.')
30 'please use language_info metadata instead.')
31 self.pygments_lexer = new
31 self.pygments_lexer = new
32
32
33 def __call__(self, source, language=None, metadata=None):
33 def __call__(self, source, language=None, metadata=None):
34 """
34 """
35 Return a syntax-highlighted version of the input source as html output.
35 Return a syntax-highlighted version of the input source as html output.
36
36
37 Parameters
37 Parameters
38 ----------
38 ----------
39 source : str
39 source : str
40 source of the cell to highlight
40 source of the cell to highlight
41 language : str
41 language : str
42 language to highlight the syntax of
42 language to highlight the syntax of
43 metadata : NotebookNode cell metadata
43 metadata : NotebookNode cell metadata
44 metadata of the cell to highlight
44 metadata of the cell to highlight
45 """
45 """
46 from pygments.formatters import HtmlFormatter
46 from pygments.formatters import HtmlFormatter
47
47
48 if not language:
48 if not language:
49 language=self.pygments_lexer
49 language=self.pygments_lexer
50
50
51 return _pygments_highlight(source if len(source) > 0 else ' ',
51 return _pygments_highlight(source if len(source) > 0 else ' ',
52 # needed to help post processors:
52 # needed to help post processors:
53 HtmlFormatter(cssclass=" highlight hl-"+language),
53 HtmlFormatter(cssclass=" highlight hl-"+language),
54 language, metadata)
54 language, metadata)
55
55
56
56
57 class Highlight2Latex(NbConvertBase):
57 class Highlight2Latex(NbConvertBase):
58 def __init__(self, pygments_lexer=None, **kwargs):
58 def __init__(self, pygments_lexer=None, **kwargs):
59 self.pygments_lexer = pygments_lexer or 'ipython3'
59 self.pygments_lexer = pygments_lexer or 'ipython3'
60 super(Highlight2Latex, self).__init__(**kwargs)
60 super(Highlight2Latex, self).__init__(**kwargs)
61
61
62 def _default_language_changed(self, name, old, new):
62 def _default_language_changed(self, name, old, new):
63 warn('Setting default_language in config is deprecated, '
63 warn('Setting default_language in config is deprecated, '
64 'please use language_info metadata instead.')
64 'please use language_info metadata instead.')
65 self.pygments_lexer = new
65 self.pygments_lexer = new
66
66
67 def __call__(self, source, language=None, metadata=None, strip_verbatim=False):
67 def __call__(self, source, language=None, metadata=None, strip_verbatim=False):
68 """
68 """
69 Return a syntax-highlighted version of the input source as latex output.
69 Return a syntax-highlighted version of the input source as latex output.
70
70
71 Parameters
71 Parameters
72 ----------
72 ----------
73 source : str
73 source : str
74 source of the cell to highlight
74 source of the cell to highlight
75 language : str
75 language : str
76 language to highlight the syntax of
76 language to highlight the syntax of
77 metadata : NotebookNode cell metadata
77 metadata : NotebookNode cell metadata
78 metadata of the cell to highlight
78 metadata of the cell to highlight
79 strip_verbatim : bool
79 strip_verbatim : bool
80 remove the Verbatim environment that pygments provides by default
80 remove the Verbatim environment that pygments provides by default
81 """
81 """
82 from pygments.formatters import LatexFormatter
82 from pygments.formatters import LatexFormatter
83 if not language:
83 if not language:
84 language=self.pygments_lexer
84 language=self.pygments_lexer
85
85
86 latex = _pygments_highlight(source, LatexFormatter(), language, metadata)
86 latex = _pygments_highlight(source, LatexFormatter(), language, metadata)
87 if strip_verbatim:
87 if strip_verbatim:
88 latex = latex.replace(r'\begin{Verbatim}[commandchars=\\\{\}]' + '\n', '')
88 latex = latex.replace(r'\begin{Verbatim}[commandchars=\\\{\}]' + '\n', '')
89 return latex.replace('\n\\end{Verbatim}\n', '')
89 return latex.replace('\n\\end{Verbatim}\n', '')
90 else:
90 else:
91 return latex
91 return latex
92
92
93
93
94
94
95 def _pygments_highlight(source, output_formatter, language='ipython', metadata=None):
95 def _pygments_highlight(source, output_formatter, language='ipython', metadata=None):
96 """
96 """
97 Return a syntax-highlighted version of the input source
97 Return a syntax-highlighted version of the input source
98
98
99 Parameters
99 Parameters
100 ----------
100 ----------
101 source : str
101 source : str
102 source of the cell to highlight
102 source of the cell to highlight
103 output_formatter : Pygments formatter
103 output_formatter : Pygments formatter
104 language : str
104 language : str
105 language to highlight the syntax of
105 language to highlight the syntax of
106 metadata : NotebookNode cell metadata
106 metadata : NotebookNode cell metadata
107 metadata of the cell to highlight
107 metadata of the cell to highlight
108 """
108 """
109 from pygments import highlight
109 from pygments import highlight
110 from pygments.lexers import get_lexer_by_name
110 from pygments.lexers import get_lexer_by_name
111 from pygments.util import ClassNotFound
111 from pygments.util import ClassNotFound
112 from IPython.nbconvert.utils.lexers import IPythonLexer, IPython3Lexer
112 from IPython.lib.lexers import IPythonLexer, IPython3Lexer
113
113
114 # If the cell uses a magic extension language,
114 # If the cell uses a magic extension language,
115 # use the magic language instead.
115 # use the magic language instead.
116 if language.startswith('ipython') \
116 if language.startswith('ipython') \
117 and metadata \
117 and metadata \
118 and 'magics_language' in metadata:
118 and 'magics_language' in metadata:
119
119
120 language = metadata['magics_language']
120 language = metadata['magics_language']
121
121
122 if language == 'ipython2':
122 if language == 'ipython2':
123 lexer = IPythonLexer()
123 lexer = IPythonLexer()
124 elif language == 'ipython3':
124 elif language == 'ipython3':
125 lexer = IPython3Lexer()
125 lexer = IPython3Lexer()
126 else:
126 else:
127 try:
127 try:
128 lexer = get_lexer_by_name(language, stripall=True)
128 lexer = get_lexer_by_name(language, stripall=True)
129 except ClassNotFound:
129 except ClassNotFound:
130 warn("No lexer found for language %r. Treating as plain text." % language)
130 warn("No lexer found for language %r. Treating as plain text." % language)
131 from pygments.lexers.special import TextLexer
131 from pygments.lexers.special import TextLexer
132 lexer = TextLexer()
132 lexer = TextLexer()
133
133
134
134
135 return highlight(source, lexer, output_formatter)
135 return highlight(source, lexer, output_formatter)
This diff has been collapsed as it changes many lines, (509 lines changed) Show them Hide them
@@ -1,508 +1,3 b''
1 # -*- coding: utf-8 -*-
1 """Deprecated; import from IPython.lib.lexers instead."""
2 """
3 Defines a variety of Pygments lexers for highlighting IPython code.
4
5 This includes:
6
7 IPythonLexer, IPython3Lexer
8 Lexers for pure IPython (python + magic/shell commands)
9
10 IPythonPartialTracebackLexer, IPythonTracebackLexer
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
15 IPythonConsoleLexer
16 A lexer for IPython console sessions, with support for tracebacks.
17
18 IPyLexer
19 A friendly lexer which examines the first line of text and from it,
20 decides whether to use an IPython lexer or an IPython console lexer.
21 This is probably the only lexer that needs to be explicitly added
22 to Pygments.
23
24 """
25 #-----------------------------------------------------------------------------
26 # Copyright (c) 2013, the IPython Development Team.
27 #
28 # Distributed under the terms of the Modified BSD License.
29 #
30 # The full license is in the file COPYING.txt, distributed with this software.
31 #-----------------------------------------------------------------------------
32
33 # Standard library
34 import re
35
36 # Third party
37 from pygments.lexers import BashLexer, PythonLexer, Python3Lexer
38 from pygments.lexer import (
39 Lexer, DelegatingLexer, RegexLexer, do_insertions, bygroups, using,
40 )
41 from pygments.token import (
42 Comment, Generic, Keyword, Literal, Name, Operator, Other, Text, Error,
43 )
44 from pygments.util import get_bool_opt
45
46 # Local
47 from IPython.testing.skipdoctest import skip_doctest
48
49 line_re = re.compile('.*?\n')
50
51 ipython_tokens = [
52 (r"(?s)(\s*)(%%)(\w+)(.*)", bygroups(Text, Operator, Keyword, Text)),
53 (r'(?s)(^\s*)(%%!)([^\n]*\n)(.*)', bygroups(Text, Operator, Text, using(BashLexer))),
54 (r"(%%?)(\w+)(\?\??)$", bygroups(Operator, Keyword, Operator)),
55 (r"\b(\?\??)(\s*)$", bygroups(Operator, Text)),
56 (r'(%)(sx|sc|system)(.*)(\n)', bygroups(Operator, Keyword,
57 using(BashLexer), Text)),
58 (r'(%)(\w+)(.*\n)', bygroups(Operator, Keyword, Text)),
59 (r'^(!!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
60 (r'(!)(?!=)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
61 (r'^(\s*)(\?\??)(\s*%{0,2}[\w\.\*]*)', bygroups(Text, Operator, Text)),
62 ]
63
64 def build_ipy_lexer(python3):
65 """Builds IPython lexers depending on the value of `python3`.
66
67 The lexer inherits from an appropriate Python lexer and then adds
68 information about IPython specific keywords (i.e. magic commands,
69 shell commands, etc.)
70
71 Parameters
72 ----------
73 python3 : bool
74 If `True`, then build an IPython lexer from a Python 3 lexer.
75
76 """
77 # It would be nice to have a single IPython lexer class which takes
78 # a boolean `python3`. But since there are two Python lexer classes,
79 # we will also have two IPython lexer classes.
80 if python3:
81 PyLexer = Python3Lexer
82 clsname = 'IPython3Lexer'
83 name = 'IPython3'
84 aliases = ['ipython3']
85 doc = """IPython3 Lexer"""
86 else:
87 PyLexer = PythonLexer
88 clsname = 'IPythonLexer'
89 name = 'IPython'
90 aliases = ['ipython2', 'ipython']
91 doc = """IPython Lexer"""
92
93 tokens = PyLexer.tokens.copy()
94 tokens['root'] = ipython_tokens + tokens['root']
95
96 attrs = {'name': name, 'aliases': aliases, 'filenames': [],
97 '__doc__': doc, 'tokens': tokens}
98
99 return type(name, (PyLexer,), attrs)
100
101
102 IPython3Lexer = build_ipy_lexer(python3=True)
103 IPythonLexer = build_ipy_lexer(python3=False)
104
105
106 class IPythonPartialTracebackLexer(RegexLexer):
107 """
108 Partial lexer for IPython tracebacks.
109
110 Handles all the non-python output. This works for both Python 2.x and 3.x.
111
112 """
113 name = 'IPython Partial Traceback'
114
115 tokens = {
116 'root': [
117 # Tracebacks for syntax errors have a different style.
118 # For both types of tracebacks, we mark the first line with
119 # Generic.Traceback. For syntax errors, we mark the filename
120 # as we mark the filenames for non-syntax tracebacks.
121 #
122 # These two regexps define how IPythonConsoleLexer finds a
123 # traceback.
124 #
125 ## Non-syntax traceback
126 (r'^(\^C)?(-+\n)', bygroups(Error, Generic.Traceback)),
127 ## Syntax traceback
128 (r'^( File)(.*)(, line )(\d+\n)',
129 bygroups(Generic.Traceback, Name.Namespace,
130 Generic.Traceback, Literal.Number.Integer)),
131
132 # (Exception Identifier)(Whitespace)(Traceback Message)
133 (r'(?u)(^[^\d\W]\w*)(\s*)(Traceback.*?\n)',
134 bygroups(Name.Exception, Generic.Whitespace, Text)),
135 # (Module/Filename)(Text)(Callee)(Function Signature)
136 # Better options for callee and function signature?
137 (r'(.*)( in )(.*)(\(.*\)\n)',
138 bygroups(Name.Namespace, Text, Name.Entity, Name.Tag)),
139 # Regular line: (Whitespace)(Line Number)(Python Code)
140 (r'(\s*?)(\d+)(.*?\n)',
141 bygroups(Generic.Whitespace, Literal.Number.Integer, Other)),
142 # Emphasized line: (Arrow)(Line Number)(Python Code)
143 # Using Exception token so arrow color matches the Exception.
144 (r'(-*>?\s?)(\d+)(.*?\n)',
145 bygroups(Name.Exception, Literal.Number.Integer, Other)),
146 # (Exception Identifier)(Message)
147 (r'(?u)(^[^\d\W]\w*)(:.*?\n)',
148 bygroups(Name.Exception, Text)),
149 # Tag everything else as Other, will be handled later.
150 (r'.*\n', Other),
151 ],
152 }
153
154
155 class IPythonTracebackLexer(DelegatingLexer):
156 """
157 IPython traceback lexer.
158
159 For doctests, the tracebacks can be snipped as much as desired with the
160 exception to the lines that designate a traceback. For non-syntax error
161 tracebacks, this is the line of hyphens. For syntax error tracebacks,
162 this is the line which lists the File and line number.
163
164 """
165 # The lexer inherits from DelegatingLexer. The "root" lexer is an
166 # appropriate IPython lexer, which depends on the value of the boolean
167 # `python3`. First, we parse with the partial IPython traceback lexer.
168 # Then, any code marked with the "Other" token is delegated to the root
169 # lexer.
170 #
171 name = 'IPython Traceback'
172 aliases = ['ipythontb']
173
174 def __init__(self, **options):
175 self.python3 = get_bool_opt(options, 'python3', False)
176 if self.python3:
177 self.aliases = ['ipython3tb']
178 else:
179 self.aliases = ['ipython2tb', 'ipythontb']
180
181 if self.python3:
182 IPyLexer = IPython3Lexer
183 else:
184 IPyLexer = IPythonLexer
185
186 DelegatingLexer.__init__(self, IPyLexer,
187 IPythonPartialTracebackLexer, **options)
188
189 @skip_doctest
190 class IPythonConsoleLexer(Lexer):
191 """
192 An IPython console lexer for IPython code-blocks and doctests, such as:
193
194 .. code-block:: rst
195
196 .. code-block:: ipythonconsole
197
198 In [1]: a = 'foo'
199
200 In [2]: a
201 Out[2]: 'foo'
202
203 In [3]: print a
204 foo
205
206 In [4]: 1 / 0
207
208
209 Support is also provided for IPython exceptions:
210
211 .. code-block:: rst
212
213 .. code-block:: ipythonconsole
214
215 In [1]: raise Exception
216
217 ---------------------------------------------------------------------------
218 Exception Traceback (most recent call last)
219 <ipython-input-1-fca2ab0ca76b> in <module>()
220 ----> 1 raise Exception
221
222 Exception:
223
224 """
225 name = 'IPython console session'
226 aliases = ['ipythonconsole']
227 mimetypes = ['text/x-ipython-console']
228
229 # The regexps used to determine what is input and what is output.
230 # The default prompts for IPython are:
231 #
232 # c.PromptManager.in_template = 'In [\#]: '
233 # c.PromptManager.in2_template = ' .\D.: '
234 # c.PromptManager.out_template = 'Out[\#]: '
235 #
236 in1_regex = r'In \[[0-9]+\]: '
237 in2_regex = r' \.\.+\.: '
238 out_regex = r'Out\[[0-9]+\]: '
239
240 #: The regex to determine when a traceback starts.
241 ipytb_start = re.compile(r'^(\^C)?(-+\n)|^( File)(.*)(, line )(\d+\n)')
242
243 def __init__(self, **options):
244 """Initialize the IPython console lexer.
245
246 Parameters
247 ----------
248 python3 : bool
249 If `True`, then the console inputs are parsed using a Python 3
250 lexer. Otherwise, they are parsed using a Python 2 lexer.
251 in1_regex : RegexObject
252 The compiled regular expression used to detect the start
253 of inputs. Although the IPython configuration setting may have a
254 trailing whitespace, do not include it in the regex. If `None`,
255 then the default input prompt is assumed.
256 in2_regex : RegexObject
257 The compiled regular expression used to detect the continuation
258 of inputs. Although the IPython configuration setting may have a
259 trailing whitespace, do not include it in the regex. If `None`,
260 then the default input prompt is assumed.
261 out_regex : RegexObject
262 The compiled regular expression used to detect outputs. If `None`,
263 then the default output prompt is assumed.
264
265 """
266 self.python3 = get_bool_opt(options, 'python3', False)
267 if self.python3:
268 self.aliases = ['ipython3console']
269 else:
270 self.aliases = ['ipython2console', 'ipythonconsole']
271
272 in1_regex = options.get('in1_regex', self.in1_regex)
273 in2_regex = options.get('in2_regex', self.in2_regex)
274 out_regex = options.get('out_regex', self.out_regex)
275
276 # So that we can work with input and output prompts which have been
277 # rstrip'd (possibly by editors) we also need rstrip'd variants. If
278 # we do not do this, then such prompts will be tagged as 'output'.
279 # The reason can't just use the rstrip'd variants instead is because
280 # we want any whitespace associated with the prompt to be inserted
281 # with the token. This allows formatted code to be modified so as hide
282 # the appearance of prompts, with the whitespace included. One example
283 # use of this is in copybutton.js from the standard lib Python docs.
284 in1_regex_rstrip = in1_regex.rstrip() + '\n'
285 in2_regex_rstrip = in2_regex.rstrip() + '\n'
286 out_regex_rstrip = out_regex.rstrip() + '\n'
287
288 # Compile and save them all.
289 attrs = ['in1_regex', 'in2_regex', 'out_regex',
290 'in1_regex_rstrip', 'in2_regex_rstrip', 'out_regex_rstrip']
291 for attr in attrs:
292 self.__setattr__(attr, re.compile(locals()[attr]))
293
294 Lexer.__init__(self, **options)
295
296 if self.python3:
297 pylexer = IPython3Lexer
298 tblexer = IPythonTracebackLexer
299 else:
300 pylexer = IPythonLexer
301 tblexer = IPythonTracebackLexer
302
303 self.pylexer = pylexer(**options)
304 self.tblexer = tblexer(**options)
305
306 self.reset()
307
308 def reset(self):
309 self.mode = 'output'
310 self.index = 0
311 self.buffer = u''
312 self.insertions = []
313
314 def buffered_tokens(self):
315 """
316 Generator of unprocessed tokens after doing insertions and before
317 changing to a new state.
318
319 """
320 if self.mode == 'output':
321 tokens = [(0, Generic.Output, self.buffer)]
322 elif self.mode == 'input':
323 tokens = self.pylexer.get_tokens_unprocessed(self.buffer)
324 else: # traceback
325 tokens = self.tblexer.get_tokens_unprocessed(self.buffer)
326
327 for i, t, v in do_insertions(self.insertions, tokens):
328 # All token indexes are relative to the buffer.
329 yield self.index + i, t, v
330
331 # Clear it all
332 self.index += len(self.buffer)
333 self.buffer = u''
334 self.insertions = []
335
336 def get_mci(self, line):
337 """
338 Parses the line and returns a 3-tuple: (mode, code, insertion).
339
340 `mode` is the next mode (or state) of the lexer, and is always equal
341 to 'input', 'output', or 'tb'.
342
343 `code` is a portion of the line that should be added to the buffer
344 corresponding to the next mode and eventually lexed by another lexer.
345 For example, `code` could be Python code if `mode` were 'input'.
346
347 `insertion` is a 3-tuple (index, token, text) representing an
348 unprocessed "token" that will be inserted into the stream of tokens
349 that are created from the buffer once we change modes. This is usually
350 the input or output prompt.
351
352 In general, the next mode depends on current mode and on the contents
353 of `line`.
354
355 """
356 # To reduce the number of regex match checks, we have multiple
357 # 'if' blocks instead of 'if-elif' blocks.
358
359 # Check for possible end of input
360 in2_match = self.in2_regex.match(line)
361 in2_match_rstrip = self.in2_regex_rstrip.match(line)
362 if (in2_match and in2_match.group().rstrip() == line.rstrip()) or \
363 in2_match_rstrip:
364 end_input = True
365 else:
366 end_input = False
367 if end_input and self.mode != 'tb':
368 # Only look for an end of input when not in tb mode.
369 # An ellipsis could appear within the traceback.
370 mode = 'output'
371 code = u''
372 insertion = (0, Generic.Prompt, line)
373 return mode, code, insertion
374
375 # Check for output prompt
376 out_match = self.out_regex.match(line)
377 out_match_rstrip = self.out_regex_rstrip.match(line)
378 if out_match or out_match_rstrip:
379 mode = 'output'
380 if out_match:
381 idx = out_match.end()
382 else:
383 idx = out_match_rstrip.end()
384 code = line[idx:]
385 # Use the 'heading' token for output. We cannot use Generic.Error
386 # since it would conflict with exceptions.
387 insertion = (0, Generic.Heading, line[:idx])
388 return mode, code, insertion
389
390
391 # Check for input or continuation prompt (non stripped version)
392 in1_match = self.in1_regex.match(line)
393 if in1_match or (in2_match and self.mode != 'tb'):
394 # New input or when not in tb, continued input.
395 # We do not check for continued input when in tb since it is
396 # allowable to replace a long stack with an ellipsis.
397 mode = 'input'
398 if in1_match:
399 idx = in1_match.end()
400 else: # in2_match
401 idx = in2_match.end()
402 code = line[idx:]
403 insertion = (0, Generic.Prompt, line[:idx])
404 return mode, code, insertion
405
406 # Check for input or continuation prompt (stripped version)
407 in1_match_rstrip = self.in1_regex_rstrip.match(line)
408 if in1_match_rstrip or (in2_match_rstrip and self.mode != 'tb'):
409 # New input or when not in tb, continued input.
410 # We do not check for continued input when in tb since it is
411 # allowable to replace a long stack with an ellipsis.
412 mode = 'input'
413 if in1_match_rstrip:
414 idx = in1_match_rstrip.end()
415 else: # in2_match
416 idx = in2_match_rstrip.end()
417 code = line[idx:]
418 insertion = (0, Generic.Prompt, line[:idx])
419 return mode, code, insertion
420
421 # Check for traceback
422 if self.ipytb_start.match(line):
423 mode = 'tb'
424 code = line
425 insertion = None
426 return mode, code, insertion
427
428 # All other stuff...
429 if self.mode in ('input', 'output'):
430 # We assume all other text is output. Multiline input that
431 # does not use the continuation marker cannot be detected.
432 # For example, the 3 in the following is clearly output:
433 #
434 # In [1]: print 3
435 # 3
436 #
437 # But the following second line is part of the input:
438 #
439 # In [2]: while True:
440 # print True
441 #
442 # In both cases, the 2nd line will be 'output'.
443 #
444 mode = 'output'
445 else:
446 mode = 'tb'
447
448 code = line
449 insertion = None
450
451 return mode, code, insertion
452
453 def get_tokens_unprocessed(self, text):
454 self.reset()
455 for match in line_re.finditer(text):
456 line = match.group()
457 mode, code, insertion = self.get_mci(line)
458
459 if mode != self.mode:
460 # Yield buffered tokens before transitioning to new mode.
461 for token in self.buffered_tokens():
462 yield token
463 self.mode = mode
464
465 if insertion:
466 self.insertions.append((len(self.buffer), [insertion]))
467 self.buffer += code
468 else:
469 for token in self.buffered_tokens():
470 yield token
471
472 class IPyLexer(Lexer):
473 """
474 Primary lexer for all IPython-like code.
475
476 This is a simple helper lexer. If the first line of the text begins with
477 "In \[[0-9]+\]:", then the entire text is parsed with an IPython console
478 lexer. If not, then the entire text is parsed with an IPython lexer.
479
480 The goal is to reduce the number of lexers that are registered
481 with Pygments.
482
483 """
484 name = 'IPy session'
485 aliases = ['ipy']
486
487 def __init__(self, **options):
488 self.python3 = get_bool_opt(options, 'python3', False)
489 if self.python3:
490 self.aliases = ['ipy3']
491 else:
492 self.aliases = ['ipy2', 'ipy']
493
494 Lexer.__init__(self, **options)
495
496 self.IPythonLexer = IPythonLexer(**options)
497 self.IPythonConsoleLexer = IPythonConsoleLexer(**options)
498
499 def get_tokens_unprocessed(self, text):
500 # Search for the input prompt anywhere...this allows code blocks to
501 # begin with comments as well.
502 if re.match(r'.*(In \[[0-9]+\]:)', text.strip(), re.DOTALL):
503 lex = self.IPythonConsoleLexer
504 else:
505 lex = self.IPythonLexer
506 for token in lex.get_tokens_unprocessed(text):
507 yield token
508
2
3 from IPython.lib.lexers import *
@@ -1,27 +1,27 b''
1 """
1 """
2 reST directive for syntax-highlighting ipython interactive sessions.
2 reST directive for syntax-highlighting ipython interactive sessions.
3
3
4 """
4 """
5
5
6 from sphinx import highlighting
6 from sphinx import highlighting
7 from ..nbconvert.utils.lexers import IPyLexer
7 from IPython.lib.lexers import IPyLexer
8
8
9 def setup(app):
9 def setup(app):
10 """Setup as a sphinx extension."""
10 """Setup as a sphinx extension."""
11
11
12 # This is only a lexer, so adding it below to pygments appears sufficient.
12 # This is only a lexer, so adding it below to pygments appears sufficient.
13 # But if somebody knows what the right API usage should be to do that via
13 # But if somebody knows what the right API usage should be to do that via
14 # sphinx, by all means fix it here. At least having this setup.py
14 # sphinx, by all means fix it here. At least having this setup.py
15 # suppresses the sphinx warning we'd get without it.
15 # suppresses the sphinx warning we'd get without it.
16 pass
16 pass
17
17
18 # Register the extension as a valid pygments lexer.
18 # Register the extension as a valid pygments lexer.
19 # Alternatively, we could register the lexer with pygments instead. This would
19 # Alternatively, we could register the lexer with pygments instead. This would
20 # require using setuptools entrypoints: http://pygments.org/docs/plugins
20 # require using setuptools entrypoints: http://pygments.org/docs/plugins
21
21
22 ipy2 = IPyLexer(python3=False)
22 ipy2 = IPyLexer(python3=False)
23 ipy3 = IPyLexer(python3=True)
23 ipy3 = IPyLexer(python3=True)
24
24
25 highlighting.lexers['ipython'] = ipy2
25 highlighting.lexers['ipython'] = ipy2
26 highlighting.lexers['ipython2'] = ipy2
26 highlighting.lexers['ipython2'] = ipy2
27 highlighting.lexers['ipython3'] = ipy3
27 highlighting.lexers['ipython3'] = ipy3
@@ -1,79 +1,81 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """Script to auto-generate our API docs.
2 """Script to auto-generate our API docs.
3 """
3 """
4 # stdlib imports
4 # stdlib imports
5 import os
5 import os
6 import sys
6 import sys
7
7
8 # local imports
8 # local imports
9 sys.path.append(os.path.abspath('sphinxext'))
9 sys.path.append(os.path.abspath('sphinxext'))
10 from apigen import ApiDocWriter
10 from apigen import ApiDocWriter
11
11
12 #*****************************************************************************
12 #*****************************************************************************
13 if __name__ == '__main__':
13 if __name__ == '__main__':
14 pjoin = os.path.join
14 pjoin = os.path.join
15 package = 'IPython'
15 package = 'IPython'
16 outdir = pjoin('source','api','generated')
16 outdir = pjoin('source','api','generated')
17 docwriter = ApiDocWriter(package,rst_extension='.rst')
17 docwriter = ApiDocWriter(package,rst_extension='.rst')
18 # You have to escape the . here because . is a special char for regexps.
18 # You have to escape the . here because . is a special char for regexps.
19 # You must do make clean if you change this!
19 # You must do make clean if you change this!
20 docwriter.package_skip_patterns += [r'\.external$',
20 docwriter.package_skip_patterns += [r'\.external$',
21 # Extensions are documented elsewhere.
21 # Extensions are documented elsewhere.
22 r'\.extensions',
22 r'\.extensions',
23 r'\.config\.profile',
23 r'\.config\.profile',
24 # Old nbformat versions
24 # Old nbformat versions
25 r'\.nbformat\.v[1-2]',
25 r'\.nbformat\.v[1-2]',
26 # Public API for this is in kernel.zmq.eventloops
26 # Public API for this is in kernel.zmq.eventloops
27 r'\.kernel\.zmq\.gui',
27 r'\.kernel\.zmq\.gui',
28 # Magics are documented separately
28 # Magics are documented separately
29 r'\.core\.magics',
29 r'\.core\.magics',
30 ]
30 ]
31
31
32 # The inputhook* modules often cause problems on import, such as trying to
32 # The inputhook* modules often cause problems on import, such as trying to
33 # load incompatible Qt bindings. It's easiest to leave them all out. The
33 # load incompatible Qt bindings. It's easiest to leave them all out. The
34 # main API is in the inputhook module, which is documented.
34 # main API is in the inputhook module, which is documented.
35 docwriter.module_skip_patterns += [ r'\.lib\.inputhook.+',
35 docwriter.module_skip_patterns += [ r'\.lib\.inputhook.+',
36 r'\.ipdoctest',
36 r'\.ipdoctest',
37 r'\.testing\.plugin',
37 r'\.testing\.plugin',
38 # This just prints a deprecation msg:
38 # This just prints a deprecation msg:
39 r'\.frontend$',
39 r'\.frontend$',
40 # Deprecated:
40 # Deprecated:
41 r'\.core\.magics\.deprecated',
41 r'\.core\.magics\.deprecated',
42 # Backwards compat import for lib.lexers
43 r'\.nbconvert\.utils\.lexers',
42 # We document this manually.
44 # We document this manually.
43 r'\.utils\.py3compat',
45 r'\.utils\.py3compat',
44 # These are exposed by nbformat
46 # These are exposed by nbformat
45 r'\.nbformat\.convert',
47 r'\.nbformat\.convert',
46 r'\.nbformat\.validator',
48 r'\.nbformat\.validator',
47 r'\.nbformat\.notebooknode',
49 r'\.nbformat\.notebooknode',
48 # Deprecated
50 # Deprecated
49 r'\.nbformat\.current',
51 r'\.nbformat\.current',
50 # Exposed by nbformat.vN
52 # Exposed by nbformat.vN
51 r'\.nbformat\.v[3-4]\.nbbase',
53 r'\.nbformat\.v[3-4]\.nbbase',
52 # These are exposed in display
54 # These are exposed in display
53 r'\.core\.display',
55 r'\.core\.display',
54 r'\.lib\.display',
56 r'\.lib\.display',
55 # This isn't actually a module
57 # This isn't actually a module
56 r'\.html\.tasks',
58 r'\.html\.tasks',
57 # This is private
59 # This is private
58 r'\.html\.allow76'
60 r'\.html\.allow76'
59 ]
61 ]
60
62
61 # These modules import functions and classes from other places to expose
63 # These modules import functions and classes from other places to expose
62 # them as part of the public API. They must have __all__ defined. The
64 # them as part of the public API. They must have __all__ defined. The
63 # non-API modules they import from should be excluded by the skip patterns
65 # non-API modules they import from should be excluded by the skip patterns
64 # above.
66 # above.
65 docwriter.names_from__all__.update({
67 docwriter.names_from__all__.update({
66 'IPython.nbformat',
68 'IPython.nbformat',
67 'IPython.nbformat.v3',
69 'IPython.nbformat.v3',
68 'IPython.nbformat.v4',
70 'IPython.nbformat.v4',
69 'IPython.display',
71 'IPython.display',
70 })
72 })
71
73
72 # Now, generate the outputs
74 # Now, generate the outputs
73 docwriter.write_api_docs(outdir)
75 docwriter.write_api_docs(outdir)
74 # Write index with .txt extension - we can include it, but Sphinx won't try
76 # Write index with .txt extension - we can include it, but Sphinx won't try
75 # to compile it
77 # to compile it
76 docwriter.write_index(outdir, 'gen.txt',
78 docwriter.write_index(outdir, 'gen.txt',
77 relative_to = pjoin('source','api')
79 relative_to = pjoin('source','api')
78 )
80 )
79 print ('%d files written' % len(docwriter.written_modules))
81 print ('%d files written' % len(docwriter.written_modules))
@@ -1,64 +1,64 b''
1 .. _console_lexer:
1 .. _console_lexer:
2
2
3 New IPython Console Lexer
3 New IPython Console Lexer
4 -------------------------
4 -------------------------
5
5
6 .. versionadded:: 2.0.0
6 .. versionadded:: 2.0.0
7
7
8 The IPython console lexer has been rewritten and now supports tracebacks
8 The IPython console lexer has been rewritten and now supports tracebacks
9 and customized input/output prompts. An entire suite of lexers is now
9 and customized input/output prompts. An entire suite of lexers is now
10 available at :mod:`IPython.nbconvert.utils.lexers`. These include:
10 available at :mod:`IPython.lib.lexers`. These include:
11
11
12 IPythonLexer & IPython3Lexer
12 IPythonLexer & IPython3Lexer
13 Lexers for pure IPython (python + magic/shell commands)
13 Lexers for pure IPython (python + magic/shell commands)
14
14
15 IPythonPartialTracebackLexer & IPythonTracebackLexer
15 IPythonPartialTracebackLexer & IPythonTracebackLexer
16 Supports 2.x and 3.x via the keyword `python3`. The partial traceback
16 Supports 2.x and 3.x via the keyword `python3`. The partial traceback
17 lexer reads everything but the Python code appearing in a traceback.
17 lexer reads everything but the Python code appearing in a traceback.
18 The full lexer combines the partial lexer with an IPython lexer.
18 The full lexer combines the partial lexer with an IPython lexer.
19
19
20 IPythonConsoleLexer
20 IPythonConsoleLexer
21 A lexer for IPython console sessions, with support for tracebacks.
21 A lexer for IPython console sessions, with support for tracebacks.
22 Supports 2.x and 3.x via the keyword `python3`.
22 Supports 2.x and 3.x via the keyword `python3`.
23
23
24 IPyLexer
24 IPyLexer
25 A friendly lexer which examines the first line of text and from it,
25 A friendly lexer which examines the first line of text and from it,
26 decides whether to use an IPython lexer or an IPython console lexer.
26 decides whether to use an IPython lexer or an IPython console lexer.
27 Supports 2.x and 3.x via the keyword `python3`.
27 Supports 2.x and 3.x via the keyword `python3`.
28
28
29 Previously, the :class:`IPythonConsoleLexer` class was available at
29 Previously, the :class:`IPythonConsoleLexer` class was available at
30 :mod:`IPython.sphinxext.ipython_console_hightlight`. It was inserted
30 :mod:`IPython.sphinxext.ipython_console_hightlight`. It was inserted
31 into Pygments' list of available lexers under the name `ipython`. It should
31 into Pygments' list of available lexers under the name `ipython`. It should
32 be mentioned that this name is inaccurate, since an IPython console session
32 be mentioned that this name is inaccurate, since an IPython console session
33 is not the same as IPython code (which itself is a superset of the Python
33 is not the same as IPython code (which itself is a superset of the Python
34 language).
34 language).
35
35
36 Now, the Sphinx extension inserts two console lexers into Pygments' list of
36 Now, the Sphinx extension inserts two console lexers into Pygments' list of
37 available lexers. Both are IPyLexer instances under the names: `ipython` and
37 available lexers. Both are IPyLexer instances under the names: `ipython` and
38 `ipython3`. Although the names can be confusing (as mentioned above), their
38 `ipython3`. Although the names can be confusing (as mentioned above), their
39 continued use is, in part, to maintain backwards compatibility and to
39 continued use is, in part, to maintain backwards compatibility and to
40 aid typical usage. If a project needs to make Pygments aware of more than just
40 aid typical usage. If a project needs to make Pygments aware of more than just
41 the IPyLexer class, then one should not make the IPyLexer class available under
41 the IPyLexer class, then one should not make the IPyLexer class available under
42 the name `ipython` and use `ipy` or some other non-conflicting value.
42 the name `ipython` and use `ipy` or some other non-conflicting value.
43
43
44 Code blocks such as:
44 Code blocks such as:
45
45
46 .. code-block:: rst
46 .. code-block:: rst
47
47
48 .. code-block:: ipython
48 .. code-block:: ipython
49
49
50 In [1]: 2**2
50 In [1]: 2**2
51 Out[1]: 4
51 Out[1]: 4
52
52
53 will continue to work as before, but now, they will also properly highlight
53 will continue to work as before, but now, they will also properly highlight
54 tracebacks. For pure IPython code, the same lexer will also work:
54 tracebacks. For pure IPython code, the same lexer will also work:
55
55
56 .. code-block:: rst
56 .. code-block:: rst
57
57
58 .. code-block:: ipython
58 .. code-block:: ipython
59
59
60 x = ''.join(map(str, range(10)))
60 x = ''.join(map(str, range(10)))
61 !echo $x
61 !echo $x
62
62
63 Since the first line of the block did not begin with a standard IPython console
63 Since the first line of the block did not begin with a standard IPython console
64 prompt, the entire block is assumed to consist of IPython code instead.
64 prompt, the entire block is assumed to consist of IPython code instead.
@@ -1,342 +1,342 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
3 """Setup script for IPython.
4
4
5 Under Posix environments it works like a typical setup.py script.
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
7 requires utilities which are not available under Windows."""
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
14 #
15 # Distributed under the terms of the Modified BSD License.
15 # Distributed under the terms of the Modified BSD License.
16 #
16 #
17 # The full license is in the file COPYING.rst, distributed with this software.
17 # The full license is in the file COPYING.rst, distributed with this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 from __future__ import print_function
23 from __future__ import print_function
24
24
25 import sys
25 import sys
26
26
27 # This check is also made in IPython/__init__, don't forget to update both when
27 # This check is also made in IPython/__init__, don't forget to update both when
28 # changing Python version requirements.
28 # changing Python version requirements.
29 v = sys.version_info
29 v = sys.version_info
30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 print(error, file=sys.stderr)
32 print(error, file=sys.stderr)
33 sys.exit(1)
33 sys.exit(1)
34
34
35 PY3 = (sys.version_info[0] >= 3)
35 PY3 = (sys.version_info[0] >= 3)
36
36
37 # At least we're on the python version we need, move on.
37 # At least we're on the python version we need, move on.
38
38
39 #-------------------------------------------------------------------------------
39 #-------------------------------------------------------------------------------
40 # Imports
40 # Imports
41 #-------------------------------------------------------------------------------
41 #-------------------------------------------------------------------------------
42
42
43 # Stdlib imports
43 # Stdlib imports
44 import os
44 import os
45 import shutil
45 import shutil
46
46
47 from glob import glob
47 from glob import glob
48
48
49 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
49 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
50 # update it when the contents of directories change.
50 # update it when the contents of directories change.
51 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
51 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
52
52
53 from distutils.core import setup
53 from distutils.core import setup
54
54
55 # Our own imports
55 # Our own imports
56 from setupbase import target_update
56 from setupbase import target_update
57
57
58 from setupbase import (
58 from setupbase import (
59 setup_args,
59 setup_args,
60 find_packages,
60 find_packages,
61 find_package_data,
61 find_package_data,
62 check_package_data_first,
62 check_package_data_first,
63 find_entry_points,
63 find_entry_points,
64 build_scripts_entrypt,
64 build_scripts_entrypt,
65 find_data_files,
65 find_data_files,
66 check_for_dependencies,
66 check_for_dependencies,
67 git_prebuild,
67 git_prebuild,
68 check_submodule_status,
68 check_submodule_status,
69 update_submodules,
69 update_submodules,
70 require_submodules,
70 require_submodules,
71 UpdateSubmodules,
71 UpdateSubmodules,
72 get_bdist_wheel,
72 get_bdist_wheel,
73 CompileCSS,
73 CompileCSS,
74 JavascriptVersion,
74 JavascriptVersion,
75 css_js_prerelease,
75 css_js_prerelease,
76 install_symlinked,
76 install_symlinked,
77 install_lib_symlink,
77 install_lib_symlink,
78 install_scripts_for_symlink,
78 install_scripts_for_symlink,
79 unsymlink,
79 unsymlink,
80 )
80 )
81 from setupext import setupext
81 from setupext import setupext
82
82
83 isfile = os.path.isfile
83 isfile = os.path.isfile
84 pjoin = os.path.join
84 pjoin = os.path.join
85
85
86 #-------------------------------------------------------------------------------
86 #-------------------------------------------------------------------------------
87 # Handle OS specific things
87 # Handle OS specific things
88 #-------------------------------------------------------------------------------
88 #-------------------------------------------------------------------------------
89
89
90 if os.name in ('nt','dos'):
90 if os.name in ('nt','dos'):
91 os_name = 'windows'
91 os_name = 'windows'
92 else:
92 else:
93 os_name = os.name
93 os_name = os.name
94
94
95 # Under Windows, 'sdist' has not been supported. Now that the docs build with
95 # Under Windows, 'sdist' has not been supported. Now that the docs build with
96 # Sphinx it might work, but let's not turn it on until someone confirms that it
96 # Sphinx it might work, but let's not turn it on until someone confirms that it
97 # actually works.
97 # actually works.
98 if os_name == 'windows' and 'sdist' in sys.argv:
98 if os_name == 'windows' and 'sdist' in sys.argv:
99 print('The sdist command is not available under Windows. Exiting.')
99 print('The sdist command is not available under Windows. Exiting.')
100 sys.exit(1)
100 sys.exit(1)
101
101
102 #-------------------------------------------------------------------------------
102 #-------------------------------------------------------------------------------
103 # Make sure we aren't trying to run without submodules
103 # Make sure we aren't trying to run without submodules
104 #-------------------------------------------------------------------------------
104 #-------------------------------------------------------------------------------
105 here = os.path.abspath(os.path.dirname(__file__))
105 here = os.path.abspath(os.path.dirname(__file__))
106
106
107 def require_clean_submodules():
107 def require_clean_submodules():
108 """Check on git submodules before distutils can do anything
108 """Check on git submodules before distutils can do anything
109
109
110 Since distutils cannot be trusted to update the tree
110 Since distutils cannot be trusted to update the tree
111 after everything has been set in motion,
111 after everything has been set in motion,
112 this is not a distutils command.
112 this is not a distutils command.
113 """
113 """
114 # PACKAGERS: Add a return here to skip checks for git submodules
114 # PACKAGERS: Add a return here to skip checks for git submodules
115
115
116 # don't do anything if nothing is actually supposed to happen
116 # don't do anything if nothing is actually supposed to happen
117 for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
117 for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
118 if do_nothing in sys.argv:
118 if do_nothing in sys.argv:
119 return
119 return
120
120
121 status = check_submodule_status(here)
121 status = check_submodule_status(here)
122
122
123 if status == "missing":
123 if status == "missing":
124 print("checking out submodules for the first time")
124 print("checking out submodules for the first time")
125 update_submodules(here)
125 update_submodules(here)
126 elif status == "unclean":
126 elif status == "unclean":
127 print('\n'.join([
127 print('\n'.join([
128 "Cannot build / install IPython with unclean submodules",
128 "Cannot build / install IPython with unclean submodules",
129 "Please update submodules with",
129 "Please update submodules with",
130 " python setup.py submodule",
130 " python setup.py submodule",
131 "or",
131 "or",
132 " git submodule update",
132 " git submodule update",
133 "or commit any submodule changes you have made."
133 "or commit any submodule changes you have made."
134 ]))
134 ]))
135 sys.exit(1)
135 sys.exit(1)
136
136
137 require_clean_submodules()
137 require_clean_submodules()
138
138
139 #-------------------------------------------------------------------------------
139 #-------------------------------------------------------------------------------
140 # Things related to the IPython documentation
140 # Things related to the IPython documentation
141 #-------------------------------------------------------------------------------
141 #-------------------------------------------------------------------------------
142
142
143 # update the manuals when building a source dist
143 # update the manuals when building a source dist
144 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
144 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
145
145
146 # List of things to be updated. Each entry is a triplet of args for
146 # List of things to be updated. Each entry is a triplet of args for
147 # target_update()
147 # target_update()
148 to_update = [
148 to_update = [
149 # FIXME - Disabled for now: we need to redo an automatic way
149 # FIXME - Disabled for now: we need to redo an automatic way
150 # of generating the magic info inside the rst.
150 # of generating the magic info inside the rst.
151 #('docs/magic.tex',
151 #('docs/magic.tex',
152 #['IPython/Magic.py'],
152 #['IPython/Magic.py'],
153 #"cd doc && ./update_magic.sh" ),
153 #"cd doc && ./update_magic.sh" ),
154
154
155 ('docs/man/ipcluster.1.gz',
155 ('docs/man/ipcluster.1.gz',
156 ['docs/man/ipcluster.1'],
156 ['docs/man/ipcluster.1'],
157 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
157 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
158
158
159 ('docs/man/ipcontroller.1.gz',
159 ('docs/man/ipcontroller.1.gz',
160 ['docs/man/ipcontroller.1'],
160 ['docs/man/ipcontroller.1'],
161 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
161 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
162
162
163 ('docs/man/ipengine.1.gz',
163 ('docs/man/ipengine.1.gz',
164 ['docs/man/ipengine.1'],
164 ['docs/man/ipengine.1'],
165 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
165 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
166
166
167 ('docs/man/ipython.1.gz',
167 ('docs/man/ipython.1.gz',
168 ['docs/man/ipython.1'],
168 ['docs/man/ipython.1'],
169 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
169 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
170
170
171 ]
171 ]
172
172
173
173
174 [ target_update(*t) for t in to_update ]
174 [ target_update(*t) for t in to_update ]
175
175
176 #---------------------------------------------------------------------------
176 #---------------------------------------------------------------------------
177 # Find all the packages, package data, and data_files
177 # Find all the packages, package data, and data_files
178 #---------------------------------------------------------------------------
178 #---------------------------------------------------------------------------
179
179
180 packages = find_packages()
180 packages = find_packages()
181 package_data = find_package_data()
181 package_data = find_package_data()
182
182
183 data_files = find_data_files()
183 data_files = find_data_files()
184
184
185 setup_args['packages'] = packages
185 setup_args['packages'] = packages
186 setup_args['package_data'] = package_data
186 setup_args['package_data'] = package_data
187 setup_args['data_files'] = data_files
187 setup_args['data_files'] = data_files
188
188
189 #---------------------------------------------------------------------------
189 #---------------------------------------------------------------------------
190 # custom distutils commands
190 # custom distutils commands
191 #---------------------------------------------------------------------------
191 #---------------------------------------------------------------------------
192 # imports here, so they are after setuptools import if there was one
192 # imports here, so they are after setuptools import if there was one
193 from distutils.command.sdist import sdist
193 from distutils.command.sdist import sdist
194 from distutils.command.upload import upload
194 from distutils.command.upload import upload
195
195
196 class UploadWindowsInstallers(upload):
196 class UploadWindowsInstallers(upload):
197
197
198 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
198 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
199 user_options = upload.user_options + [
199 user_options = upload.user_options + [
200 ('files=', 'f', 'exe file (or glob) to upload')
200 ('files=', 'f', 'exe file (or glob) to upload')
201 ]
201 ]
202 def initialize_options(self):
202 def initialize_options(self):
203 upload.initialize_options(self)
203 upload.initialize_options(self)
204 meta = self.distribution.metadata
204 meta = self.distribution.metadata
205 base = '{name}-{version}'.format(
205 base = '{name}-{version}'.format(
206 name=meta.get_name(),
206 name=meta.get_name(),
207 version=meta.get_version()
207 version=meta.get_version()
208 )
208 )
209 self.files = os.path.join('dist', '%s.*.exe' % base)
209 self.files = os.path.join('dist', '%s.*.exe' % base)
210
210
211 def run(self):
211 def run(self):
212 for dist_file in glob(self.files):
212 for dist_file in glob(self.files):
213 self.upload_file('bdist_wininst', 'any', dist_file)
213 self.upload_file('bdist_wininst', 'any', dist_file)
214
214
215 setup_args['cmdclass'] = {
215 setup_args['cmdclass'] = {
216 'build_py': css_js_prerelease(
216 'build_py': css_js_prerelease(
217 check_package_data_first(git_prebuild('IPython'))),
217 check_package_data_first(git_prebuild('IPython'))),
218 'sdist' : css_js_prerelease(git_prebuild('IPython', sdist)),
218 'sdist' : css_js_prerelease(git_prebuild('IPython', sdist)),
219 'upload_wininst' : UploadWindowsInstallers,
219 'upload_wininst' : UploadWindowsInstallers,
220 'submodule' : UpdateSubmodules,
220 'submodule' : UpdateSubmodules,
221 'css' : CompileCSS,
221 'css' : CompileCSS,
222 'symlink': install_symlinked,
222 'symlink': install_symlinked,
223 'install_lib_symlink': install_lib_symlink,
223 'install_lib_symlink': install_lib_symlink,
224 'install_scripts_sym': install_scripts_for_symlink,
224 'install_scripts_sym': install_scripts_for_symlink,
225 'unsymlink': unsymlink,
225 'unsymlink': unsymlink,
226 'jsversion' : JavascriptVersion,
226 'jsversion' : JavascriptVersion,
227 }
227 }
228
228
229 #---------------------------------------------------------------------------
229 #---------------------------------------------------------------------------
230 # Handle scripts, dependencies, and setuptools specific things
230 # Handle scripts, dependencies, and setuptools specific things
231 #---------------------------------------------------------------------------
231 #---------------------------------------------------------------------------
232
232
233 # For some commands, use setuptools. Note that we do NOT list install here!
233 # For some commands, use setuptools. Note that we do NOT list install here!
234 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
234 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
235 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
235 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
236 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
236 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
237 'egg_info', 'easy_install', 'upload', 'install_egg_info',
237 'egg_info', 'easy_install', 'upload', 'install_egg_info',
238 ))
238 ))
239
239
240 if len(needs_setuptools.intersection(sys.argv)) > 0:
240 if len(needs_setuptools.intersection(sys.argv)) > 0:
241 import setuptools
241 import setuptools
242
242
243 # This dict is used for passing extra arguments that are setuptools
243 # This dict is used for passing extra arguments that are setuptools
244 # specific to setup
244 # specific to setup
245 setuptools_extra_args = {}
245 setuptools_extra_args = {}
246
246
247 # setuptools requirements
247 # setuptools requirements
248
248
249 pyzmq = 'pyzmq>=13'
249 pyzmq = 'pyzmq>=13'
250
250
251 extras_require = dict(
251 extras_require = dict(
252 parallel = [pyzmq],
252 parallel = [pyzmq],
253 qtconsole = [pyzmq, 'pygments'],
253 qtconsole = [pyzmq, 'pygments'],
254 doc = ['Sphinx>=1.1', 'numpydoc'],
254 doc = ['Sphinx>=1.1', 'numpydoc'],
255 test = ['nose>=0.10.1', 'requests'],
255 test = ['nose>=0.10.1', 'requests'],
256 terminal = [],
256 terminal = [],
257 nbformat = ['jsonschema>=2.0'],
257 nbformat = ['jsonschema>=2.0'],
258 notebook = ['tornado>=4.0', pyzmq, 'jinja2', 'pygments', 'mistune>=0.5'],
258 notebook = ['tornado>=4.0', pyzmq, 'jinja2', 'pygments', 'mistune>=0.5'],
259 nbconvert = ['pygments', 'jinja2', 'mistune>=0.3.1']
259 nbconvert = ['pygments', 'jinja2', 'mistune>=0.3.1']
260 )
260 )
261
261
262 if not sys.platform.startswith('win'):
262 if not sys.platform.startswith('win'):
263 extras_require['notebook'].append('terminado>=0.3.3')
263 extras_require['notebook'].append('terminado>=0.3.3')
264
264
265 if sys.version_info < (3, 3):
265 if sys.version_info < (3, 3):
266 extras_require['test'].append('mock')
266 extras_require['test'].append('mock')
267
267
268 extras_require['notebook'].extend(extras_require['nbformat'])
268 extras_require['notebook'].extend(extras_require['nbformat'])
269 extras_require['nbconvert'].extend(extras_require['nbformat'])
269 extras_require['nbconvert'].extend(extras_require['nbformat'])
270
270
271 install_requires = []
271 install_requires = []
272
272
273 # add readline
273 # add readline
274 if sys.platform == 'darwin':
274 if sys.platform == 'darwin':
275 if 'bdist_wheel' in sys.argv[1:] or not setupext.check_for_readline():
275 if 'bdist_wheel' in sys.argv[1:] or not setupext.check_for_readline():
276 install_requires.append('gnureadline')
276 install_requires.append('gnureadline')
277 elif sys.platform.startswith('win'):
277 elif sys.platform.startswith('win'):
278 extras_require['terminal'].append('pyreadline>=2.0')
278 extras_require['terminal'].append('pyreadline>=2.0')
279
279
280 everything = set()
280 everything = set()
281 for deps in extras_require.values():
281 for deps in extras_require.values():
282 everything.update(deps)
282 everything.update(deps)
283 extras_require['all'] = everything
283 extras_require['all'] = everything
284
284
285 if 'setuptools' in sys.modules:
285 if 'setuptools' in sys.modules:
286 # setup.py develop should check for submodules
286 # setup.py develop should check for submodules
287 from setuptools.command.develop import develop
287 from setuptools.command.develop import develop
288 setup_args['cmdclass']['develop'] = require_submodules(develop)
288 setup_args['cmdclass']['develop'] = require_submodules(develop)
289 setup_args['cmdclass']['bdist_wheel'] = css_js_prerelease(get_bdist_wheel())
289 setup_args['cmdclass']['bdist_wheel'] = css_js_prerelease(get_bdist_wheel())
290
290
291 setuptools_extra_args['zip_safe'] = False
291 setuptools_extra_args['zip_safe'] = False
292 setuptools_extra_args['entry_points'] = {
292 setuptools_extra_args['entry_points'] = {
293 'console_scripts': find_entry_points(),
293 'console_scripts': find_entry_points(),
294 'pygments.lexers': [
294 'pygments.lexers': [
295 'ipythonconsole = IPython.nbconvert.utils.lexers:IPythonConsoleLexer',
295 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
296 'ipython = IPython.nbconvert.utils.lexers:IPythonLexer',
296 'ipython = IPython.lib.lexers:IPythonLexer',
297 'ipython3 = IPython.nbconvert.utils.lexers:IPython3Lexer',
297 'ipython3 = IPython.lib.lexers:IPython3Lexer',
298 ],
298 ],
299 }
299 }
300 setup_args['extras_require'] = extras_require
300 setup_args['extras_require'] = extras_require
301 requires = setup_args['install_requires'] = install_requires
301 requires = setup_args['install_requires'] = install_requires
302
302
303 # Script to be run by the windows binary installer after the default setup
303 # Script to be run by the windows binary installer after the default setup
304 # routine, to add shortcuts and similar windows-only things. Windows
304 # routine, to add shortcuts and similar windows-only things. Windows
305 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
305 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
306 # doesn't find them.
306 # doesn't find them.
307 if 'bdist_wininst' in sys.argv:
307 if 'bdist_wininst' in sys.argv:
308 if len(sys.argv) > 2 and \
308 if len(sys.argv) > 2 and \
309 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
309 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
310 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
310 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
311 sys.exit(1)
311 sys.exit(1)
312 setup_args['data_files'].append(
312 setup_args['data_files'].append(
313 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
313 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
314 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
314 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
315 setup_args['options'] = {"bdist_wininst":
315 setup_args['options'] = {"bdist_wininst":
316 {"install_script":
316 {"install_script":
317 "ipython_win_post_install.py"}}
317 "ipython_win_post_install.py"}}
318
318
319 else:
319 else:
320 # If we are installing without setuptools, call this function which will
320 # If we are installing without setuptools, call this function which will
321 # check for dependencies an inform the user what is needed. This is
321 # check for dependencies an inform the user what is needed. This is
322 # just to make life easy for users.
322 # just to make life easy for users.
323 for install_cmd in ('install', 'symlink'):
323 for install_cmd in ('install', 'symlink'):
324 if install_cmd in sys.argv:
324 if install_cmd in sys.argv:
325 check_for_dependencies()
325 check_for_dependencies()
326 break
326 break
327 # scripts has to be a non-empty list, or install_scripts isn't called
327 # scripts has to be a non-empty list, or install_scripts isn't called
328 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
328 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
329
329
330 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
330 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
331
331
332 #---------------------------------------------------------------------------
332 #---------------------------------------------------------------------------
333 # Do the actual setup now
333 # Do the actual setup now
334 #---------------------------------------------------------------------------
334 #---------------------------------------------------------------------------
335
335
336 setup_args.update(setuptools_extra_args)
336 setup_args.update(setuptools_extra_args)
337
337
338 def main():
338 def main():
339 setup(**setup_args)
339 setup(**setup_args)
340
340
341 if __name__ == '__main__':
341 if __name__ == '__main__':
342 main()
342 main()
General Comments 0
You need to be logged in to leave comments. Login now