##// END OF EJS Templates
Make mistune a requirement for nbconvert
Thomas Kluyver -
Show More
@@ -1,29 +1,28
1 1 # http://travis-ci.org/#!/ipython/ipython
2 2 language: python
3 3 python:
4 4 - 3.4
5 5 - 2.7
6 6 - 3.3
7 7 env:
8 8 - GROUP=js
9 9 - GROUP=
10 10 before_install:
11 11 # workaround for https://github.com/travis-ci/travis-cookbooks/issues/155
12 12 - sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm
13 13 # Pierre Carrier's PPA for PhantomJS and CasperJS
14 14 - time sudo add-apt-repository -y ppa:pcarrier/ppa
15 15 - time sudo apt-get update
16 16 - time sudo apt-get install pandoc casperjs nodejs libzmq3-dev
17 17 # pin tornado < 4 for js tests while phantom is on super old webkit
18 18 - if [[ $GROUP == 'js' ]]; then pip install 'tornado<4'; fi
19 - time pip install -f https://nipy.bic.berkeley.edu/wheelhouse/travis jinja2 sphinx pygments tornado requests mock pyzmq jsonschema jsonpointer
20 - time npm install -g requirejs jquery
19 - time pip install -f https://nipy.bic.berkeley.edu/wheelhouse/travis jinja2 sphinx pygments tornado requests mock pyzmq jsonschema jsonpointer mistune
21 20 install:
22 21 - time python setup.py install -q
23 22 script:
24 23 - cd /tmp && iptest $GROUP
25 24
26 25 matrix:
27 26 exclude:
28 27 - python: 3.3
29 28 env: GROUP=js
@@ -1,164 +1,153
1 1 """Markdown filters
2 2 This file contains a collection of utility filters for dealing with
3 3 markdown within Jinja templates.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib imports
19 19 import os
20 20 import subprocess
21 import warnings
22 21 from io import TextIOWrapper, BytesIO
23 22
24 try:
25 import mistune
26 except ImportError:
27 mistune = None
23 import mistune
24 from pygments import highlight
25 from pygments.lexers import get_lexer_by_name
26 from pygments.formatters import HtmlFormatter
28 27
29 28 # IPython imports
30 29 from IPython.nbconvert.utils.pandoc import pandoc
31 30 from IPython.nbconvert.utils.exceptions import ConversionException
32 31 from IPython.utils.process import get_output_error_code
33 32 from IPython.utils.py3compat import cast_bytes
34 33 from IPython.utils.version import check_version
35 34
36 35 #-----------------------------------------------------------------------------
37 36 # Functions
38 37 #-----------------------------------------------------------------------------
39 38 marked = os.path.join(os.path.dirname(__file__), "marked.js")
40 39 _node = None
41 40
42 41 __all__ = [
43 42 'markdown2html',
44 43 'markdown2html_pandoc',
45 44 'markdown2html_marked',
46 45 'markdown2html_mistune',
47 46 'markdown2latex',
48 47 'markdown2rst',
49 48 ]
50 49
51 50 class NodeJSMissing(ConversionException):
52 51 """Exception raised when node.js is missing."""
53 52 pass
54 53
55 54 def markdown2latex(source):
56 55 """Convert a markdown string to LaTeX via pandoc.
57 56
58 57 This function will raise an error if pandoc is not installed.
59 58 Any error messages generated by pandoc are printed to stderr.
60 59
61 60 Parameters
62 61 ----------
63 62 source : string
64 63 Input string, assumed to be valid markdown.
65 64
66 65 Returns
67 66 -------
68 67 out : string
69 68 Output as returned by pandoc.
70 69 """
71 70 return pandoc(source, 'markdown', 'latex')
72 71
73 def markdown2html(source):
74 """Convert a markdown string to HTML"""
75 global _node
76 if _node is None:
77 # prefer md2html via marked if node.js >= 0.9.12 is available
78 # node is called nodejs on debian, so try that first
79 _node = 'nodejs'
80 if not _verify_node(_node):
81 _node = 'node'
82 if not _verify_node(_node):
83 warnings.warn( "Node.js 0.9.12 or later wasn't found.\n" +
84 "Nbconvert will try to use Pandoc instead.")
85 _node = False
86 if _node:
87 return markdown2html_marked(source)
88 if mistune is not None:
89 return markdown2html_mistune(source)
90 else:
91 return markdown2html_pandoc(source)
92
93 if mistune is not None:
94 from pygments import highlight
95 from pygments.lexers import get_lexer_by_name
96 from pygments.formatters import HtmlFormatter
97
98 class MyRenderer(mistune.Renderer):
99 def block_code(self, code, lang):
100 if not lang:
101 return '\n<pre><code>%s</code></pre>\n' % \
102 mistune.escape(code)
103 lexer = get_lexer_by_name(lang, stripall=True)
104 formatter = HtmlFormatter()
105 return highlight(code, lexer, formatter)
72
73 class MyRenderer(mistune.Renderer):
74 def block_code(self, code, lang):
75 if not lang:
76 return '\n<pre><code>%s</code></pre>\n' % \
77 mistune.escape(code)
78 lexer = get_lexer_by_name(lang, stripall=True)
79 formatter = HtmlFormatter()
80 return highlight(code, lexer, formatter)
106 81
107 82 def markdown2html_mistune(source):
83 """Convert a markdown string to HTML using mistune"""
108 84 return mistune.Markdown(renderer=MyRenderer()).render(source)
109 85
110 86 def markdown2html_pandoc(source):
111 87 """Convert a markdown string to HTML via pandoc"""
112 88 return pandoc(source, 'markdown', 'html', extra_args=['--mathjax'])
113 89
90 def _find_nodejs():
91 global _node
92 if _node is None:
93 # prefer md2html via marked if node.js >= 0.9.12 is available
94 # node is called nodejs on debian, so try that first
95 _node = 'nodejs'
96 if not _verify_node(_node):
97 _node = 'node'
98 return _node
99
114 100 def markdown2html_marked(source, encoding='utf-8'):
115 101 """Convert a markdown string to HTML via marked"""
116 command = [_node, marked]
102 command = [_find_nodejs(), marked]
117 103 try:
118 104 p = subprocess.Popen(command,
119 105 stdin=subprocess.PIPE, stdout=subprocess.PIPE
120 106 )
121 107 except OSError as e:
122 108 raise NodeJSMissing(
123 109 "The command '%s' returned an error: %s.\n" % (" ".join(command), e) +
124 110 "Please check that Node.js is installed."
125 111 )
126 112 out, _ = p.communicate(cast_bytes(source, encoding))
127 113 out = TextIOWrapper(BytesIO(out), encoding, 'replace').read()
128 114 return out.rstrip('\n')
129 115
116 # The mistune renderer is the default, because it's simple to depend on it
117 markdown2html = markdown2html_mistune
118
130 119 def markdown2rst(source):
131 120 """Convert a markdown string to ReST via pandoc.
132 121
133 122 This function will raise an error if pandoc is not installed.
134 123 Any error messages generated by pandoc are printed to stderr.
135 124
136 125 Parameters
137 126 ----------
138 127 source : string
139 128 Input string, assumed to be valid markdown.
140 129
141 130 Returns
142 131 -------
143 132 out : string
144 133 Output as returned by pandoc.
145 134 """
146 135 return pandoc(source, 'markdown', 'rst')
147 136
148 137 def _verify_node(cmd):
149 138 """Verify that the node command exists and is at least the minimum supported
150 139 version of node.
151 140
152 141 Parameters
153 142 ----------
154 143 cmd : string
155 144 Node command to verify (i.e 'node')."""
156 145 try:
157 146 out, err, return_code = get_output_error_code([cmd, '--version'])
158 147 except OSError:
159 148 # Command not found
160 149 return False
161 150 if return_code:
162 151 # Command error
163 152 return False
164 153 return check_version(out.lstrip('v'), '0.9.12')
@@ -1,352 +1,352
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.rst, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23 from __future__ import print_function
24 24
25 25 import sys
26 26
27 27 # This check is also made in IPython/__init__, don't forget to update both when
28 28 # changing Python version requirements.
29 29 v = sys.version_info
30 30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 32 print(error, file=sys.stderr)
33 33 sys.exit(1)
34 34
35 35 PY3 = (sys.version_info[0] >= 3)
36 36
37 37 # At least we're on the python version we need, move on.
38 38
39 39 #-------------------------------------------------------------------------------
40 40 # Imports
41 41 #-------------------------------------------------------------------------------
42 42
43 43 # Stdlib imports
44 44 import os
45 45 import shutil
46 46
47 47 from glob import glob
48 48
49 49 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
50 50 # update it when the contents of directories change.
51 51 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
52 52
53 53 from distutils.core import setup
54 54
55 55 # Our own imports
56 56 from setupbase import target_update
57 57
58 58 from setupbase import (
59 59 setup_args,
60 60 find_packages,
61 61 find_package_data,
62 62 check_package_data_first,
63 63 find_entry_points,
64 64 build_scripts_entrypt,
65 65 find_data_files,
66 66 check_for_dependencies,
67 67 git_prebuild,
68 68 check_submodule_status,
69 69 update_submodules,
70 70 require_submodules,
71 71 UpdateSubmodules,
72 72 get_bdist_wheel,
73 73 CompileCSS,
74 74 JavascriptVersion,
75 75 install_symlinked,
76 76 install_lib_symlink,
77 77 install_scripts_for_symlink,
78 78 unsymlink,
79 79 )
80 80 from setupext import setupext
81 81
82 82 isfile = os.path.isfile
83 83 pjoin = os.path.join
84 84
85 85 #-----------------------------------------------------------------------------
86 86 # Function definitions
87 87 #-----------------------------------------------------------------------------
88 88
89 89 def cleanup():
90 90 """Clean up the junk left around by the build process"""
91 91 if "develop" not in sys.argv and "egg_info" not in sys.argv:
92 92 try:
93 93 shutil.rmtree('ipython.egg-info')
94 94 except:
95 95 try:
96 96 os.unlink('ipython.egg-info')
97 97 except:
98 98 pass
99 99
100 100 #-------------------------------------------------------------------------------
101 101 # Handle OS specific things
102 102 #-------------------------------------------------------------------------------
103 103
104 104 if os.name in ('nt','dos'):
105 105 os_name = 'windows'
106 106 else:
107 107 os_name = os.name
108 108
109 109 # Under Windows, 'sdist' has not been supported. Now that the docs build with
110 110 # Sphinx it might work, but let's not turn it on until someone confirms that it
111 111 # actually works.
112 112 if os_name == 'windows' and 'sdist' in sys.argv:
113 113 print('The sdist command is not available under Windows. Exiting.')
114 114 sys.exit(1)
115 115
116 116 #-------------------------------------------------------------------------------
117 117 # Make sure we aren't trying to run without submodules
118 118 #-------------------------------------------------------------------------------
119 119 here = os.path.abspath(os.path.dirname(__file__))
120 120
121 121 def require_clean_submodules():
122 122 """Check on git submodules before distutils can do anything
123 123
124 124 Since distutils cannot be trusted to update the tree
125 125 after everything has been set in motion,
126 126 this is not a distutils command.
127 127 """
128 128 # PACKAGERS: Add a return here to skip checks for git submodules
129 129
130 130 # don't do anything if nothing is actually supposed to happen
131 131 for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
132 132 if do_nothing in sys.argv:
133 133 return
134 134
135 135 status = check_submodule_status(here)
136 136
137 137 if status == "missing":
138 138 print("checking out submodules for the first time")
139 139 update_submodules(here)
140 140 elif status == "unclean":
141 141 print('\n'.join([
142 142 "Cannot build / install IPython with unclean submodules",
143 143 "Please update submodules with",
144 144 " python setup.py submodule",
145 145 "or",
146 146 " git submodule update",
147 147 "or commit any submodule changes you have made."
148 148 ]))
149 149 sys.exit(1)
150 150
151 151 require_clean_submodules()
152 152
153 153 #-------------------------------------------------------------------------------
154 154 # Things related to the IPython documentation
155 155 #-------------------------------------------------------------------------------
156 156
157 157 # update the manuals when building a source dist
158 158 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
159 159
160 160 # List of things to be updated. Each entry is a triplet of args for
161 161 # target_update()
162 162 to_update = [
163 163 # FIXME - Disabled for now: we need to redo an automatic way
164 164 # of generating the magic info inside the rst.
165 165 #('docs/magic.tex',
166 166 #['IPython/Magic.py'],
167 167 #"cd doc && ./update_magic.sh" ),
168 168
169 169 ('docs/man/ipcluster.1.gz',
170 170 ['docs/man/ipcluster.1'],
171 171 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
172 172
173 173 ('docs/man/ipcontroller.1.gz',
174 174 ['docs/man/ipcontroller.1'],
175 175 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
176 176
177 177 ('docs/man/ipengine.1.gz',
178 178 ['docs/man/ipengine.1'],
179 179 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
180 180
181 181 ('docs/man/ipython.1.gz',
182 182 ['docs/man/ipython.1'],
183 183 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
184 184
185 185 ]
186 186
187 187
188 188 [ target_update(*t) for t in to_update ]
189 189
190 190 #---------------------------------------------------------------------------
191 191 # Find all the packages, package data, and data_files
192 192 #---------------------------------------------------------------------------
193 193
194 194 packages = find_packages()
195 195 package_data = find_package_data()
196 196
197 197 data_files = find_data_files()
198 198
199 199 setup_args['packages'] = packages
200 200 setup_args['package_data'] = package_data
201 201 setup_args['data_files'] = data_files
202 202
203 203 #---------------------------------------------------------------------------
204 204 # custom distutils commands
205 205 #---------------------------------------------------------------------------
206 206 # imports here, so they are after setuptools import if there was one
207 207 from distutils.command.sdist import sdist
208 208 from distutils.command.upload import upload
209 209
210 210 class UploadWindowsInstallers(upload):
211 211
212 212 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
213 213 user_options = upload.user_options + [
214 214 ('files=', 'f', 'exe file (or glob) to upload')
215 215 ]
216 216 def initialize_options(self):
217 217 upload.initialize_options(self)
218 218 meta = self.distribution.metadata
219 219 base = '{name}-{version}'.format(
220 220 name=meta.get_name(),
221 221 version=meta.get_version()
222 222 )
223 223 self.files = os.path.join('dist', '%s.*.exe' % base)
224 224
225 225 def run(self):
226 226 for dist_file in glob(self.files):
227 227 self.upload_file('bdist_wininst', 'any', dist_file)
228 228
229 229 setup_args['cmdclass'] = {
230 230 'build_py': check_package_data_first(git_prebuild('IPython')),
231 231 'sdist' : git_prebuild('IPython', sdist),
232 232 'upload_wininst' : UploadWindowsInstallers,
233 233 'submodule' : UpdateSubmodules,
234 234 'css' : CompileCSS,
235 235 'symlink': install_symlinked,
236 236 'install_lib_symlink': install_lib_symlink,
237 237 'install_scripts_sym': install_scripts_for_symlink,
238 238 'unsymlink': unsymlink,
239 239 'jsversion' : JavascriptVersion,
240 240 }
241 241
242 242 #---------------------------------------------------------------------------
243 243 # Handle scripts, dependencies, and setuptools specific things
244 244 #---------------------------------------------------------------------------
245 245
246 246 # For some commands, use setuptools. Note that we do NOT list install here!
247 247 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
248 248 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
249 249 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
250 250 'egg_info', 'easy_install', 'upload', 'install_egg_info',
251 251 ))
252 252 if sys.platform == 'win32':
253 253 # Depend on setuptools for install on *Windows only*
254 254 # If we get script-installation working without setuptools,
255 255 # then we can back off, but until then use it.
256 256 # See Issue #369 on GitHub for more
257 257 needs_setuptools.add('install')
258 258
259 259 if len(needs_setuptools.intersection(sys.argv)) > 0:
260 260 import setuptools
261 261
262 262 # This dict is used for passing extra arguments that are setuptools
263 263 # specific to setup
264 264 setuptools_extra_args = {}
265 265
266 266 # setuptools requirements
267 267
268 268 extras_require = dict(
269 269 parallel = ['pyzmq>=2.1.11'],
270 270 qtconsole = ['pyzmq>=2.1.11', 'pygments'],
271 271 zmq = ['pyzmq>=2.1.11'],
272 272 doc = ['Sphinx>=1.1', 'numpydoc'],
273 273 test = ['nose>=0.10.1'],
274 274 terminal = [],
275 275 nbformat = ['jsonschema>=2.0', 'jsonpointer>=1.3'],
276 276 notebook = ['tornado>=3.1', 'pyzmq>=2.1.11', 'jinja2'],
277 nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3']
277 nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3', 'mistune']
278 278 )
279 279
280 280 if sys.version_info < (3, 3):
281 281 extras_require['test'].append('mock')
282 282
283 283 extras_require['notebook'].extend(extras_require['nbformat'])
284 284 extras_require['nbconvert'].extend(extras_require['nbformat'])
285 285
286 286 everything = set()
287 287 for deps in extras_require.values():
288 288 everything.update(deps)
289 289 extras_require['all'] = everything
290 290
291 291 install_requires = []
292 292
293 293 # add readline
294 294 if sys.platform == 'darwin':
295 295 if any(arg.startswith('bdist') for arg in sys.argv) or not setupext.check_for_readline():
296 296 install_requires.append('gnureadline')
297 297 elif sys.platform.startswith('win'):
298 298 extras_require['terminal'].append('pyreadline>=2.0')
299 299
300 300
301 301 if 'setuptools' in sys.modules:
302 302 # setup.py develop should check for submodules
303 303 from setuptools.command.develop import develop
304 304 setup_args['cmdclass']['develop'] = require_submodules(develop)
305 305 setup_args['cmdclass']['bdist_wheel'] = get_bdist_wheel()
306 306
307 307 setuptools_extra_args['zip_safe'] = False
308 308 setuptools_extra_args['entry_points'] = {'console_scripts':find_entry_points()}
309 309 setup_args['extras_require'] = extras_require
310 310 requires = setup_args['install_requires'] = install_requires
311 311
312 312 # Script to be run by the windows binary installer after the default setup
313 313 # routine, to add shortcuts and similar windows-only things. Windows
314 314 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
315 315 # doesn't find them.
316 316 if 'bdist_wininst' in sys.argv:
317 317 if len(sys.argv) > 2 and \
318 318 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
319 319 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
320 320 sys.exit(1)
321 321 setup_args['data_files'].append(
322 322 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
323 323 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
324 324 setup_args['options'] = {"bdist_wininst":
325 325 {"install_script":
326 326 "ipython_win_post_install.py"}}
327 327
328 328 else:
329 329 # If we are installing without setuptools, call this function which will
330 330 # check for dependencies an inform the user what is needed. This is
331 331 # just to make life easy for users.
332 332 for install_cmd in ('install', 'symlink'):
333 333 if install_cmd in sys.argv:
334 334 check_for_dependencies()
335 335 break
336 336 # scripts has to be a non-empty list, or install_scripts isn't called
337 337 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
338 338
339 339 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
340 340
341 341 #---------------------------------------------------------------------------
342 342 # Do the actual setup now
343 343 #---------------------------------------------------------------------------
344 344
345 345 setup_args.update(setuptools_extra_args)
346 346
347 347 def main():
348 348 setup(**setup_args)
349 349 cleanup()
350 350
351 351 if __name__ == '__main__':
352 352 main()
General Comments 0
You need to be logged in to leave comments. Login now