##// END OF EJS Templates
Merge pull request #3734 from jdfreder/file_subdir...
Matthias Bussonnier -
r11642:321025c8 merge
parent child Browse files
Show More
@@ -131,7 +131,7 b' class Exporter(Configurable):'
131 131
132 132 default_transformers = List([nbtransformers.coalesce_streams,
133 133 nbtransformers.SVG2PDFTransformer,
134 nbtransformers.ExtractFigureTransformer,
134 nbtransformers.ExtractOutputTransformer,
135 135 nbtransformers.CSSHTMLHeaderTransformer,
136 136 nbtransformers.RevealHelpTransformer,
137 137 nbtransformers.LatexTransformer,
@@ -88,7 +88,7 b' class LatexExporter(Exporter):'
88 88 'NbConvertBase': {
89 89 'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
90 90 },
91 'ExtractFigureTransformer': {
91 'ExtractOutputTransformer': {
92 92 'enabled':True
93 93 },
94 94 'SVG2PDFTransformer': {
@@ -37,6 +37,6 b' class RSTExporter(Exporter):'
37 37
38 38 @property
39 39 def default_config(self):
40 c = Config({'ExtractFigureTransformer':{'enabled':True}})
40 c = Config({'ExtractOutputTransformer':{'enabled':True}})
41 41 c.merge(super(RSTExporter,self).default_config)
42 42 return c
@@ -45,16 +45,16 b' class TestExporter(ExportersTestsBase):'
45 45 assert len(output) > 0
46 46
47 47
48 def test_extract_figures(self):
48 def test_extract_outputs(self):
49 49 """
50 If the ExtractFigureTransformer is enabled, are figures extracted?
50 If the ExtractOutputTransformer is enabled, are outputs extracted?
51 51 """
52 config = Config({'ExtractFigureTransformer': {'enabled': True}})
52 config = Config({'ExtractOutputTransformer': {'enabled': True}})
53 53 exporter = self._make_exporter(config=config)
54 54 (output, resources) = exporter.from_filename(self._get_notebook())
55 55 assert resources is not None
56 assert 'figures' in resources
57 assert len(resources['figures']) > 0
56 assert 'outputs' in resources
57 assert len(resources['outputs']) > 0
58 58
59 59
60 60 def test_transformer_class(self):
@@ -15,13 +15,13 b' Command-line interface for the NbConvert conversion utility.'
15 15 #Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 #Stdlib imports
18 # Stdlib imports
19 19 from __future__ import print_function
20 20 import sys
21 21 import os
22 22 import glob
23 23
24 #From IPython
24 # From IPython
25 25 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
26 26 from IPython.config import catch_config_error, Configurable
27 27 from IPython.utils.traitlets import (
@@ -103,7 +103,7 b' class NbConvertApp(BaseIPythonApplication):'
103 103
104 104 > ipython nbconvert --config mycfg.py
105 105 """.format(get_export_names()))
106 #Writer specific variables
106 # Writer specific variables
107 107 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
108 108 help="""Instance of the writer class used to write the
109 109 results of the conversion.""")
@@ -121,7 +121,7 b' class NbConvertApp(BaseIPythonApplication):'
121 121 self.writer_factory = import_item(new)
122 122
123 123
124 #Other configurable variables
124 # Other configurable variables
125 125 export_format = CaselessStrEnum(get_export_names(),
126 126 default_value="full_html",
127 127 config=True,
@@ -153,7 +153,7 b' class NbConvertApp(BaseIPythonApplication):'
153 153 else:
154 154 patterns = self.notebooks
155 155
156 #Use glob to replace all the notebook patterns with filenames.
156 # Use glob to replace all the notebook patterns with filenames.
157 157 filenames = []
158 158 for pattern in patterns:
159 159 for filename in glob.glob(pattern):
@@ -179,17 +179,18 b' class NbConvertApp(BaseIPythonApplication):'
179 179 """
180 180 Convert the notebooks in the self.notebook traitlet
181 181 """
182 #Export each notebook
182 # Export each notebook
183 183 conversion_success = 0
184 184 for notebook_filename in self.notebooks:
185 185
186 #Get a unique key for the notebook and set it in the resources object.
186 # Get a unique key for the notebook and set it in the resources object.
187 187 basename = os.path.basename(notebook_filename)
188 188 notebook_name = basename[:basename.rfind('.')]
189 189 resources = {}
190 190 resources['unique_key'] = notebook_name
191 resources['output_files_dir'] = '%s_files' % notebook_name
191 192
192 #Try to export
193 # Try to export
193 194 try:
194 195 output, resources = export_by_name(self.export_format,
195 196 notebook_filename,
@@ -202,22 +203,22 b' class NbConvertApp(BaseIPythonApplication):'
202 203 "\n\t" + "\n\t".join(get_export_names()),
203 204 file=sys.stderr)
204 205 sys.exit(-1)
205 #except Exception as e:
206 #print("Error: could not export '%s'" % notebook_filename, file=sys.stderr)
207 #print(e, file=sys.stderr)
206 # except Exception as e:
207 # print("Error: could not export '%s'" % notebook_filename, file=sys.stderr)
208 # print(e, file=sys.stderr)
208 209 else:
209 210 self.writer.write(output, resources, notebook_name=notebook_name)
210 211 conversion_success += 1
211 212
212 #If nothing was converted successfully, help the user.
213 # If nothing was converted successfully, help the user.
213 214 if conversion_success == 0:
214 215
215 #No notebooks were specified, show help.
216 # No notebooks were specified, show help.
216 217 if len(self.notebooks) == 0:
217 218 self.print_help()
218 219
219 #Notebooks were specified, but not converted successfully. Show how
220 #to access help.
220 # Notebooks were specified, but not converted successfully. Show how
221 # to access help.
221 222 else:
222 223 print('For help, use "ipython nbconvert --help"')
223 224
@@ -23,7 +23,7 b' from IPython.utils import py3compat'
23 23 # Constants
24 24 #-----------------------------------------------------------------------------
25 25
26 #Define ipython commandline name
26 # Define ipython commandline name
27 27 if py3compat.PY3:
28 28 IPYTHON = 'ipython3'
29 29 else:
@@ -53,8 +53,8 b' class TestNbConvertApp(TestsBase):'
53 53 with self.create_temp_cwd(['notebook*.ipynb']):
54 54 assert not 'error' in self.call([IPYTHON, 'nbconvert',
55 55 '--format="python"', '--notebooks=["*.ipynb"]']).lower()
56 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
57 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
56 assert os.path.isfile('notebook1.py')
57 assert os.path.isfile('notebook2.py')
58 58
59 59
60 60 def test_glob_subdir(self):
@@ -65,8 +65,8 b' class TestNbConvertApp(TestsBase):'
65 65 self.copy_files_to(['notebook*.ipynb'], 'subdir/')
66 66 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
67 67 '--notebooks=["%s"]' % os.path.join('subdir', '*.ipynb')]).lower()
68 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
69 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
68 assert os.path.isfile('notebook1.py')
69 assert os.path.isfile('notebook2.py')
70 70
71 71
72 72 def test_explicit(self):
@@ -76,8 +76,8 b' class TestNbConvertApp(TestsBase):'
76 76 with self.create_temp_cwd(['notebook*.ipynb']):
77 77 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
78 78 '--notebooks=["notebook2.ipynb"]']).lower()
79 assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
80 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
79 assert not os.path.isfile('notebook1.py')
80 assert os.path.isfile('notebook2.py')
81 81
82 82
83 83 def test_glob_explicit(self):
@@ -87,8 +87,8 b' class TestNbConvertApp(TestsBase):'
87 87 with self.create_temp_cwd(['notebook*.ipynb']):
88 88 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
89 89 '--notebooks=["*.ipynb", "notebook1.ipynb", "notebook2.ipynb"]']).lower()
90 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
91 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
90 assert os.path.isfile('notebook1.py')
91 assert os.path.isfile('notebook2.py')
92 92
93 93
94 94 def test_explicit_glob(self):
@@ -98,8 +98,8 b' class TestNbConvertApp(TestsBase):'
98 98 with self.create_temp_cwd(['notebook*.ipynb']):
99 99 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
100 100 '--notebooks=["notebook1.ipynb", "notebook2.ipynb", "*.ipynb"]']).lower()
101 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
102 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
101 assert os.path.isfile('notebook1.py')
102 assert os.path.isfile('notebook2.py')
103 103
104 104
105 105 def test_default_config(self):
@@ -108,8 +108,8 b' class TestNbConvertApp(TestsBase):'
108 108 """
109 109 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']):
110 110 assert not 'error' in self.call([IPYTHON, 'nbconvert']).lower()
111 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
112 assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
111 assert os.path.isfile('notebook1.py')
112 assert not os.path.isfile('notebook2.py')
113 113
114 114
115 115 def test_override_config(self):
@@ -119,5 +119,5 b' class TestNbConvertApp(TestsBase):'
119 119 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py',
120 120 'override.py']):
121 121 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--config="override.py"']).lower()
122 assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
123 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
122 assert not os.path.isfile('notebook1.py')
123 assert os.path.isfile('notebook2.py')
@@ -2,7 +2,7 b''
2 2 from .base import Transformer
3 3 from .convertfigures import ConvertFiguresTransformer
4 4 from .svg2pdf import SVG2PDFTransformer
5 from .extractfigure import ExtractFigureTransformer
5 from .extractoutput import ExtractOutputTransformer
6 6 from .revealhelp import RevealHelpTransformer
7 7 from .latex import LatexTransformer
8 8 from .sphinx import SphinxTransformer
@@ -46,10 +46,10 b' class ConvertFiguresTransformer(Transformer):'
46 46 See base.py
47 47 """
48 48
49 #Loop through all of the datatypes of the outputs in the cell.
49 # Loop through all of the datatypes of the outputs in the cell.
50 50 for index, cell_out in enumerate(cell.get('outputs', [])):
51 51 for data_type, data in cell_out.items():
52 # this must run *before* extract figures,
52 # this must run *before* extract outputs,
53 53 # so figure_name and filename do not exist
54 54 self._convert_figure(cell_out, resources, data_type, data)
55 55 return cell, resources
@@ -1,5 +1,5 b''
1 """Module containing a transformer that extracts all of the figures from the
2 notebook file. The extracted figures are returned in the 'resources' dictionary.
1 """Module containing a transformer that extracts all of the outputs from the
2 notebook file. The extracted outputs are returned in the 'resources' dictionary.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
@@ -15,6 +15,7 b" notebook file. The extracted figures are returned in the 'resources' dictionary"
15 15
16 16 import base64
17 17 import sys
18 import os
18 19
19 20 from IPython.utils.traitlets import Unicode
20 21 from .base import Transformer
@@ -24,10 +25,10 b' from IPython.utils import py3compat'
24 25 # Classes
25 26 #-----------------------------------------------------------------------------
26 27
27 class ExtractFigureTransformer(Transformer):
28 class ExtractOutputTransformer(Transformer):
28 29 """
29 Extracts all of the figures from the notebook file. The extracted
30 figures are returned in the 'resources' dictionary.
30 Extracts all of the outputs from the notebook file. The extracted
31 outputs are returned in the 'resources' dictionary.
31 32 """
32 33
33 34 figure_filename_template = Unicode(
@@ -50,12 +51,14 b' class ExtractFigureTransformer(Transformer):'
50 51 """
51 52
52 53 #Get the unique key from the resource dict if it exists. If it does not
53 #exist, use 'figure' as the default.
54 #exist, use 'figure' as the default. Also, get files directory if it
55 #has been specified
54 56 unique_key = resources.get('unique_key', 'figure')
57 output_files_dir = resources.get('output_files_dir', None)
55 58
56 #Make sure figures key exists
57 if not 'figures' in resources:
58 resources['figures'] = {}
59 #Make sure outputs key exists
60 if not 'outputs' in resources:
61 resources['outputs'] = {}
59 62
60 63 #Loop through all of the outputs in the cell
61 64 for index, out in enumerate(cell.get('outputs', [])):
@@ -77,7 +80,7 b' class ExtractFigureTransformer(Transformer):'
77 80 data = data.encode("UTF-8")
78 81
79 82 #Build a figure name
80 figure_name = self.figure_filename_template.format(
83 filename = self.figure_filename_template.format(
81 84 unique_key=unique_key,
82 85 cell_index=cell_index,
83 86 index=index,
@@ -87,10 +90,12 b' class ExtractFigureTransformer(Transformer):'
87 90 # cell.outputs[i].svg_filename ... etc (svg in example)
88 91 # Where
89 92 # cell.outputs[i].svg contains the data
90 out[out_type + '_filename'] = figure_name
93 if output_files_dir is not None:
94 filename = os.path.join(output_files_dir, filename)
95 out[out_type + '_filename'] = filename
91 96
92 97 #In the resources, make the figure available via
93 # resources['figures']['filename'] = data
94 resources['figures'][figure_name] = data
98 # resources['outputs']['filename'] = data
99 resources['outputs'][filename] = data
95 100
96 101 return cell, resources
@@ -34,10 +34,10 b' class DebugWriter(WriterBase):'
34 34 See base for more...
35 35 """
36 36
37 if 'figures' in resources:
38 print("Figures extracted from %s" % notebook_name)
37 if 'outputs' in resources:
38 print("outputs extracted from %s" % notebook_name)
39 39 print('-' * 80)
40 pprint.pprint(resources['figures'], indent=2, width=70)
40 pprint.pprint(resources['outputs'], indent=2, width=70)
41 41 else:
42 print("No figures extracted from %s" % notebook_name)
42 print("No outputs extracted from %s" % notebook_name)
43 43 print('=' * 80)
@@ -31,12 +31,12 b' class FilesWriter(WriterBase):'
31 31 """Consumes nbconvert output and produces files."""
32 32
33 33
34 build_directory = Unicode("nbconvert_build", config=True,
34 build_directory = Unicode(".", config=True,
35 35 help="""Directory to write output to. Leave blank
36 36 to output to the current directory""")
37 37
38 38
39 #Make sure that the output directory exists.
39 # Make sure that the output directory exists.
40 40 def _build_directory_changed(self, name, old, new):
41 41 if new and not os.path.isdir(new):
42 42 os.makedirs(new)
@@ -57,42 +57,46 b' class FilesWriter(WriterBase):'
57 57 See base for more...
58 58 """
59 59
60 #Pull the extension from the resources dict.
60 # Pull the extension and subdir from the resources dict.
61 61 output_extension = resources['output_extension']
62 62
63 #Write all of the extracted resources to the destination directory.
64 #NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG
65 #TRANSFORMER SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
66 for filename, data in resources.get('figures', {}).items():
63 # Write all of the extracted resources to the destination directory.
64 # NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG
65 # TRANSFORMER SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
66 for filename, data in resources.get('outputs', {}).items():
67 67
68 #Determine where to write the file to
68 # Determine where to write the file to
69 69 dest = os.path.join(self.build_directory, filename)
70 path = os.path.dirname(dest)
71 if not os.path.isdir(path):
72 os.makedirs(path)
70 73
71 #Write file
74 # Write file
72 75 with io.open(dest, 'wb') as f:
73 76 f.write(data)
74 77
75 #Copy referenced files to output directory
78 # Copy referenced files to output directory
76 79 if self.build_directory:
77 80 for filename in self.files:
78 81
79 #Copy files that match search pattern
82 # Copy files that match search pattern
80 83 for matching_filename in glob.glob(filename):
81 84
82 #Make sure folder exists.
85 # Make sure folder exists.
83 86 dest = os.path.join(self.build_directory, filename)
84 87 path = os.path.dirname(dest)
85 88 if not os.path.isdir(path):
86 89 os.makedirs(path)
87 90
88 #Copy
89 shutil.copyfile(matching_filename, dest)
91 # Copy if destination is different.
92 if not os.path.normpath(dest) == os.path.normpath(matching_filename):
93 shutil.copyfile(matching_filename, dest)
90 94
91 #Determine where to write conversion results.
95 # Determine where to write conversion results.
92 96 dest = notebook_name + '.' + output_extension
93 97 if self.build_directory:
94 98 dest = os.path.join(self.build_directory, dest)
95 99
96 #Write conversion results.
100 # Write conversion results.
97 101 with io.open(dest, 'w') as f:
98 102 f.write(output)
@@ -22,9 +22,7 b' from .base import WriterBase'
22 22
23 23 class StdoutWriter(WriterBase):
24 24 """Consumes output from nbconvert export...() methods and writes to the
25 stdout stream. Allows for quick debuging of nbconvert output. Using the
26 debug flag makes the writer pretty-print the figures contained within the
27 notebook."""
25 stdout stream."""
28 26
29 27
30 28 def write(self, output, resources, **kw):
General Comments 0
You need to be logged in to leave comments. Login now