Show More
@@ -20,7 +20,6 b' from __future__ import print_function, absolute_import' | |||||
20 | import io |
|
20 | import io | |
21 | import os |
|
21 | import os | |
22 | import inspect |
|
22 | import inspect | |
23 | import types |
|
|||
24 | import copy |
|
23 | import copy | |
25 | import collections |
|
24 | import collections | |
26 | import datetime |
|
25 | import datetime | |
@@ -35,6 +34,7 b' from IPython.nbformat import current as nbformat' | |||||
35 | from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict |
|
34 | from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict | |
36 | from IPython.utils.importstring import import_item |
|
35 | from IPython.utils.importstring import import_item | |
37 | from IPython.utils.text import indent |
|
36 | from IPython.utils.text import indent | |
|
37 | from IPython.utils import py3compat | |||
38 |
|
38 | |||
39 | from IPython.nbconvert import transformers as nbtransformers |
|
39 | from IPython.nbconvert import transformers as nbtransformers | |
40 | from IPython.nbconvert import filters |
|
40 | from IPython.nbconvert import filters | |
@@ -247,11 +247,11 b' class Exporter(Configurable):' | |||||
247 | """ |
|
247 | """ | |
248 | if transformer is None: |
|
248 | if transformer is None: | |
249 | raise TypeError('transformer') |
|
249 | raise TypeError('transformer') | |
250 |
isclass = i |
|
250 | isclass = isinstance(transformer, type) | |
251 | constructed = not isclass |
|
251 | constructed = not isclass | |
252 |
|
252 | |||
253 | #Handle transformer's registration based on it's type |
|
253 | #Handle transformer's registration based on it's type | |
254 |
if constructed and isinstance(transformer, |
|
254 | if constructed and isinstance(transformer, py3compat.string_types): | |
255 | #Transformer is a string, import the namespace and recursively call |
|
255 | #Transformer is a string, import the namespace and recursively call | |
256 | #this register_transformer method |
|
256 | #this register_transformer method | |
257 | transformer_cls = import_item(transformer) |
|
257 | transformer_cls = import_item(transformer) | |
@@ -280,7 +280,7 b' class Exporter(Configurable):' | |||||
280 | raise TypeError('transformer') |
|
280 | raise TypeError('transformer') | |
281 |
|
281 | |||
282 |
|
282 | |||
283 | def register_filter(self, name, filter): |
|
283 | def register_filter(self, name, jinja_filter): | |
284 | """ |
|
284 | """ | |
285 | Register a filter. |
|
285 | Register a filter. | |
286 | A filter is a function that accepts and acts on one string. |
|
286 | A filter is a function that accepts and acts on one string. | |
@@ -292,31 +292,33 b' class Exporter(Configurable):' | |||||
292 | name to give the filter in the Jinja engine |
|
292 | name to give the filter in the Jinja engine | |
293 | filter : filter |
|
293 | filter : filter | |
294 | """ |
|
294 | """ | |
295 | if filter is None: |
|
295 | if jinja_filter is None: | |
296 | raise TypeError('filter') |
|
296 | raise TypeError('filter') | |
297 |
isclass = i |
|
297 | isclass = isinstance(jinja_filter, type) | |
298 | constructed = not isclass |
|
298 | constructed = not isclass | |
299 |
|
299 | |||
300 | #Handle filter's registration based on it's type |
|
300 | #Handle filter's registration based on it's type | |
301 |
if constructed and isinstance(filter, |
|
301 | if constructed and isinstance(jinja_filter, py3compat.string_types): | |
302 | #filter is a string, import the namespace and recursively call |
|
302 | #filter is a string, import the namespace and recursively call | |
303 | #this register_filter method |
|
303 | #this register_filter method | |
304 | filter_cls = import_item(filter) |
|
304 | filter_cls = import_item(jinja_filter) | |
305 | return self.register_filter(name, filter_cls) |
|
305 | return self.register_filter(name, filter_cls) | |
306 |
|
306 | |||
307 | if constructed and hasattr(filter, '__call__'): |
|
307 | if constructed and hasattr(jinja_filter, '__call__'): | |
308 | #filter is a function, no need to construct it. |
|
308 | #filter is a function, no need to construct it. | |
309 | self.environment.filters[name] = filter |
|
309 | self.environment.filters[name] = jinja_filter | |
310 | return filter |
|
310 | return jinja_filter | |
311 |
|
311 | |||
312 | elif isclass and isinstance(filter, MetaHasTraits): |
|
312 | elif isclass and isinstance(jinja_filter, MetaHasTraits): | |
313 | #filter is configurable. Make sure to pass in new default for |
|
313 | #filter is configurable. Make sure to pass in new default for | |
314 | #the enabled flag if one was specified. |
|
314 | #the enabled flag if one was specified. | |
315 |
|
|
315 | filter_instance = jinja_filter(parent=self) | |
|
316 | self.register_filter(name, filter_instance ) | |||
316 |
|
317 | |||
317 | elif isclass: |
|
318 | elif isclass: | |
318 | #filter is not configurable, construct it |
|
319 | #filter is not configurable, construct it | |
319 | self.register_filter(name, filter()) |
|
320 | filter_instance = jinja_filter() | |
|
321 | self.register_filter(name, filter_instance) | |||
320 |
|
322 | |||
321 | else: |
|
323 | else: | |
322 | #filter is an instance of something without a __call__ |
|
324 | #filter is an instance of something without a __call__ | |
@@ -382,12 +384,12 b' class Exporter(Configurable):' | |||||
382 | """ |
|
384 | """ | |
383 |
|
385 | |||
384 | #Add default filters to the Jinja2 environment |
|
386 | #Add default filters to the Jinja2 environment | |
385 |
for key, value in default_filters. |
|
387 | for key, value in default_filters.items(): | |
386 | self.register_filter(key, value) |
|
388 | self.register_filter(key, value) | |
387 |
|
389 | |||
388 | #Load user filters. Overwrite existing filters if need be. |
|
390 | #Load user filters. Overwrite existing filters if need be. | |
389 | if self.filters: |
|
391 | if self.filters: | |
390 |
for key, user_filter in self.filters. |
|
392 | for key, user_filter in self.filters.items(): | |
391 | self.register_filter(key, user_filter) |
|
393 | self.register_filter(key, user_filter) | |
392 |
|
394 | |||
393 |
|
395 |
@@ -145,7 +145,7 b' def ansi2latex(text):' | |||||
145 | if openbrack: |
|
145 | if openbrack: | |
146 | outstring += '}'*openbrack |
|
146 | outstring += '}'*openbrack | |
147 | openbrack = 0 |
|
147 | openbrack = 0 | |
148 |
if match.group() |
|
148 | if not (match.group() == coloransi.TermColors.Normal or openbrack): | |
149 | texform, openbrack = single_ansi2latex(match.group()) |
|
149 | texform, openbrack = single_ansi2latex(match.group()) | |
150 | outstring += texform |
|
150 | outstring += texform | |
151 | last_end = match.end() |
|
151 | last_end = match.end() |
@@ -23,7 +23,7 b" __all__ = ['DataTypeFilter']" | |||||
23 |
|
23 | |||
24 | class DataTypeFilter(NbConvertBase): |
|
24 | class DataTypeFilter(NbConvertBase): | |
25 | """ Returns the preferred display format """ |
|
25 | """ Returns the preferred display format """ | |
26 |
|
26 | |||
27 | def __call__(self, output): |
|
27 | def __call__(self, output): | |
28 | """ Return the first available format in the priority """ |
|
28 | """ Return the first available format in the priority """ | |
29 |
|
29 |
@@ -19,8 +19,6 b' templates.' | |||||
19 | import re |
|
19 | import re | |
20 | import textwrap |
|
20 | import textwrap | |
21 | from xml.etree import ElementTree |
|
21 | from xml.etree import ElementTree | |
22 | from types import StringTypes |
|
|||
23 |
|
||||
24 | from IPython.utils import py3compat |
|
22 | from IPython.utils import py3compat | |
25 |
|
23 | |||
26 | #----------------------------------------------------------------------------- |
|
24 | #----------------------------------------------------------------------------- | |
@@ -62,7 +60,7 b' def html_text(element):' | |||||
62 |
|
60 | |||
63 | Analog of jQuery's $(element).text() |
|
61 | Analog of jQuery's $(element).text() | |
64 | """ |
|
62 | """ | |
65 |
if isinstance(element, |
|
63 | if isinstance(element, py3compat.string_types): | |
66 | element = ElementTree.fromstring(element) |
|
64 | element = ElementTree.fromstring(element) | |
67 |
|
65 | |||
68 | text = element.text or "" |
|
66 | text = element.text or "" |
@@ -22,6 +22,7 b' import sys' | |||||
22 |
|
22 | |||
23 | import IPython |
|
23 | import IPython | |
24 | from IPython.utils.tempdir import TemporaryDirectory |
|
24 | from IPython.utils.tempdir import TemporaryDirectory | |
|
25 | from IPython.utils import py3compat | |||
25 |
|
26 | |||
26 | #----------------------------------------------------------------------------- |
|
27 | #----------------------------------------------------------------------------- | |
27 | # Classes and functions |
|
28 | # Classes and functions | |
@@ -167,5 +168,11 b' class TestsBase(object):' | |||||
167 |
|
168 | |||
168 |
|
169 | |||
169 | def call(self, parameters): |
|
170 | def call(self, parameters): | |
170 |
|
|
171 | output = subprocess.Popen(parameters, stdout=subprocess.PIPE).communicate()[0] | |
|
172 | ||||
|
173 | #Convert the output to a string if running Python3 | |||
|
174 | if py3compat.PY3: | |||
|
175 | return output.decode('utf-8') | |||
|
176 | else: | |||
|
177 | return output | |||
171 | No newline at end of file |
|
178 |
@@ -16,6 +16,20 b' Contains tests for the nbconvertapp' | |||||
16 | import os |
|
16 | import os | |
17 | from .base import TestsBase |
|
17 | from .base import TestsBase | |
18 |
|
18 | |||
|
19 | from IPython.utils import py3compat | |||
|
20 | ||||
|
21 | ||||
|
22 | #----------------------------------------------------------------------------- | |||
|
23 | # Constants | |||
|
24 | #----------------------------------------------------------------------------- | |||
|
25 | ||||
|
26 | #Define ipython commandline name | |||
|
27 | if py3compat.PY3: | |||
|
28 | IPYTHON = 'ipython3' | |||
|
29 | else: | |||
|
30 | IPYTHON = 'ipython' | |||
|
31 | ||||
|
32 | ||||
19 | #----------------------------------------------------------------------------- |
|
33 | #----------------------------------------------------------------------------- | |
20 | # Classes and functions |
|
34 | # Classes and functions | |
21 | #----------------------------------------------------------------------------- |
|
35 | #----------------------------------------------------------------------------- | |
@@ -29,7 +43,7 b' class TestNbConvertApp(TestsBase):' | |||||
29 | Will help show if no notebooks are specified? |
|
43 | Will help show if no notebooks are specified? | |
30 | """ |
|
44 | """ | |
31 | with self.create_temp_cwd(): |
|
45 | with self.create_temp_cwd(): | |
32 |
assert "see '--help-all'" in self.call([ |
|
46 | assert "see '--help-all'" in self.call([IPYTHON, 'nbconvert']) | |
33 |
|
47 | |||
34 |
|
48 | |||
35 | def test_glob(self): |
|
49 | def test_glob(self): | |
@@ -37,7 +51,7 b' class TestNbConvertApp(TestsBase):' | |||||
37 | Do search patterns work for notebook names? |
|
51 | Do search patterns work for notebook names? | |
38 | """ |
|
52 | """ | |
39 | with self.create_temp_cwd(['notebook*.ipynb']): |
|
53 | with self.create_temp_cwd(['notebook*.ipynb']): | |
40 |
assert not 'error' in self.call([ |
|
54 | assert not 'error' in self.call([IPYTHON, 'nbconvert', | |
41 | '--format="python"', '--notebooks=["*.ipynb"]']).lower() |
|
55 | '--format="python"', '--notebooks=["*.ipynb"]']).lower() | |
42 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
56 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
43 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
57 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) | |
@@ -49,7 +63,7 b' class TestNbConvertApp(TestsBase):' | |||||
49 | """ |
|
63 | """ | |
50 | with self.create_temp_cwd() as cwd: |
|
64 | with self.create_temp_cwd() as cwd: | |
51 | self.copy_files_to(['notebook*.ipynb'], 'subdir/') |
|
65 | self.copy_files_to(['notebook*.ipynb'], 'subdir/') | |
52 |
assert not 'error' in self.call([ |
|
66 | assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"', | |
53 | '--notebooks=["%s"]' % os.path.join('subdir', '*.ipynb')]).lower() |
|
67 | '--notebooks=["%s"]' % os.path.join('subdir', '*.ipynb')]).lower() | |
54 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
68 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
55 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
69 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) | |
@@ -60,7 +74,7 b' class TestNbConvertApp(TestsBase):' | |||||
60 | Do explicit notebook names work? |
|
74 | Do explicit notebook names work? | |
61 | """ |
|
75 | """ | |
62 | with self.create_temp_cwd(['notebook*.ipynb']): |
|
76 | with self.create_temp_cwd(['notebook*.ipynb']): | |
63 |
assert not 'error' in self.call([ |
|
77 | assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"', | |
64 | '--notebooks=["notebook2.ipynb"]']).lower() |
|
78 | '--notebooks=["notebook2.ipynb"]']).lower() | |
65 | assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
79 | assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
66 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
80 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) | |
@@ -71,7 +85,7 b' class TestNbConvertApp(TestsBase):' | |||||
71 | Can a search pattern be used along with matching explicit notebook names? |
|
85 | Can a search pattern be used along with matching explicit notebook names? | |
72 | """ |
|
86 | """ | |
73 | with self.create_temp_cwd(['notebook*.ipynb']): |
|
87 | with self.create_temp_cwd(['notebook*.ipynb']): | |
74 |
assert not 'error' in self.call([ |
|
88 | assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"', | |
75 | '--notebooks=["*.ipynb", "notebook1.ipynb", "notebook2.ipynb"]']).lower() |
|
89 | '--notebooks=["*.ipynb", "notebook1.ipynb", "notebook2.ipynb"]']).lower() | |
76 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
90 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
77 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
91 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) | |
@@ -82,7 +96,7 b' class TestNbConvertApp(TestsBase):' | |||||
82 | Can explicit notebook names be used and then a matching search pattern? |
|
96 | Can explicit notebook names be used and then a matching search pattern? | |
83 | """ |
|
97 | """ | |
84 | with self.create_temp_cwd(['notebook*.ipynb']): |
|
98 | with self.create_temp_cwd(['notebook*.ipynb']): | |
85 |
assert not 'error' in self.call([ |
|
99 | assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"', | |
86 | '--notebooks=["notebook1.ipynb", "notebook2.ipynb", "*.ipynb"]']).lower() |
|
100 | '--notebooks=["notebook1.ipynb", "notebook2.ipynb", "*.ipynb"]']).lower() | |
87 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
101 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
88 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
102 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) | |
@@ -93,7 +107,7 b' class TestNbConvertApp(TestsBase):' | |||||
93 | Does the default config work? |
|
107 | Does the default config work? | |
94 | """ |
|
108 | """ | |
95 | with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']): |
|
109 | with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']): | |
96 |
assert not 'error' in self.call([ |
|
110 | assert not 'error' in self.call([IPYTHON, 'nbconvert']).lower() | |
97 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
111 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
98 | assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
112 | assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) | |
99 |
|
113 | |||
@@ -104,6 +118,6 b' class TestNbConvertApp(TestsBase):' | |||||
104 | """ |
|
118 | """ | |
105 | with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py', |
|
119 | with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py', | |
106 | 'override.py']): |
|
120 | 'override.py']): | |
107 |
assert not 'error' in self.call([ |
|
121 | assert not 'error' in self.call([IPYTHON, 'nbconvert', '--config="override.py"']).lower() | |
108 | assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) |
|
122 | assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py')) | |
109 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
|
123 | assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py')) |
@@ -16,6 +16,7 b" notebook file. The extracted figures are returned in the 'resources' dictionary" | |||||
16 | import sys |
|
16 | import sys | |
17 | from IPython.utils.traitlets import Unicode |
|
17 | from IPython.utils.traitlets import Unicode | |
18 | from .base import Transformer |
|
18 | from .base import Transformer | |
|
19 | from IPython.utils import py3compat | |||
19 |
|
20 | |||
20 | #----------------------------------------------------------------------------- |
|
21 | #----------------------------------------------------------------------------- | |
21 | # Classes |
|
22 | # Classes | |
@@ -64,7 +65,15 b' class ExtractFigureTransformer(Transformer):' | |||||
64 |
|
65 | |||
65 | #Binary files are base64-encoded, SVG is already XML |
|
66 | #Binary files are base64-encoded, SVG is already XML | |
66 | if out_type in ('png', 'jpg', 'jpeg', 'pdf'): |
|
67 | if out_type in ('png', 'jpg', 'jpeg', 'pdf'): | |
67 |
|
|
68 | ||
|
69 | #Python3 base64 is in a separate library... | |||
|
70 | if py3compat.PY3: | |||
|
71 | ||||
|
72 | #Base 64 decode the bytes | |||
|
73 | import base64 | |||
|
74 | data = base64.b64decode(data) | |||
|
75 | else: | |||
|
76 | data = data.decode('base64') | |||
68 | elif sys.platform == 'win32': |
|
77 | elif sys.platform == 'win32': | |
69 | data = data.replace('\n', '\r\n').encode("UTF-8") |
|
78 | data = data.replace('\n', '\r\n').encode("UTF-8") | |
70 | else: |
|
79 | else: |
@@ -27,7 +27,7 b' class DebugWriter(WriterBase):' | |||||
27 | resources that were extracted from the notebook(s) during export.""" |
|
27 | resources that were extracted from the notebook(s) during export.""" | |
28 |
|
28 | |||
29 |
|
29 | |||
30 | def write(self, output, resources, **kw): |
|
30 | def write(self, output, resources, notebook_name='notebook', **kw): | |
31 | """ |
|
31 | """ | |
32 | Consume and write Jinja output. |
|
32 | Consume and write Jinja output. | |
33 |
|
33 |
General Comments 0
You need to be logged in to leave comments.
Login now