Show More
@@ -0,0 +1,36 b'' | |||
|
1 | """Tests for PDF export""" | |
|
2 | ||
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
5 | ||
|
6 | import logging | |
|
7 | import os | |
|
8 | ||
|
9 | from IPython.testing import decorators as dec | |
|
10 | ||
|
11 | from .base import ExportersTestsBase | |
|
12 | from ..pdf import PDFExporter | |
|
13 | ||
|
14 | ||
|
15 | #----------------------------------------------------------------------------- | |
|
16 | # Class | |
|
17 | #----------------------------------------------------------------------------- | |
|
18 | ||
|
19 | class TestPDF(ExportersTestsBase): | |
|
20 | """Test PDF export""" | |
|
21 | ||
|
22 | exporter_class = PDFExporter | |
|
23 | ||
|
24 | def test_constructor(self): | |
|
25 | """Can a PDFExporter be constructed?""" | |
|
26 | self.exporter_class() | |
|
27 | ||
|
28 | ||
|
29 | @dec.onlyif_cmds_exist('pdflatex') | |
|
30 | @dec.onlyif_cmds_exist('pandoc') | |
|
31 | def test_export(self): | |
|
32 | """Smoke test PDFExporter""" | |
|
33 | (output, resources) = self.exporter_class(latex_count=1).from_filename(self._get_notebook()) | |
|
34 | self.assertIsInstance(output, bytes) | |
|
35 | assert len(output) > 0 | |
|
36 |
@@ -0,0 +1,2 b'' | |||
|
1 | Creating PDFs with LaTeX no longer uses a post processor. | |
|
2 | Use `nbconvert --to pdf` instead of `nbconvert --to latex --post pdf`. |
@@ -73,7 +73,7 b' class NbconvertFileHandler(IPythonHandler):' | |||
|
73 | 73 | @web.authenticated |
|
74 | 74 | def get(self, format, path='', name=None): |
|
75 | 75 | |
|
76 | exporter = get_exporter(format, config=self.config) | |
|
76 | exporter = get_exporter(format, config=self.config, log=self.log) | |
|
77 | 77 | |
|
78 | 78 | path = path.strip('/') |
|
79 | 79 | model = self.notebook_manager.get_notebook(name=name, path=path) |
@@ -1,9 +1,5 b'' | |||
|
1 | //---------------------------------------------------------------------------- | |
|
2 | // Copyright (C) 2008-2011 The IPython Development Team | |
|
3 | // | |
|
4 | // Distributed under the terms of the BSD License. The full license is in | |
|
5 | // the file COPYING, distributed as part of this software. | |
|
6 | //---------------------------------------------------------------------------- | |
|
1 | // Copyright (c) IPython Development Team. | |
|
2 | // Distributed under the terms of the Modified BSD License. | |
|
7 | 3 | |
|
8 | 4 | //============================================================================ |
|
9 | 5 | // MenuBar |
@@ -125,6 +121,10 b' var IPython = (function (IPython) {' | |||
|
125 | 121 | that._nbconvert('rst', true); |
|
126 | 122 | }); |
|
127 | 123 | |
|
124 | this.element.find('#download_pdf').click(function () { | |
|
125 | that._nbconvert('pdf', true); | |
|
126 | }); | |
|
127 | ||
|
128 | 128 | this.element.find('#rename_notebook').click(function () { |
|
129 | 129 | IPython.save_widget.rename_notebook(); |
|
130 | 130 | }); |
@@ -84,6 +84,7 b' class="notebook_app"' | |||
|
84 | 84 | <li id="download_py"><a href="#">Python (.py)</a></li> |
|
85 | 85 | <li id="download_html"><a href="#">HTML (.html)</a></li> |
|
86 | 86 | <li id="download_rst"><a href="#">reST (.rst)</a></li> |
|
87 | <li id="download_pdf"><a href="#">PDF (.pdf)</a></li> | |
|
87 | 88 | </ul> |
|
88 | 89 | </li> |
|
89 | 90 | <li class="divider"></li> |
@@ -4,6 +4,7 b' from .slides import SlidesExporter' | |||
|
4 | 4 | from .templateexporter import TemplateExporter |
|
5 | 5 | from .latex import LatexExporter |
|
6 | 6 | from .markdown import MarkdownExporter |
|
7 | from .pdf import PDFExporter | |
|
7 | 8 | from .python import PythonExporter |
|
8 | 9 | from .rst import RSTExporter |
|
9 | 10 | from .exporter import Exporter |
@@ -1,17 +1,7 b'' | |||
|
1 | """ | |
|
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 | #----------------------------------------------------------------------------- | |
|
1 | """Module containing single call export functions.""" | |
|
11 | 2 | |
|
12 | #----------------------------------------------------------------------------- | |
|
13 | # Imports | |
|
14 | #----------------------------------------------------------------------------- | |
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
15 | 5 | |
|
16 | 6 | from functools import wraps |
|
17 | 7 | |
@@ -24,6 +14,7 b' from .templateexporter import TemplateExporter' | |||
|
24 | 14 | from .html import HTMLExporter |
|
25 | 15 | from .slides import SlidesExporter |
|
26 | 16 | from .latex import LatexExporter |
|
17 | from .pdf import PDFExporter | |
|
27 | 18 | from .markdown import MarkdownExporter |
|
28 | 19 | from .python import PythonExporter |
|
29 | 20 | from .rst import RSTExporter |
@@ -79,6 +70,7 b' __all__ = [' | |||
|
79 | 70 | 'export_custom', |
|
80 | 71 | 'export_slides', |
|
81 | 72 | 'export_latex', |
|
73 | 'export_pdf', | |
|
82 | 74 | 'export_markdown', |
|
83 | 75 | 'export_python', |
|
84 | 76 | 'export_rst', |
@@ -134,6 +126,7 b' exporter_map = dict(' | |||
|
134 | 126 | html=HTMLExporter, |
|
135 | 127 | slides=SlidesExporter, |
|
136 | 128 | latex=LatexExporter, |
|
129 | pdf=PDFExporter, | |
|
137 | 130 | markdown=MarkdownExporter, |
|
138 | 131 | python=PythonExporter, |
|
139 | 132 | rst=RSTExporter, |
@@ -1,53 +1,41 b'' | |||
|
1 | """ | |
|
2 | Contains writer for writing nbconvert output to PDF. | |
|
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 | ||
|
12 | #----------------------------------------------------------------------------- | |
|
13 | # Imports | |
|
14 | #----------------------------------------------------------------------------- | |
|
1 | """Export to PDF via latex""" | |
|
2 | ||
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
15 | 5 | |
|
16 | 6 | import subprocess |
|
17 | 7 | import os |
|
18 | 8 | import sys |
|
19 | 9 | |
|
20 | from IPython.utils.traitlets import Integer, List, Bool | |
|
10 | from IPython.utils.traitlets import Integer, List, Bool, Instance | |
|
11 | from IPython.utils.tempdir import TemporaryWorkingDirectory | |
|
12 | from .latex import LatexExporter | |
|
21 | 13 | |
|
22 | from .base import PostProcessorBase | |
|
23 | 14 | |
|
24 | #----------------------------------------------------------------------------- | |
|
25 | # Classes | |
|
26 | #----------------------------------------------------------------------------- | |
|
27 | class PDFPostProcessor(PostProcessorBase): | |
|
15 | class PDFExporter(LatexExporter): | |
|
28 | 16 | """Writer designed to write to PDF files""" |
|
29 | 17 | |
|
30 |
latex_count = Integer(3, config=True, |
|
|
31 |
How many times |
|
|
32 | """) | |
|
18 | latex_count = Integer(3, config=True, | |
|
19 | help="How many times latex will be called." | |
|
20 | ) | |
|
33 | 21 | |
|
34 |
latex_command = List([u"pdflatex", u"{filename}"], config=True, |
|
|
35 |
Shell command used to compile |
|
|
22 | latex_command = List([u"pdflatex", u"{filename}"], config=True, | |
|
23 | help="Shell command used to compile latex." | |
|
24 | ) | |
|
36 | 25 | |
|
37 |
bib_command = List([u"bibtex", u"{filename}"], config=True, |
|
|
38 |
Shell command used to run bibtex." |
|
|
26 | bib_command = List([u"bibtex", u"{filename}"], config=True, | |
|
27 | help="Shell command used to run bibtex." | |
|
28 | ) | |
|
39 | 29 | |
|
40 |
verbose = Bool(False, config=True, |
|
|
41 |
Whether |
|
|
42 | """) | |
|
30 | verbose = Bool(False, config=True, | |
|
31 | help="Whether to display the output of latex commands." | |
|
32 | ) | |
|
43 | 33 | |
|
44 | temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'], | |
|
45 | config=True, help=""" | |
|
46 | Filename extensions of temp files to remove after running. | |
|
47 | """) | |
|
48 | pdf_open = Bool(False, config=True, help=""" | |
|
49 | Whether or not to open the pdf after the compile call. | |
|
50 | """) | |
|
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=()) | |
|
51 | 39 | |
|
52 | 40 | def run_command(self, command_list, filename, count, log_function): |
|
53 | 41 | """Run command_list count times. |
@@ -64,7 +52,7 b' class PDFPostProcessor(PostProcessorBase):' | |||
|
64 | 52 | |
|
65 | 53 | Returns |
|
66 | 54 | ------- |
|
67 |
|
|
|
55 | success : bool | |
|
68 | 56 | A boolean indicating if the command was successful (True) |
|
69 | 57 | or failed (False). |
|
70 | 58 | """ |
@@ -124,33 +112,30 b' class PDFPostProcessor(PostProcessorBase):' | |||
|
124 | 112 | except OSError: |
|
125 | 113 | pass |
|
126 | 114 | |
|
127 | def open_pdf(self, filename): | |
|
128 | """Open the pdf in the default viewer.""" | |
|
129 | if sys.platform.startswith('darwin'): | |
|
130 | subprocess.call(('open', filename)) | |
|
131 | elif os.name == 'nt': | |
|
132 | os.startfile(filename) | |
|
133 | elif os.name == 'posix': | |
|
134 | subprocess.call(('xdg-open', filename)) | |
|
135 | return | |
|
136 | ||
|
137 | def postprocess(self, filename): | |
|
138 | """Build a PDF by running pdflatex and bibtex""" | |
|
139 | self.log.info("Building PDF") | |
|
140 | cont = self.run_latex(filename) | |
|
141 | if cont: | |
|
142 | cont = self.run_bib(filename) | |
|
143 | else: | |
|
144 | self.clean_temp_files(filename) | |
|
145 | return | |
|
146 | if cont: | |
|
147 | cont = self.run_latex(filename) | |
|
148 | self.clean_temp_files(filename) | |
|
149 | filename = os.path.splitext(filename)[0] | |
|
150 | if os.path.isfile(filename+'.pdf'): | |
|
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") | |
|
151 | 132 | self.log.info('PDF successfully created') |
|
152 | if self.pdf_open: | |
|
153 | self.log.info('Viewer called') | |
|
154 | self.open_pdf(filename+'.pdf') | |
|
155 | return | |
|
156 | ||
|
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,21 +1,12 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 |
"""N |
|
|
2 | """NbConvert is a utility for conversion of .ipynb files. | |
|
3 | 3 | |
|
4 | 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 | #----------------------------------------------------------------------------- | |
|
15 | #Imports | |
|
16 | #----------------------------------------------------------------------------- | |
|
7 | # Copyright (c) IPython Development Team. | |
|
8 | # Distributed under the terms of the Modified BSD License. | |
|
17 | 9 | |
|
18 | # Stdlib imports | |
|
19 | 10 | from __future__ import print_function |
|
20 | 11 | |
|
21 | 12 | import logging |
@@ -23,7 +14,6 b' import sys' | |||
|
23 | 14 | import os |
|
24 | 15 | import glob |
|
25 | 16 | |
|
26 | # From IPython | |
|
27 | 17 | from IPython.core.application import BaseIPythonApplication, base_aliases, base_flags |
|
28 | 18 | from IPython.core.profiledir import ProfileDir |
|
29 | 19 | from IPython.config import catch_config_error, Configurable |
@@ -128,9 +118,9 b' class NbConvertApp(BaseIPythonApplication):' | |||
|
128 | 118 | |
|
129 | 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 |
|
|
123 | > ipython nbconvert mynotebook.ipynb --to pdf | |
|
134 | 124 | |
|
135 | 125 | You can get (and serve) a Reveal.js-powered slideshow |
|
136 | 126 | |
@@ -174,8 +164,7 b' class NbConvertApp(BaseIPythonApplication):' | |||
|
174 | 164 | postprocessor_class = DottedOrNone(config=True, |
|
175 | 165 | help="""PostProcessor class used to write the |
|
176 | 166 | results of the conversion""") |
|
177 |
postprocessor_aliases = {' |
|
|
178 | 'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'} | |
|
167 | postprocessor_aliases = {'serve': 'IPython.nbconvert.postprocessors.serve.ServePostProcessor'} | |
|
179 | 168 | postprocessor_factory = Type() |
|
180 | 169 | |
|
181 | 170 | def _postprocessor_class_changed(self, name, old, new): |
@@ -1,5 +1,4 b'' | |||
|
1 | 1 | from .base import PostProcessorBase |
|
2 | from .pdf import PDFPostProcessor | |
|
3 | 2 | |
|
4 | 3 | # protect against unavailable tornado |
|
5 | 4 | try: |
@@ -1,22 +1,15 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | """Test NbConvertApp""" |
|
3 | 3 | |
|
4 | #----------------------------------------------------------------------------- | |
|
5 | # Copyright (C) 2013 The IPython Development Team | |
|
6 | # | |
|
7 | # Distributed under the terms of the BSD License. The full license is in | |
|
8 | # the file COPYING, distributed as part of this software. | |
|
9 | #----------------------------------------------------------------------------- | |
|
10 | ||
|
11 | #----------------------------------------------------------------------------- | |
|
12 | # Imports | |
|
13 | #----------------------------------------------------------------------------- | |
|
4 | # Copyright (c) IPython Development Team. | |
|
5 | # Distributed under the terms of the Modified BSD License. | |
|
14 | 6 | |
|
15 | 7 | import os |
|
16 | 8 | import glob |
|
17 | 9 | import sys |
|
18 | 10 | |
|
19 | 11 | from .base import TestsBase |
|
12 | from ..postprocessors import PostProcessorBase | |
|
20 | 13 | |
|
21 | 14 | import IPython.testing.tools as tt |
|
22 | 15 | from IPython.testing import decorators as dec |
@@ -25,6 +18,10 b' from IPython.testing import decorators as dec' | |||
|
25 | 18 | # Classes and functions |
|
26 | 19 | #----------------------------------------------------------------------------- |
|
27 | 20 | |
|
21 | class DummyPost(PostProcessorBase): | |
|
22 | def postprocess(self, filename): | |
|
23 | print("Dummy:%s" % filename) | |
|
24 | ||
|
28 | 25 | class TestNbConvertApp(TestsBase): |
|
29 | 26 | """Collection of NbConvertApp tests""" |
|
30 | 27 | |
@@ -79,24 +76,19 b' class TestNbConvertApp(TestsBase):' | |||
|
79 | 76 | """ |
|
80 | 77 | with self.create_temp_cwd(['notebook2.ipynb']): |
|
81 | 78 | os.rename('notebook2.ipynb', 'notebook with spaces.ipynb') |
|
82 |
self.call('nbconvert --log-level 0 --to |
|
|
83 |
|
|
|
84 | '--PDFPostProcessor.verbose=True') | |
|
85 | assert os.path.isfile('notebook with spaces.tex') | |
|
86 | assert os.path.isdir('notebook with spaces_files') | |
|
79 | self.call('nbconvert --log-level 0 --to pdf' | |
|
80 | ' "notebook with spaces"' | |
|
81 | ' --PDFExporter.latex_count=1' | |
|
82 | ' --PDFExporter.verbose=True' | |
|
83 | ) | |
|
87 | 84 | assert os.path.isfile('notebook with spaces.pdf') |
|
88 | 85 | |
|
89 | @dec.onlyif_cmds_exist('pdflatex') | |
|
90 | @dec.onlyif_cmds_exist('pandoc') | |
|
91 | 86 | def test_post_processor(self): |
|
92 | """ | |
|
93 | Do post processors work? | |
|
94 | """ | |
|
87 | """Do post processors work?""" | |
|
95 | 88 | with self.create_temp_cwd(['notebook1.ipynb']): |
|
96 |
self.call('nbconvert --log-level 0 --to |
|
|
97 | '--post PDF --PDFPostProcessor.verbose=True') | |
|
98 |
|
|
|
99 | assert os.path.isfile('notebook1.pdf') | |
|
89 | out, err = self.call('nbconvert --log-level 0 --to python notebook1 ' | |
|
90 | '--post IPython.nbconvert.tests.test_nbconvertapp.DummyPost') | |
|
91 | self.assertIn('Dummy:notebook1.py', out) | |
|
100 | 92 | |
|
101 | 93 | @dec.onlyif_cmds_exist('pandoc') |
|
102 | 94 | def test_spurious_cr(self): |
@@ -195,10 +187,9 b' class TestNbConvertApp(TestsBase):' | |||
|
195 | 187 | """ |
|
196 | 188 | with self.create_temp_cwd(): |
|
197 | 189 | self.create_empty_notebook(u'nb1_análisis.ipynb') |
|
198 |
self.call('nbconvert --log-level 0 --to |
|
|
199 | '"nb1_*" --post PDF ' | |
|
200 |
|
|
|
201 | assert os.path.isfile(u'nb1_análisis.tex') | |
|
190 | self.call('nbconvert --log-level 0 --to pdf "nb1_*"' | |
|
191 | ' --PDFExporter.latex_count=1' | |
|
192 | ' --PDFExporter.verbose=True') | |
|
202 | 193 | assert os.path.isfile(u'nb1_análisis.pdf') |
|
203 | 194 | |
|
204 | 195 | def test_cwd_plugin(self): |
@@ -1,17 +1,7 b'' | |||
|
1 | """ | |
|
2 | Contains writer for writing nbconvert output to filesystem. | |
|
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 | #----------------------------------------------------------------------------- | |
|
1 | """Contains writer for writing nbconvert output to filesystem.""" | |
|
11 | 2 | |
|
12 | #----------------------------------------------------------------------------- | |
|
13 | # Imports | |
|
14 | #----------------------------------------------------------------------------- | |
|
3 | # Copyright (c) IPython Development Team. | |
|
4 | # Distributed under the terms of the Modified BSD License. | |
|
15 | 5 | |
|
16 | 6 | import io |
|
17 | 7 | import os |
@@ -19,6 +9,7 b' import glob' | |||
|
19 | 9 | |
|
20 | 10 | from IPython.utils.traitlets import Unicode |
|
21 | 11 | from IPython.utils.path import link_or_copy |
|
12 | from IPython.utils.py3compat import unicode_type | |
|
22 | 13 | |
|
23 | 14 | from .base import WriterBase |
|
24 | 15 | |
@@ -110,6 +101,11 b' class FilesWriter(WriterBase):' | |||
|
110 | 101 | |
|
111 | 102 | # Write conversion results. |
|
112 | 103 | self.log.info("Writing %i bytes to %s", len(output), dest) |
|
113 | with io.open(dest, 'w', encoding='utf-8') as f: | |
|
114 | f.write(output) | |
|
104 | if isinstance(output, unicode_type): | |
|
105 | with io.open(dest, 'w', encoding='utf-8') as f: | |
|
106 | f.write(output) | |
|
107 | else: | |
|
108 | with io.open(dest, 'wb') as f: | |
|
109 | f.write(output) | |
|
110 | ||
|
115 | 111 | return dest |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now