##// END OF EJS Templates
add PDFExporter...
MinRK -
Show More
@@ -0,0 +1,141 b''
1 """Export to PDF via latex"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 import subprocess
7 import os
8 import sys
9
10 from IPython.utils.traitlets import Integer, List, Bool, Instance
11 from IPython.utils.tempdir import TemporaryWorkingDirectory
12 from .latex import LatexExporter
13
14
15 class PDFExporter(LatexExporter):
16 """Writer designed to write to PDF files"""
17
18 latex_count = Integer(3, config=True,
19 help="How many times latex will be called."
20 )
21
22 latex_command = List([u"pdflatex", u"{filename}"], config=True,
23 help="Shell command used to compile latex."
24 )
25
26 bib_command = List([u"bibtex", u"{filename}"], config=True,
27 help="Shell command used to run bibtex."
28 )
29
30 verbose = Bool(False, config=True,
31 help="Whether to display the output of latex commands."
32 )
33
34 temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'], config=True,
35 help="File extensions of temp files to remove after running."
36 )
37
38 writer = Instance("IPython.nbconvert.writers.FilesWriter", args=())
39
40 def run_command(self, command_list, filename, count, log_function):
41 """Run command_list count times.
42
43 Parameters
44 ----------
45 command_list : list
46 A list of args to provide to Popen. Each element of this
47 list will be interpolated with the filename to convert.
48 filename : unicode
49 The name of the file to convert.
50 count : int
51 How many times to run the command.
52
53 Returns
54 -------
55 success : bool
56 A boolean indicating if the command was successful (True)
57 or failed (False).
58 """
59 command = [c.format(filename=filename) for c in command_list]
60 #In windows and python 2.x there is a bug in subprocess.Popen and
61 # unicode commands are not supported
62 if sys.platform == 'win32' and sys.version_info < (3,0):
63 #We must use cp1252 encoding for calling subprocess.Popen
64 #Note that sys.stdin.encoding and encoding.DEFAULT_ENCODING
65 # could be different (cp437 in case of dos console)
66 command = [c.encode('cp1252') for c in command]
67 times = 'time' if count == 1 else 'times'
68 self.log.info("Running %s %i %s: %s", command_list[0], count, times, command)
69 with open(os.devnull, 'rb') as null:
70 stdout = subprocess.PIPE if not self.verbose else None
71 for index in range(count):
72 p = subprocess.Popen(command, stdout=stdout, stdin=null)
73 out, err = p.communicate()
74 if p.returncode:
75 if self.verbose:
76 # verbose means I didn't capture stdout with PIPE,
77 # so it's already been displayed and `out` is None.
78 out = u''
79 else:
80 out = out.decode('utf-8', 'replace')
81 log_function(command, out)
82 return False # failure
83 return True # success
84
85 def run_latex(self, filename):
86 """Run pdflatex self.latex_count times."""
87
88 def log_error(command, out):
89 self.log.critical(u"%s failed: %s\n%s", command[0], command, out)
90
91 return self.run_command(self.latex_command, filename,
92 self.latex_count, log_error)
93
94 def run_bib(self, filename):
95 """Run bibtex self.latex_count times."""
96 filename = os.path.splitext(filename)[0]
97
98 def log_error(command, out):
99 self.log.warn('%s had problems, most likely because there were no citations',
100 command[0])
101 self.log.debug(u"%s output: %s\n%s", command[0], command, out)
102
103 return self.run_command(self.bib_command, filename, 1, log_error)
104
105 def clean_temp_files(self, filename):
106 """Remove temporary files created by pdflatex/bibtex."""
107 self.log.info("Removing temporary LaTeX files")
108 filename = os.path.splitext(filename)[0]
109 for ext in self.temp_file_exts:
110 try:
111 os.remove(filename+ext)
112 except OSError:
113 pass
114
115 def from_notebook_node(self, nb, resources=None, **kw):
116 latex, resources = super(PDFExporter, self).from_notebook_node(
117 nb, resources=resources, **kw
118 )
119 with TemporaryWorkingDirectory() as td:
120 notebook_name = "notebook"
121 tex_file = self.writer.write(latex, resources, notebook_name=notebook_name)
122 self.log.info("Building PDF")
123 rc = self.run_latex(tex_file)
124 if not rc:
125 rc = self.run_bib(tex_file)
126 if not rc:
127 rc = self.run_latex(tex_file)
128
129 pdf_file = notebook_name + '.pdf'
130 if not os.path.isfile(pdf_file):
131 raise RuntimeError("PDF creating failed")
132 self.log.info('PDF successfully created')
133 with open(pdf_file, 'rb') as f:
134 pdf_data = f.read()
135
136 # convert output extension to pdf
137 # the writer above required it to be tex
138 resources['output_extension'] = 'pdf'
139
140 return pdf_data, resources
141
@@ -1,9 +1,10 b''
1 from .export import *
1 from .export import *
2 from .html import HTMLExporter
2 from .html import HTMLExporter
3 from .slides import SlidesExporter
3 from .slides import SlidesExporter
4 from .templateexporter import TemplateExporter
4 from .templateexporter import TemplateExporter
5 from .latex import LatexExporter
5 from .latex import LatexExporter
6 from .markdown import MarkdownExporter
6 from .markdown import MarkdownExporter
7 from .pdf import PDFExporter
7 from .python import PythonExporter
8 from .python import PythonExporter
8 from .rst import RSTExporter
9 from .rst import RSTExporter
9 from .exporter import Exporter
10 from .exporter import Exporter
@@ -1,179 +1,172 b''
1 """
1 """Module containing single call export functions."""
2 Module containing single call export functions.
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
2
12 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
13 # Imports
4 # Distributed under the terms of the Modified BSD License.
14 #-----------------------------------------------------------------------------
15
5
16 from functools import wraps
6 from functools import wraps
17
7
18 from IPython.nbformat.v3.nbbase import NotebookNode
8 from IPython.nbformat.v3.nbbase import NotebookNode
19 from IPython.utils.decorators import undoc
9 from IPython.utils.decorators import undoc
20 from IPython.utils.py3compat import string_types
10 from IPython.utils.py3compat import string_types
21
11
22 from .exporter import Exporter
12 from .exporter import Exporter
23 from .templateexporter import TemplateExporter
13 from .templateexporter import TemplateExporter
24 from .html import HTMLExporter
14 from .html import HTMLExporter
25 from .slides import SlidesExporter
15 from .slides import SlidesExporter
26 from .latex import LatexExporter
16 from .latex import LatexExporter
17 from .pdf import PDFExporter
27 from .markdown import MarkdownExporter
18 from .markdown import MarkdownExporter
28 from .python import PythonExporter
19 from .python import PythonExporter
29 from .rst import RSTExporter
20 from .rst import RSTExporter
30
21
31 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
32 # Classes
23 # Classes
33 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
34
25
35 @undoc
26 @undoc
36 def DocDecorator(f):
27 def DocDecorator(f):
37
28
38 #Set docstring of function
29 #Set docstring of function
39 f.__doc__ = f.__doc__ + """
30 f.__doc__ = f.__doc__ + """
40 nb : :class:`~{nbnode_mod}.NotebookNode`
31 nb : :class:`~{nbnode_mod}.NotebookNode`
41 The notebook to export.
32 The notebook to export.
42 config : config (optional, keyword arg)
33 config : config (optional, keyword arg)
43 User configuration instance.
34 User configuration instance.
44 resources : dict (optional, keyword arg)
35 resources : dict (optional, keyword arg)
45 Resources used in the conversion process.
36 Resources used in the conversion process.
46
37
47 Returns
38 Returns
48 -------
39 -------
49 tuple- output, resources, exporter_instance
40 tuple- output, resources, exporter_instance
50 output : str
41 output : str
51 Jinja 2 output. This is the resulting converted notebook.
42 Jinja 2 output. This is the resulting converted notebook.
52 resources : dictionary
43 resources : dictionary
53 Dictionary of resources used prior to and during the conversion
44 Dictionary of resources used prior to and during the conversion
54 process.
45 process.
55 exporter_instance : Exporter
46 exporter_instance : Exporter
56 Instance of the Exporter class used to export the document. Useful
47 Instance of the Exporter class used to export the document. Useful
57 to caller because it provides a 'file_extension' property which
48 to caller because it provides a 'file_extension' property which
58 specifies what extension the output should be saved as.
49 specifies what extension the output should be saved as.
59
50
60 Notes
51 Notes
61 -----
52 -----
62 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
53 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
63 """.format(nbnode_mod=NotebookNode.__module__)
54 """.format(nbnode_mod=NotebookNode.__module__)
64
55
65 @wraps(f)
56 @wraps(f)
66 def decorator(*args, **kwargs):
57 def decorator(*args, **kwargs):
67 return f(*args, **kwargs)
58 return f(*args, **kwargs)
68
59
69 return decorator
60 return decorator
70
61
71
62
72 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
73 # Functions
64 # Functions
74 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
75
66
76 __all__ = [
67 __all__ = [
77 'export',
68 'export',
78 'export_html',
69 'export_html',
79 'export_custom',
70 'export_custom',
80 'export_slides',
71 'export_slides',
81 'export_latex',
72 'export_latex',
73 'export_pdf',
82 'export_markdown',
74 'export_markdown',
83 'export_python',
75 'export_python',
84 'export_rst',
76 'export_rst',
85 'export_by_name',
77 'export_by_name',
86 'get_export_names',
78 'get_export_names',
87 'ExporterNameError'
79 'ExporterNameError'
88 ]
80 ]
89
81
90
82
91 class ExporterNameError(NameError):
83 class ExporterNameError(NameError):
92 pass
84 pass
93
85
94 @DocDecorator
86 @DocDecorator
95 def export(exporter, nb, **kw):
87 def export(exporter, nb, **kw):
96 """
88 """
97 Export a notebook object using specific exporter class.
89 Export a notebook object using specific exporter class.
98
90
99 Parameters
91 Parameters
100 ----------
92 ----------
101 exporter : class:`~IPython.nbconvert.exporters.exporter.Exporter` class or instance
93 exporter : class:`~IPython.nbconvert.exporters.exporter.Exporter` class or instance
102 Class type or instance of the exporter that should be used. If the
94 Class type or instance of the exporter that should be used. If the
103 method initializes it's own instance of the class, it is ASSUMED that
95 method initializes it's own instance of the class, it is ASSUMED that
104 the class type provided exposes a constructor (``__init__``) with the same
96 the class type provided exposes a constructor (``__init__``) with the same
105 signature as the base Exporter class.
97 signature as the base Exporter class.
106 """
98 """
107
99
108 #Check arguments
100 #Check arguments
109 if exporter is None:
101 if exporter is None:
110 raise TypeError("Exporter is None")
102 raise TypeError("Exporter is None")
111 elif not isinstance(exporter, Exporter) and not issubclass(exporter, Exporter):
103 elif not isinstance(exporter, Exporter) and not issubclass(exporter, Exporter):
112 raise TypeError("exporter does not inherit from Exporter (base)")
104 raise TypeError("exporter does not inherit from Exporter (base)")
113 if nb is None:
105 if nb is None:
114 raise TypeError("nb is None")
106 raise TypeError("nb is None")
115
107
116 #Create the exporter
108 #Create the exporter
117 resources = kw.pop('resources', None)
109 resources = kw.pop('resources', None)
118 if isinstance(exporter, Exporter):
110 if isinstance(exporter, Exporter):
119 exporter_instance = exporter
111 exporter_instance = exporter
120 else:
112 else:
121 exporter_instance = exporter(**kw)
113 exporter_instance = exporter(**kw)
122
114
123 #Try to convert the notebook using the appropriate conversion function.
115 #Try to convert the notebook using the appropriate conversion function.
124 if isinstance(nb, NotebookNode):
116 if isinstance(nb, NotebookNode):
125 output, resources = exporter_instance.from_notebook_node(nb, resources)
117 output, resources = exporter_instance.from_notebook_node(nb, resources)
126 elif isinstance(nb, string_types):
118 elif isinstance(nb, string_types):
127 output, resources = exporter_instance.from_filename(nb, resources)
119 output, resources = exporter_instance.from_filename(nb, resources)
128 else:
120 else:
129 output, resources = exporter_instance.from_file(nb, resources)
121 output, resources = exporter_instance.from_file(nb, resources)
130 return output, resources
122 return output, resources
131
123
132 exporter_map = dict(
124 exporter_map = dict(
133 custom=TemplateExporter,
125 custom=TemplateExporter,
134 html=HTMLExporter,
126 html=HTMLExporter,
135 slides=SlidesExporter,
127 slides=SlidesExporter,
136 latex=LatexExporter,
128 latex=LatexExporter,
129 pdf=PDFExporter,
137 markdown=MarkdownExporter,
130 markdown=MarkdownExporter,
138 python=PythonExporter,
131 python=PythonExporter,
139 rst=RSTExporter,
132 rst=RSTExporter,
140 )
133 )
141
134
142 def _make_exporter(name, E):
135 def _make_exporter(name, E):
143 """make an export_foo function from a short key and Exporter class E"""
136 """make an export_foo function from a short key and Exporter class E"""
144 def _export(nb, **kw):
137 def _export(nb, **kw):
145 return export(E, nb, **kw)
138 return export(E, nb, **kw)
146 _export.__doc__ = """Export a notebook object to {0} format""".format(name)
139 _export.__doc__ = """Export a notebook object to {0} format""".format(name)
147 return _export
140 return _export
148
141
149 g = globals()
142 g = globals()
150
143
151 for name, E in exporter_map.items():
144 for name, E in exporter_map.items():
152 g['export_%s' % name] = DocDecorator(_make_exporter(name, E))
145 g['export_%s' % name] = DocDecorator(_make_exporter(name, E))
153
146
154 @DocDecorator
147 @DocDecorator
155 def export_by_name(format_name, nb, **kw):
148 def export_by_name(format_name, nb, **kw):
156 """
149 """
157 Export a notebook object to a template type by its name. Reflection
150 Export a notebook object to a template type by its name. Reflection
158 (Inspect) is used to find the template's corresponding explicit export
151 (Inspect) is used to find the template's corresponding explicit export
159 method defined in this module. That method is then called directly.
152 method defined in this module. That method is then called directly.
160
153
161 Parameters
154 Parameters
162 ----------
155 ----------
163 format_name : str
156 format_name : str
164 Name of the template style to export to.
157 Name of the template style to export to.
165 """
158 """
166
159
167 function_name = "export_" + format_name.lower()
160 function_name = "export_" + format_name.lower()
168
161
169 if function_name in globals():
162 if function_name in globals():
170 return globals()[function_name](nb, **kw)
163 return globals()[function_name](nb, **kw)
171 else:
164 else:
172 raise ExporterNameError("template for `%s` not found" % function_name)
165 raise ExporterNameError("template for `%s` not found" % function_name)
173
166
174
167
175 def get_export_names():
168 def get_export_names():
176 """Return a list of the currently supported export targets
169 """Return a list of the currently supported export targets
177
170
178 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT"""
171 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT"""
179 return sorted(exporter_map.keys())
172 return sorted(exporter_map.keys())
@@ -1,323 +1,313 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """NBConvert is a utility for conversion of .ipynb files.
2 """NbConvert is a utility for conversion of .ipynb files.
3
3
4 Command-line interface for the NbConvert conversion utility.
4 Command-line interface for the NbConvert conversion utility.
5 """
5 """
6 #-----------------------------------------------------------------------------
7 #Copyright (c) 2013, the IPython Development Team.
8 #
9 #Distributed under the terms of the Modified BSD License.
10 #
11 #The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13
6
14 #-----------------------------------------------------------------------------
7 # Copyright (c) IPython Development Team.
15 #Imports
8 # Distributed under the terms of the Modified BSD License.
16 #-----------------------------------------------------------------------------
17
9
18 # Stdlib imports
19 from __future__ import print_function
10 from __future__ import print_function
20
11
21 import logging
12 import logging
22 import sys
13 import sys
23 import os
14 import os
24 import glob
15 import glob
25
16
26 # From IPython
27 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
17 from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags
28 from IPython.core.profiledir import ProfileDir
18 from IPython.core.profiledir import ProfileDir
29 from IPython.config import catch_config_error, Configurable
19 from IPython.config import catch_config_error, Configurable
30 from IPython.utils.traitlets import (
20 from IPython.utils.traitlets import (
31 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
21 Unicode, List, Instance, DottedObjectName, Type, CaselessStrEnum,
32 )
22 )
33 from IPython.utils.importstring import import_item
23 from IPython.utils.importstring import import_item
34 from IPython.utils.text import dedent
24 from IPython.utils.text import dedent
35
25
36 from .exporters.export import get_export_names, exporter_map
26 from .exporters.export import get_export_names, exporter_map
37 from IPython.nbconvert import exporters, preprocessors, writers, postprocessors
27 from IPython.nbconvert import exporters, preprocessors, writers, postprocessors
38 from .utils.base import NbConvertBase
28 from .utils.base import NbConvertBase
39 from .utils.exceptions import ConversionException
29 from .utils.exceptions import ConversionException
40
30
41 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
42 #Classes and functions
32 #Classes and functions
43 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
44
34
45 class DottedOrNone(DottedObjectName):
35 class DottedOrNone(DottedObjectName):
46 """
36 """
47 A string holding a valid dotted object name in Python, such as A.b3._c
37 A string holding a valid dotted object name in Python, such as A.b3._c
48 Also allows for None type."""
38 Also allows for None type."""
49
39
50 default_value = u''
40 default_value = u''
51
41
52 def validate(self, obj, value):
42 def validate(self, obj, value):
53 if value is not None and len(value) > 0:
43 if value is not None and len(value) > 0:
54 return super(DottedOrNone, self).validate(obj, value)
44 return super(DottedOrNone, self).validate(obj, value)
55 else:
45 else:
56 return value
46 return value
57
47
58 nbconvert_aliases = {}
48 nbconvert_aliases = {}
59 nbconvert_aliases.update(base_aliases)
49 nbconvert_aliases.update(base_aliases)
60 nbconvert_aliases.update({
50 nbconvert_aliases.update({
61 'to' : 'NbConvertApp.export_format',
51 'to' : 'NbConvertApp.export_format',
62 'template' : 'TemplateExporter.template_file',
52 'template' : 'TemplateExporter.template_file',
63 'writer' : 'NbConvertApp.writer_class',
53 'writer' : 'NbConvertApp.writer_class',
64 'post': 'NbConvertApp.postprocessor_class',
54 'post': 'NbConvertApp.postprocessor_class',
65 'output': 'NbConvertApp.output_base',
55 'output': 'NbConvertApp.output_base',
66 'reveal-prefix': 'RevealHelpPreprocessor.url_prefix',
56 'reveal-prefix': 'RevealHelpPreprocessor.url_prefix',
67 })
57 })
68
58
69 nbconvert_flags = {}
59 nbconvert_flags = {}
70 nbconvert_flags.update(base_flags)
60 nbconvert_flags.update(base_flags)
71 nbconvert_flags.update({
61 nbconvert_flags.update({
72 'stdout' : (
62 'stdout' : (
73 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
63 {'NbConvertApp' : {'writer_class' : "StdoutWriter"}},
74 "Write notebook output to stdout instead of files."
64 "Write notebook output to stdout instead of files."
75 )
65 )
76 })
66 })
77
67
78
68
79 class NbConvertApp(BaseIPythonApplication):
69 class NbConvertApp(BaseIPythonApplication):
80 """Application used to convert from notebook file type (``*.ipynb``)"""
70 """Application used to convert from notebook file type (``*.ipynb``)"""
81
71
82 name = 'ipython-nbconvert'
72 name = 'ipython-nbconvert'
83 aliases = nbconvert_aliases
73 aliases = nbconvert_aliases
84 flags = nbconvert_flags
74 flags = nbconvert_flags
85
75
86 def _log_level_default(self):
76 def _log_level_default(self):
87 return logging.INFO
77 return logging.INFO
88
78
89 def _classes_default(self):
79 def _classes_default(self):
90 classes = [NbConvertBase, ProfileDir]
80 classes = [NbConvertBase, ProfileDir]
91 for pkg in (exporters, preprocessors, writers, postprocessors):
81 for pkg in (exporters, preprocessors, writers, postprocessors):
92 for name in dir(pkg):
82 for name in dir(pkg):
93 cls = getattr(pkg, name)
83 cls = getattr(pkg, name)
94 if isinstance(cls, type) and issubclass(cls, Configurable):
84 if isinstance(cls, type) and issubclass(cls, Configurable):
95 classes.append(cls)
85 classes.append(cls)
96
86
97 return classes
87 return classes
98
88
99 description = Unicode(
89 description = Unicode(
100 u"""This application is used to convert notebook files (*.ipynb)
90 u"""This application is used to convert notebook files (*.ipynb)
101 to various other formats.
91 to various other formats.
102
92
103 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
93 WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""")
104
94
105 output_base = Unicode('', config=True, help='''overwrite base name use for output files.
95 output_base = Unicode('', config=True, help='''overwrite base name use for output files.
106 can only be use when converting one notebook at a time.
96 can only be use when converting one notebook at a time.
107 ''')
97 ''')
108
98
109 examples = Unicode(u"""
99 examples = Unicode(u"""
110 The simplest way to use nbconvert is
100 The simplest way to use nbconvert is
111
101
112 > ipython nbconvert mynotebook.ipynb
102 > ipython nbconvert mynotebook.ipynb
113
103
114 which will convert mynotebook.ipynb to the default format (probably HTML).
104 which will convert mynotebook.ipynb to the default format (probably HTML).
115
105
116 You can specify the export format with `--to`.
106 You can specify the export format with `--to`.
117 Options include {0}
107 Options include {0}
118
108
119 > ipython nbconvert --to latex mynotebook.ipnynb
109 > ipython nbconvert --to latex mynotebook.ipnynb
120
110
121 Both HTML and LaTeX support multiple output templates. LaTeX includes
111 Both HTML and LaTeX support multiple output templates. LaTeX includes
122 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You
112 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You
123 can specify the flavor of the format used.
113 can specify the flavor of the format used.
124
114
125 > ipython nbconvert --to html --template basic mynotebook.ipynb
115 > ipython nbconvert --to html --template basic mynotebook.ipynb
126
116
127 You can also pipe the output to stdout, rather than a file
117 You can also pipe the output to stdout, rather than a file
128
118
129 > ipython nbconvert mynotebook.ipynb --stdout
119 > ipython nbconvert mynotebook.ipynb --stdout
130
120
131 A post-processor can be used to compile a PDF
121 PDF is generated via latex
132
122
133 > ipython nbconvert mynotebook.ipynb --to latex --post PDF
123 > ipython nbconvert mynotebook.ipynb --to pdf
134
124
135 You can get (and serve) a Reveal.js-powered slideshow
125 You can get (and serve) a Reveal.js-powered slideshow
136
126
137 > ipython nbconvert myslides.ipynb --to slides --post serve
127 > ipython nbconvert myslides.ipynb --to slides --post serve
138
128
139 Multiple notebooks can be given at the command line in a couple of
129 Multiple notebooks can be given at the command line in a couple of
140 different ways:
130 different ways:
141
131
142 > ipython nbconvert notebook*.ipynb
132 > ipython nbconvert notebook*.ipynb
143 > ipython nbconvert notebook1.ipynb notebook2.ipynb
133 > ipython nbconvert notebook1.ipynb notebook2.ipynb
144
134
145 or you can specify the notebooks list in a config file, containing::
135 or you can specify the notebooks list in a config file, containing::
146
136
147 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
137 c.NbConvertApp.notebooks = ["my_notebook.ipynb"]
148
138
149 > ipython nbconvert --config mycfg.py
139 > ipython nbconvert --config mycfg.py
150 """.format(get_export_names()))
140 """.format(get_export_names()))
151
141
152 # Writer specific variables
142 # Writer specific variables
153 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
143 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
154 help="""Instance of the writer class used to write the
144 help="""Instance of the writer class used to write the
155 results of the conversion.""")
145 results of the conversion.""")
156 writer_class = DottedObjectName('FilesWriter', config=True,
146 writer_class = DottedObjectName('FilesWriter', config=True,
157 help="""Writer class used to write the
147 help="""Writer class used to write the
158 results of the conversion""")
148 results of the conversion""")
159 writer_aliases = {'fileswriter': 'IPython.nbconvert.writers.files.FilesWriter',
149 writer_aliases = {'fileswriter': 'IPython.nbconvert.writers.files.FilesWriter',
160 'debugwriter': 'IPython.nbconvert.writers.debug.DebugWriter',
150 'debugwriter': 'IPython.nbconvert.writers.debug.DebugWriter',
161 'stdoutwriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
151 'stdoutwriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
162 writer_factory = Type()
152 writer_factory = Type()
163
153
164 def _writer_class_changed(self, name, old, new):
154 def _writer_class_changed(self, name, old, new):
165 if new.lower() in self.writer_aliases:
155 if new.lower() in self.writer_aliases:
166 new = self.writer_aliases[new.lower()]
156 new = self.writer_aliases[new.lower()]
167 self.writer_factory = import_item(new)
157 self.writer_factory = import_item(new)
168
158
169 # Post-processor specific variables
159 # Post-processor specific variables
170 postprocessor = Instance('IPython.nbconvert.postprocessors.base.PostProcessorBase',
160 postprocessor = Instance('IPython.nbconvert.postprocessors.base.PostProcessorBase',
171 help="""Instance of the PostProcessor class used to write the
161 help="""Instance of the PostProcessor class used to write the
172 results of the conversion.""")
162 results of the conversion.""")
173
163
174 postprocessor_class = DottedOrNone(config=True,
164 postprocessor_class = DottedOrNone(config=True,
175 help="""PostProcessor class used to write the
165 help="""PostProcessor class used to write the
176 results of the conversion""")
166 results of the conversion""")
177 postprocessor_aliases = {'pdf': 'IPython.nbconvert.postprocessors.pdf.PDFPostProcessor',
167 postprocessor_aliases = {'pdf': 'IPython.nbconvert.postprocessors.pdf.PDFPostProcessor',
178 'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'}
168 'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'}
179 postprocessor_factory = Type()
169 postprocessor_factory = Type()
180
170
181 def _postprocessor_class_changed(self, name, old, new):
171 def _postprocessor_class_changed(self, name, old, new):
182 if new.lower() in self.postprocessor_aliases:
172 if new.lower() in self.postprocessor_aliases:
183 new = self.postprocessor_aliases[new.lower()]
173 new = self.postprocessor_aliases[new.lower()]
184 if new:
174 if new:
185 self.postprocessor_factory = import_item(new)
175 self.postprocessor_factory = import_item(new)
186
176
187
177
188 # Other configurable variables
178 # Other configurable variables
189 export_format = CaselessStrEnum(get_export_names(),
179 export_format = CaselessStrEnum(get_export_names(),
190 default_value="html",
180 default_value="html",
191 config=True,
181 config=True,
192 help="""The export format to be used."""
182 help="""The export format to be used."""
193 )
183 )
194
184
195 notebooks = List([], config=True, help="""List of notebooks to convert.
185 notebooks = List([], config=True, help="""List of notebooks to convert.
196 Wildcards are supported.
186 Wildcards are supported.
197 Filenames passed positionally will be added to the list.
187 Filenames passed positionally will be added to the list.
198 """)
188 """)
199
189
200 @catch_config_error
190 @catch_config_error
201 def initialize(self, argv=None):
191 def initialize(self, argv=None):
202 super(NbConvertApp, self).initialize(argv)
192 super(NbConvertApp, self).initialize(argv)
203 self.init_syspath()
193 self.init_syspath()
204 self.init_notebooks()
194 self.init_notebooks()
205 self.init_writer()
195 self.init_writer()
206 self.init_postprocessor()
196 self.init_postprocessor()
207
197
208
198
209
199
210 def init_syspath(self):
200 def init_syspath(self):
211 """
201 """
212 Add the cwd to the sys.path ($PYTHONPATH)
202 Add the cwd to the sys.path ($PYTHONPATH)
213 """
203 """
214 sys.path.insert(0, os.getcwd())
204 sys.path.insert(0, os.getcwd())
215
205
216
206
217 def init_notebooks(self):
207 def init_notebooks(self):
218 """Construct the list of notebooks.
208 """Construct the list of notebooks.
219 If notebooks are passed on the command-line,
209 If notebooks are passed on the command-line,
220 they override notebooks specified in config files.
210 they override notebooks specified in config files.
221 Glob each notebook to replace notebook patterns with filenames.
211 Glob each notebook to replace notebook patterns with filenames.
222 """
212 """
223
213
224 # Specifying notebooks on the command-line overrides (rather than adds)
214 # Specifying notebooks on the command-line overrides (rather than adds)
225 # the notebook list
215 # the notebook list
226 if self.extra_args:
216 if self.extra_args:
227 patterns = self.extra_args
217 patterns = self.extra_args
228 else:
218 else:
229 patterns = self.notebooks
219 patterns = self.notebooks
230
220
231 # Use glob to replace all the notebook patterns with filenames.
221 # Use glob to replace all the notebook patterns with filenames.
232 filenames = []
222 filenames = []
233 for pattern in patterns:
223 for pattern in patterns:
234
224
235 # Use glob to find matching filenames. Allow the user to convert
225 # Use glob to find matching filenames. Allow the user to convert
236 # notebooks without having to type the extension.
226 # notebooks without having to type the extension.
237 globbed_files = glob.glob(pattern)
227 globbed_files = glob.glob(pattern)
238 globbed_files.extend(glob.glob(pattern + '.ipynb'))
228 globbed_files.extend(glob.glob(pattern + '.ipynb'))
239 if not globbed_files:
229 if not globbed_files:
240 self.log.warn("pattern %r matched no files", pattern)
230 self.log.warn("pattern %r matched no files", pattern)
241
231
242 for filename in globbed_files:
232 for filename in globbed_files:
243 if not filename in filenames:
233 if not filename in filenames:
244 filenames.append(filename)
234 filenames.append(filename)
245 self.notebooks = filenames
235 self.notebooks = filenames
246
236
247 def init_writer(self):
237 def init_writer(self):
248 """
238 """
249 Initialize the writer (which is stateless)
239 Initialize the writer (which is stateless)
250 """
240 """
251 self._writer_class_changed(None, self.writer_class, self.writer_class)
241 self._writer_class_changed(None, self.writer_class, self.writer_class)
252 self.writer = self.writer_factory(parent=self)
242 self.writer = self.writer_factory(parent=self)
253
243
254 def init_postprocessor(self):
244 def init_postprocessor(self):
255 """
245 """
256 Initialize the postprocessor (which is stateless)
246 Initialize the postprocessor (which is stateless)
257 """
247 """
258 self._postprocessor_class_changed(None, self.postprocessor_class,
248 self._postprocessor_class_changed(None, self.postprocessor_class,
259 self.postprocessor_class)
249 self.postprocessor_class)
260 if self.postprocessor_factory:
250 if self.postprocessor_factory:
261 self.postprocessor = self.postprocessor_factory(parent=self)
251 self.postprocessor = self.postprocessor_factory(parent=self)
262
252
263 def start(self):
253 def start(self):
264 """
254 """
265 Ran after initialization completed
255 Ran after initialization completed
266 """
256 """
267 super(NbConvertApp, self).start()
257 super(NbConvertApp, self).start()
268 self.convert_notebooks()
258 self.convert_notebooks()
269
259
270 def convert_notebooks(self):
260 def convert_notebooks(self):
271 """
261 """
272 Convert the notebooks in the self.notebook traitlet
262 Convert the notebooks in the self.notebook traitlet
273 """
263 """
274 # Export each notebook
264 # Export each notebook
275 conversion_success = 0
265 conversion_success = 0
276
266
277 if self.output_base != '' and len(self.notebooks) > 1:
267 if self.output_base != '' and len(self.notebooks) > 1:
278 self.log.error(
268 self.log.error(
279 """UsageError: --output flag or `NbConvertApp.output_base` config option
269 """UsageError: --output flag or `NbConvertApp.output_base` config option
280 cannot be used when converting multiple notebooks.
270 cannot be used when converting multiple notebooks.
281 """)
271 """)
282 self.exit(1)
272 self.exit(1)
283
273
284 exporter = exporter_map[self.export_format](config=self.config)
274 exporter = exporter_map[self.export_format](config=self.config)
285
275
286 for notebook_filename in self.notebooks:
276 for notebook_filename in self.notebooks:
287 self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format)
277 self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format)
288
278
289 # Get a unique key for the notebook and set it in the resources object.
279 # Get a unique key for the notebook and set it in the resources object.
290 basename = os.path.basename(notebook_filename)
280 basename = os.path.basename(notebook_filename)
291 notebook_name = basename[:basename.rfind('.')]
281 notebook_name = basename[:basename.rfind('.')]
292 if self.output_base:
282 if self.output_base:
293 notebook_name = self.output_base
283 notebook_name = self.output_base
294 resources = {}
284 resources = {}
295 resources['unique_key'] = notebook_name
285 resources['unique_key'] = notebook_name
296 resources['output_files_dir'] = '%s_files' % notebook_name
286 resources['output_files_dir'] = '%s_files' % notebook_name
297 self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], ''))
287 self.log.info("Support files will be in %s", os.path.join(resources['output_files_dir'], ''))
298
288
299 # Try to export
289 # Try to export
300 try:
290 try:
301 output, resources = exporter.from_filename(notebook_filename, resources=resources)
291 output, resources = exporter.from_filename(notebook_filename, resources=resources)
302 except ConversionException as e:
292 except ConversionException as e:
303 self.log.error("Error while converting '%s'", notebook_filename,
293 self.log.error("Error while converting '%s'", notebook_filename,
304 exc_info=True)
294 exc_info=True)
305 self.exit(1)
295 self.exit(1)
306 else:
296 else:
307 write_resultes = self.writer.write(output, resources, notebook_name=notebook_name)
297 write_resultes = self.writer.write(output, resources, notebook_name=notebook_name)
308
298
309 #Post-process if post processor has been defined.
299 #Post-process if post processor has been defined.
310 if hasattr(self, 'postprocessor') and self.postprocessor:
300 if hasattr(self, 'postprocessor') and self.postprocessor:
311 self.postprocessor(write_resultes)
301 self.postprocessor(write_resultes)
312 conversion_success += 1
302 conversion_success += 1
313
303
314 # If nothing was converted successfully, help the user.
304 # If nothing was converted successfully, help the user.
315 if conversion_success == 0:
305 if conversion_success == 0:
316 self.print_help()
306 self.print_help()
317 sys.exit(-1)
307 sys.exit(-1)
318
308
319 #-----------------------------------------------------------------------------
309 #-----------------------------------------------------------------------------
320 # Main entry point
310 # Main entry point
321 #-----------------------------------------------------------------------------
311 #-----------------------------------------------------------------------------
322
312
323 launch_new_instance = NbConvertApp.launch_instance
313 launch_new_instance = NbConvertApp.launch_instance
General Comments 0
You need to be logged in to leave comments. Login now