##// END OF EJS Templates
Allow for files output without an extension
Jonathan Frederic -
Show More
@@ -1,112 +1,115 b''
1 """
1 """
2 Contains writer for writing nbconvert output to filesystem.
2 Contains writer for writing nbconvert output to filesystem.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 #Copyright (c) 2013, the IPython Development Team.
5 #Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 #Distributed under the terms of the Modified BSD License.
7 #Distributed under the terms of the Modified BSD License.
8 #
8 #
9 #The full license is in the file COPYING.txt, distributed with this software.
9 #The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import io
16 import io
17 import os
17 import os
18 import glob
18 import glob
19
19
20 from IPython.utils.traitlets import Unicode
20 from IPython.utils.traitlets import Unicode
21 from IPython.utils.path import link_or_copy
21 from IPython.utils.path import link_or_copy
22
22
23 from .base import WriterBase
23 from .base import WriterBase
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Classes
26 # Classes
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 class FilesWriter(WriterBase):
29 class FilesWriter(WriterBase):
30 """Consumes nbconvert output and produces files."""
30 """Consumes nbconvert output and produces files."""
31
31
32
32
33 build_directory = Unicode("", config=True,
33 build_directory = Unicode("", config=True,
34 help="""Directory to write output to. Leave blank
34 help="""Directory to write output to. Leave blank
35 to output to the current directory""")
35 to output to the current directory""")
36
36
37
37
38 # Make sure that the output directory exists.
38 # Make sure that the output directory exists.
39 def _build_directory_changed(self, name, old, new):
39 def _build_directory_changed(self, name, old, new):
40 if new and not os.path.isdir(new):
40 if new and not os.path.isdir(new):
41 os.makedirs(new)
41 os.makedirs(new)
42
42
43
43
44 def __init__(self, **kw):
44 def __init__(self, **kw):
45 super(FilesWriter, self).__init__(**kw)
45 super(FilesWriter, self).__init__(**kw)
46 self._build_directory_changed('build_directory', self.build_directory,
46 self._build_directory_changed('build_directory', self.build_directory,
47 self.build_directory)
47 self.build_directory)
48
48
49 def _makedir(self, path):
49 def _makedir(self, path):
50 """Make a directory if it doesn't already exist"""
50 """Make a directory if it doesn't already exist"""
51 if path and not os.path.isdir(path):
51 if path and not os.path.isdir(path):
52 self.log.info("Making directory %s", path)
52 self.log.info("Making directory %s", path)
53 os.makedirs(path)
53 os.makedirs(path)
54
54
55 def write(self, output, resources, notebook_name=None, **kw):
55 def write(self, output, resources, notebook_name=None, **kw):
56 """
56 """
57 Consume and write Jinja output to the file system. Output directory
57 Consume and write Jinja output to the file system. Output directory
58 is set via the 'build_directory' variable of this instance (a
58 is set via the 'build_directory' variable of this instance (a
59 configurable).
59 configurable).
60
60
61 See base for more...
61 See base for more...
62 """
62 """
63
63
64 # Verify that a notebook name is provided.
64 # Verify that a notebook name is provided.
65 if notebook_name is None:
65 if notebook_name is None:
66 raise AttributeError('notebook_name')
66 raise AttributeError('notebook_name')
67
67
68 # Pull the extension and subdir from the resources dict.
68 # Pull the extension and subdir from the resources dict.
69 output_extension = resources['output_extension']
69 output_extension = resources.get('output_extension', None)
70
70
71 # Write all of the extracted resources to the destination directory.
71 # Write all of the extracted resources to the destination directory.
72 # NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG
72 # NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG
73 # TRANSFORMER SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
73 # TRANSFORMER SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
74 for filename, data in resources.get('outputs', {}).items():
74 for filename, data in resources.get('outputs', {}).items():
75
75
76 # Determine where to write the file to
76 # Determine where to write the file to
77 dest = os.path.join(self.build_directory, filename)
77 dest = os.path.join(self.build_directory, filename)
78 path = os.path.dirname(dest)
78 path = os.path.dirname(dest)
79 self._makedir(path)
79 self._makedir(path)
80
80
81 # Write file
81 # Write file
82 self.log.debug("Writing %i bytes to support file %s", len(data), dest)
82 self.log.debug("Writing %i bytes to support file %s", len(data), dest)
83 with io.open(dest, 'wb') as f:
83 with io.open(dest, 'wb') as f:
84 f.write(data)
84 f.write(data)
85
85
86 # Copy referenced files to output directory
86 # Copy referenced files to output directory
87 if self.build_directory:
87 if self.build_directory:
88 for filename in self.files:
88 for filename in self.files:
89
89
90 # Copy files that match search pattern
90 # Copy files that match search pattern
91 for matching_filename in glob.glob(filename):
91 for matching_filename in glob.glob(filename):
92
92
93 # Make sure folder exists.
93 # Make sure folder exists.
94 dest = os.path.join(self.build_directory, filename)
94 dest = os.path.join(self.build_directory, filename)
95 path = os.path.dirname(dest)
95 path = os.path.dirname(dest)
96 self._makedir(path)
96 self._makedir(path)
97
97
98 # Copy if destination is different.
98 # Copy if destination is different.
99 if not os.path.normpath(dest) == os.path.normpath(matching_filename):
99 if not os.path.normpath(dest) == os.path.normpath(matching_filename):
100 self.log.info("Linking %s -> %s", matching_filename, dest)
100 self.log.info("Linking %s -> %s", matching_filename, dest)
101 link_or_copy(matching_filename, dest)
101 link_or_copy(matching_filename, dest)
102
102
103 # Determine where to write conversion results.
103 # Determine where to write conversion results.
104 dest = notebook_name + '.' + output_extension
104 if output_extension is not None:
105 dest = notebook_name + '.' + output_extension
106 else:
107 dest = notebook_name
105 if self.build_directory:
108 if self.build_directory:
106 dest = os.path.join(self.build_directory, dest)
109 dest = os.path.join(self.build_directory, dest)
107
110
108 # Write conversion results.
111 # Write conversion results.
109 self.log.info("Writing %i bytes to %s", len(output), dest)
112 self.log.info("Writing %i bytes to %s", len(output), dest)
110 with io.open(dest, 'w', encoding='utf-8') as f:
113 with io.open(dest, 'w', encoding='utf-8') as f:
111 f.write(output)
114 f.write(output)
112 return dest No newline at end of file
115 return dest
General Comments 0
You need to be logged in to leave comments. Login now