##// END OF EJS Templates
Merge pull request #3924 from jdfreder/backport_fixes...
Min RK -
r12020:dfaefbe3 merge
parent child Browse files
Show More
@@ -1,74 +1,75 b''
1 """Module that allows latex output notebooks to be conditioned before
1 """Module that allows latex output notebooks to be conditioned before
2 they are converted. Exposes a decorator (@cell_preprocessor) in
2 they are converted. Exposes a decorator (@cell_preprocessor) in
3 addition to the coalesce_streams pre-proccessor.
3 addition to the coalesce_streams pre-proccessor.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Functions
14 # Functions
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 def cell_preprocessor(function):
17 def cell_preprocessor(function):
18 """
18 """
19 Wrap a function to be executed on all cells of a notebook
19 Wrap a function to be executed on all cells of a notebook
20
20
21 Wrapped Parameters
21 Wrapped Parameters
22 ----------
22 ----------
23 cell : NotebookNode cell
23 cell : NotebookNode cell
24 Notebook cell being processed
24 Notebook cell being processed
25 resources : dictionary
25 resources : dictionary
26 Additional resources used in the conversion process. Allows
26 Additional resources used in the conversion process. Allows
27 transformers to pass variables into the Jinja engine.
27 transformers to pass variables into the Jinja engine.
28 index : int
28 index : int
29 Index of the cell being processed
29 Index of the cell being processed
30 """
30 """
31
31
32 def wrappedfunc(nb, resources):
32 def wrappedfunc(nb, resources):
33 for worksheet in nb.worksheets :
33 for worksheet in nb.worksheets :
34 for index, cell in enumerate(worksheet.cells):
34 for index, cell in enumerate(worksheet.cells):
35 worksheet.cells[index], resources = function(cell, resources, index)
35 worksheet.cells[index], resources = function(cell, resources, index)
36 return nb, resources
36 return nb, resources
37 return wrappedfunc
37 return wrappedfunc
38
38
39
39
40 @cell_preprocessor
40 @cell_preprocessor
41 def coalesce_streams(cell, resources, index):
41 def coalesce_streams(cell, resources, index):
42 """
42 """
43 Merge consecutive sequences of stream output into single stream
43 Merge consecutive sequences of stream output into single stream
44 to prevent extra newlines inserted at flush calls
44 to prevent extra newlines inserted at flush calls
45
45
46 Parameters
46 Parameters
47 ----------
47 ----------
48 cell : NotebookNode cell
48 cell : NotebookNode cell
49 Notebook cell being processed
49 Notebook cell being processed
50 resources : dictionary
50 resources : dictionary
51 Additional resources used in the conversion process. Allows
51 Additional resources used in the conversion process. Allows
52 transformers to pass variables into the Jinja engine.
52 transformers to pass variables into the Jinja engine.
53 index : int
53 index : int
54 Index of the cell being processed
54 Index of the cell being processed
55 """
55 """
56
56
57 outputs = cell.get('outputs', [])
57 outputs = cell.get('outputs', [])
58 if not outputs:
58 if not outputs:
59 return cell, resources
59 return cell, resources
60
60
61 last = outputs[0]
61 last = outputs[0]
62 new_outputs = [last]
62 new_outputs = [last]
63
63
64 for output in outputs[1:]:
64 for output in outputs[1:]:
65 if (output.output_type == 'stream' and
65 if (output.output_type == 'stream' and
66 last.output_type == 'stream' and
66 last.output_type == 'stream' and
67 last.stream == output.stream
67 last.stream == output.stream
68 ):
68 ):
69 last.text += output.text
69 last.text += output.text
70 else:
70 else:
71 new_outputs.append(output)
71 new_outputs.append(output)
72 last = output
72
73
73 cell.outputs = new_outputs
74 cell.outputs = new_outputs
74 return cell, resources
75 return cell, resources
@@ -1,106 +1,106 b''
1 """Module that pre-processes the notebook for export to HTML.
1 """Module that pre-processes the notebook for export to HTML.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import io
16 import io
17
17
18 from pygments.formatters import HtmlFormatter
18 from pygments.formatters import HtmlFormatter
19
19
20 from IPython.utils import path
20 from IPython.utils import path
21
21
22 from .base import Transformer
22 from .base import Transformer
23
23
24 from IPython.utils.traitlets import Unicode
24 from IPython.utils.traitlets import Unicode
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Classes and functions
27 # Classes and functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 class CSSHTMLHeaderTransformer(Transformer):
30 class CSSHTMLHeaderTransformer(Transformer):
31 """
31 """
32 Transformer used to pre-process notebook for HTML output. Adds IPython notebook
32 Transformer used to pre-process notebook for HTML output. Adds IPython notebook
33 front-end CSS and Pygments CSS to HTML output.
33 front-end CSS and Pygments CSS to HTML output.
34 """
34 """
35
35
36 header = []
36 header = []
37
37
38 highlight_class = Unicode('.highlight', config=True,
38 highlight_class = Unicode('.highlight', config=True,
39 help="CSS highlight class identifier")
39 help="CSS highlight class identifier")
40
40
41 def __init__(self, config=None, **kw):
41 def __init__(self, config=None, **kw):
42 """
42 """
43 Public constructor
43 Public constructor
44
44
45 Parameters
45 Parameters
46 ----------
46 ----------
47 config : Config
47 config : Config
48 Configuration file structure
48 Configuration file structure
49 **kw : misc
49 **kw : misc
50 Additional arguments
50 Additional arguments
51 """
51 """
52
52
53 super(CSSHTMLHeaderTransformer, self).__init__(config=config, **kw)
53 super(CSSHTMLHeaderTransformer, self).__init__(config=config, **kw)
54
54
55 if self.enabled :
55 if self.enabled :
56 self._regen_header()
56 self._regen_header()
57
57
58
58
59 def __call__(self, nb, resources):
59 def call(self, nb, resources):
60 """Fetch and add CSS to the resource dictionary
60 """Fetch and add CSS to the resource dictionary
61
61
62 Fetch CSS from IPython and Pygments to add at the beginning
62 Fetch CSS from IPython and Pygments to add at the beginning
63 of the html files. Add this css in resources in the
63 of the html files. Add this css in resources in the
64 "inlining.css" key
64 "inlining.css" key
65
65
66 Parameters
66 Parameters
67 ----------
67 ----------
68 nb : NotebookNode
68 nb : NotebookNode
69 Notebook being converted
69 Notebook being converted
70 resources : dictionary
70 resources : dictionary
71 Additional resources used in the conversion process. Allows
71 Additional resources used in the conversion process. Allows
72 transformers to pass variables into the Jinja engine.
72 transformers to pass variables into the Jinja engine.
73 """
73 """
74
74
75 resources['inlining'] = {}
75 resources['inlining'] = {}
76 resources['inlining']['css'] = self.header
76 resources['inlining']['css'] = self.header
77
77
78 return nb, resources
78 return nb, resources
79
79
80
80
81 def _regen_header(self):
81 def _regen_header(self):
82 """
82 """
83 Fills self.header with lines of CSS extracted from IPython
83 Fills self.header with lines of CSS extracted from IPython
84 and Pygments.
84 and Pygments.
85 """
85 """
86
86
87 #Clear existing header.
87 #Clear existing header.
88 header = []
88 header = []
89
89
90 #Construct path to IPy CSS
90 #Construct path to IPy CSS
91 sheet_filename = os.path.join(path.get_ipython_package_dir(),
91 sheet_filename = os.path.join(path.get_ipython_package_dir(),
92 'html', 'static', 'style', 'style.min.css')
92 'html', 'static', 'style', 'style.min.css')
93
93
94 #Load style CSS file.
94 #Load style CSS file.
95 with io.open(sheet_filename, encoding='utf-8') as file:
95 with io.open(sheet_filename, encoding='utf-8') as file:
96 file_text = file.read()
96 file_text = file.read()
97 header.append(file_text)
97 header.append(file_text)
98
98
99 #Add pygments CSS
99 #Add pygments CSS
100 formatter = HtmlFormatter()
100 formatter = HtmlFormatter()
101 pygments_css = formatter.get_style_defs(self.highlight_class)
101 pygments_css = formatter.get_style_defs(self.highlight_class)
102 header.append(pygments_css)
102 header.append(pygments_css)
103
103
104 #Set header
104 #Set header
105 self.header = header
105 self.header = header
106
106
@@ -1,101 +1,101 b''
1 """Module containing a transformer that extracts all of the outputs from the
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.
2 notebook file. The extracted outputs are returned in the 'resources' dictionary.
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 base64
16 import base64
17 import sys
17 import sys
18 import os
18 import os
19
19
20 from IPython.utils.traitlets import Unicode
20 from IPython.utils.traitlets import Unicode
21 from .base import Transformer
21 from .base import Transformer
22 from IPython.utils import py3compat
22 from IPython.utils import py3compat
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes
25 # Classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class ExtractOutputTransformer(Transformer):
28 class ExtractOutputTransformer(Transformer):
29 """
29 """
30 Extracts all of the outputs from the notebook file. The extracted
30 Extracts all of the outputs from the notebook file. The extracted
31 outputs are returned in the 'resources' dictionary.
31 outputs are returned in the 'resources' dictionary.
32 """
32 """
33
33
34 figure_filename_template = Unicode(
34 output_filename_template = Unicode(
35 "{unique_key}_{cell_index}_{index}.{extension}", config=True)
35 "{unique_key}_{cell_index}_{index}.{extension}", config=True)
36
36
37
37
38 def transform_cell(self, cell, resources, cell_index):
38 def transform_cell(self, cell, resources, cell_index):
39 """
39 """
40 Apply a transformation on each cell,
40 Apply a transformation on each cell,
41
41
42 Parameters
42 Parameters
43 ----------
43 ----------
44 cell : NotebookNode cell
44 cell : NotebookNode cell
45 Notebook cell being processed
45 Notebook cell being processed
46 resources : dictionary
46 resources : dictionary
47 Additional resources used in the conversion process. Allows
47 Additional resources used in the conversion process. Allows
48 transformers to pass variables into the Jinja engine.
48 transformers to pass variables into the Jinja engine.
49 cell_index : int
49 cell_index : int
50 Index of the cell being processed (see base.py)
50 Index of the cell being processed (see base.py)
51 """
51 """
52
52
53 #Get the unique key from the resource dict if it exists. If it does not
53 #Get the unique key from the resource dict if it exists. If it does not
54 #exist, use 'figure' as the default. Also, get files directory if it
54 #exist, use 'output' as the default. Also, get files directory if it
55 #has been specified
55 #has been specified
56 unique_key = resources.get('unique_key', 'figure')
56 unique_key = resources.get('unique_key', 'output')
57 output_files_dir = resources.get('output_files_dir', None)
57 output_files_dir = resources.get('output_files_dir', None)
58
58
59 #Make sure outputs key exists
59 #Make sure outputs key exists
60 if not 'outputs' in resources:
60 if not 'outputs' in resources:
61 resources['outputs'] = {}
61 resources['outputs'] = {}
62
62
63 #Loop through all of the outputs in the cell
63 #Loop through all of the outputs in the cell
64 for index, out in enumerate(cell.get('outputs', [])):
64 for index, out in enumerate(cell.get('outputs', [])):
65
65
66 #Get the output in data formats that the template is interested in.
66 #Get the output in data formats that the template is interested in.
67 for out_type in self.display_data_priority:
67 for out_type in self.display_data_priority:
68 if out.hasattr(out_type):
68 if out.hasattr(out_type):
69 data = out[out_type]
69 data = out[out_type]
70
70
71 #Binary files are base64-encoded, SVG is already XML
71 #Binary files are base64-encoded, SVG is already XML
72 if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
72 if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
73 # data is b64-encoded as text (str, unicode)
73 # data is b64-encoded as text (str, unicode)
74 # decodestring only accepts bytes
74 # decodestring only accepts bytes
75 data = py3compat.cast_bytes(data)
75 data = py3compat.cast_bytes(data)
76 data = base64.decodestring(data)
76 data = base64.decodestring(data)
77 elif sys.platform == 'win32':
77 elif sys.platform == 'win32':
78 data = data.replace('\n', '\r\n').encode("UTF-8")
78 data = data.replace('\n', '\r\n').encode("UTF-8")
79 else:
79 else:
80 data = data.encode("UTF-8")
80 data = data.encode("UTF-8")
81
81
82 #Build a figure name
82 #Build an output name
83 filename = self.figure_filename_template.format(
83 filename = self.output_filename_template.format(
84 unique_key=unique_key,
84 unique_key=unique_key,
85 cell_index=cell_index,
85 cell_index=cell_index,
86 index=index,
86 index=index,
87 extension=out_type)
87 extension=out_type)
88
88
89 #On the cell, make the figure available via
89 #On the cell, make the figure available via
90 # cell.outputs[i].svg_filename ... etc (svg in example)
90 # cell.outputs[i].svg_filename ... etc (svg in example)
91 # Where
91 # Where
92 # cell.outputs[i].svg contains the data
92 # cell.outputs[i].svg contains the data
93 if output_files_dir is not None:
93 if output_files_dir is not None:
94 filename = os.path.join(output_files_dir, filename)
94 filename = os.path.join(output_files_dir, filename)
95 out[out_type + '_filename'] = filename
95 out[out_type + '_filename'] = filename
96
96
97 #In the resources, make the figure available via
97 #In the resources, make the figure available via
98 # resources['outputs']['filename'] = data
98 # resources['outputs']['filename'] = data
99 resources['outputs'][filename] = data
99 resources['outputs'][filename] = data
100
100
101 return cell, resources
101 return cell, resources
@@ -1,42 +1,42 b''
1 """
1 """
2 Contains debug writer.
2 Contains debug writer.
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 from .base import WriterBase
16 from .base import WriterBase
17 from pprint import pprint
17 from pprint import pprint
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Classes
20 # Classes
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 class DebugWriter(WriterBase):
23 class DebugWriter(WriterBase):
24 """Consumes output from nbconvert export...() methods and writes usefull
24 """Consumes output from nbconvert export...() methods and writes usefull
25 debugging information to the stdout. The information includes a list of
25 debugging information to the stdout. The information includes a list of
26 resources that were extracted from the notebook(s) during export."""
26 resources that were extracted from the notebook(s) during export."""
27
27
28
28
29 def write(self, output, resources, notebook_name='notebook', **kw):
29 def write(self, output, resources, notebook_name='notebook', **kw):
30 """
30 """
31 Consume and write Jinja output.
31 Consume and write Jinja output.
32
32
33 See base for more...
33 See base for more...
34 """
34 """
35
35
36 if 'outputs' in resources:
36 if 'outputs' in resources:
37 print("outputs extracted from %s" % notebook_name)
37 print("outputs extracted from %s" % notebook_name)
38 print('-' * 80)
38 print('-' * 80)
39 pprint.pprint(resources['outputs'], indent=2, width=70)
39 pprint(resources['outputs'], indent=2, width=70)
40 else:
40 else:
41 print("No outputs extracted from %s" % notebook_name)
41 print("no outputs extracted from %s" % notebook_name)
42 print('=' * 80)
42 print('=' * 80)
@@ -1,108 +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 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.
65 if notebook_name is None:
66 raise TypeError('notebook_name')
67
64 # Pull the extension and subdir from the resources dict.
68 # Pull the extension and subdir from the resources dict.
65 output_extension = resources['output_extension']
69 output_extension = resources.get('output_extension', None)
66
70
67 # Write all of the extracted resources to the destination directory.
71 # Write all of the extracted resources to the destination directory.
68 # 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
69 # TRANSFORMER SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
73 # TRANSFORMER SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS...
70 for filename, data in resources.get('outputs', {}).items():
74 for filename, data in resources.get('outputs', {}).items():
71
75
72 # Determine where to write the file to
76 # Determine where to write the file to
73 dest = os.path.join(self.build_directory, filename)
77 dest = os.path.join(self.build_directory, filename)
74 path = os.path.dirname(dest)
78 path = os.path.dirname(dest)
75 self._makedir(path)
79 self._makedir(path)
76
80
77 # Write file
81 # Write file
78 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)
79 with io.open(dest, 'wb') as f:
83 with io.open(dest, 'wb') as f:
80 f.write(data)
84 f.write(data)
81
85
82 # Copy referenced files to output directory
86 # Copy referenced files to output directory
83 if self.build_directory:
87 if self.build_directory:
84 for filename in self.files:
88 for filename in self.files:
85
89
86 # Copy files that match search pattern
90 # Copy files that match search pattern
87 for matching_filename in glob.glob(filename):
91 for matching_filename in glob.glob(filename):
88
92
89 # Make sure folder exists.
93 # Make sure folder exists.
90 dest = os.path.join(self.build_directory, filename)
94 dest = os.path.join(self.build_directory, filename)
91 path = os.path.dirname(dest)
95 path = os.path.dirname(dest)
92 self._makedir(path)
96 self._makedir(path)
93
97
94 # Copy if destination is different.
98 # Copy if destination is different.
95 if not os.path.normpath(dest) == os.path.normpath(matching_filename):
99 if not os.path.normpath(dest) == os.path.normpath(matching_filename):
96 self.log.info("Linking %s -> %s", matching_filename, dest)
100 self.log.info("Linking %s -> %s", matching_filename, dest)
97 link_or_copy(matching_filename, dest)
101 link_or_copy(matching_filename, dest)
98
102
99 # Determine where to write conversion results.
103 # Determine where to write conversion results.
100 dest = notebook_name + '.' + output_extension
104 if output_extension is not None:
105 dest = notebook_name + '.' + output_extension
106 else:
107 dest = notebook_name
101 if self.build_directory:
108 if self.build_directory:
102 dest = os.path.join(self.build_directory, dest)
109 dest = os.path.join(self.build_directory, dest)
103
110
104 # Write conversion results.
111 # Write conversion results.
105 self.log.info("Writing %i bytes to %s", len(output), dest)
112 self.log.info("Writing %i bytes to %s", len(output), dest)
106 with io.open(dest, 'w', encoding='utf-8') as f:
113 with io.open(dest, 'w', encoding='utf-8') as f:
107 f.write(output)
114 f.write(output)
108 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