##// END OF EJS Templates
Merge pull request #4912 from takluyver/win-io-failures...
Merge pull request #4912 from takluyver/win-io-failures Skip some Windows io failures

File last commit:

r14757:820bebf2
r14893:04ab4044 merge
Show More
pdf.py
156 lines | 5.8 KiB | text/x-python | PythonLexer
Jonathan Frederic
Fixed errors after testing...
r11742 """
Contains writer for writing nbconvert output to PDF.
"""
#-----------------------------------------------------------------------------
#Copyright (c) 2013, the IPython Development Team.
#
#Distributed under the terms of the Modified BSD License.
#
#The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import subprocess
import os
jakobgager
Open pdf after compiling (configurable)
r12899 import sys
Jonathan Frederic
Fixed errors after testing...
r11742
Thomas Robitaille
Provide a list of the command and argument to subprocess for PDF post-processor, which is a better way to avoid issues if there are spaces in the filename.
r11911 from IPython.utils.traitlets import Integer, List, Bool
Jonathan Frederic
Fixed errors after testing...
r11742
Jonathan Frederic
Moved PDF logic into Post-Processor class
r11747 from .base import PostProcessorBase
Jonathan Frederic
Fixed errors after testing...
r11742
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
Jonathan Frederic
Moved PDF logic into Post-Processor class
r11747 class PDFPostProcessor(PostProcessorBase):
Jonathan Frederic
Fixed errors after testing...
r11742 """Writer designed to write to PDF files"""
Brian E. Granger
Fixing review comments:...
r12281 latex_count = Integer(3, config=True, help="""
Jonathan Frederic
Fixed errors after testing...
r11742 How many times pdflatex will be called.
""")
marcmolla
updated hack for pdf postprocess. Now it is only used for windows platforms and python 2.x
r13943 latex_command = List([u"pdflatex", u"{filename}"], config=True, help="""
Jonathan Frederic
flavor=template
r11745 Shell command used to compile PDF.""")
marcmolla
updated hack for pdf postprocess. Now it is only used for windows platforms and python 2.x
r13943 bib_command = List([u"bibtex", u"{filename}"], config=True, help="""
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 Shell command used to run bibtex.""")
Jonathan Frederic
Moved PDF logic into Post-Processor class
r11747 verbose = Bool(False, config=True, help="""
Whether or not to display the output of the compile call.
""")
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'],
config=True, help="""
Brian E. Granger
Fixing review comments:...
r12281 Filename extensions of temp files to remove after running.
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 """)
jakobgager
Adress comments...
r12902 pdf_open = Bool(False, config=True, help="""
jakobgager
Open pdf after compiling (configurable)
r12899 Whether or not to open the pdf after the compile call.
""")
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
def run_command(self, command_list, filename, count, log_function):
Brian E. Granger
Fixing docstring.
r12300 """Run command_list count times.
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
Parameters
----------
command_list : list
A list of args to provide to Popen. Each element of this
list will be interpolated with the filename to convert.
filename : unicode
The name of the file to convert.
count : int
How many times to run the command.
Returns
-------
continue : bool
A boolean indicating if the command was successful (True)
or failed (False).
"""
command = [c.format(filename=filename) for c in command_list]
marcmolla
updated hack for pdf postprocess. Now it is only used for windows platforms and python 2.x
r13943 #In windows and python 2.x there is a bug in subprocess.Popen and
# unicode commands are not supported
marcmolla
Removed Sphinxtransformer test
r13975 if sys.platform == 'win32' and sys.version_info < (3,0):
marcmolla
updated hack for pdf postprocess. Now it is only used for windows platforms and python 2.x
r13943 #We must use cp1252 encoding for calling subprocess.Popen
#Note that sys.stdin.encoding and encoding.DEFAULT_ENCODING
# could be different (cp437 in case of dos console)
command = [c.encode('cp1252') for c in command]
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 times = 'time' if count == 1 else 'times'
self.log.info("Running %s %i %s: %s", command_list[0], count, times, command)
with open(os.devnull, 'rb') as null:
stdout = subprocess.PIPE if not self.verbose else None
for index in range(count):
marcmolla
removed sehll=True
r14757 p = subprocess.Popen(command, stdout=stdout, stdin=null)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 out, err = p.communicate()
if p.returncode:
if self.verbose:
# verbose means I didn't capture stdout with PIPE,
# so it's already been displayed and `out` is None.
out = u''
else:
out = out.decode('utf-8', 'replace')
log_function(command, out)
return False # failure
return True # success
Brian E. Granger
Fixing review comments:...
r12281 def run_latex(self, filename):
"""Run pdflatex self.latex_count times."""
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
def log_error(command, out):
Brian E. Granger
Fixing review comments:...
r12281 self.log.critical(u"%s failed: %s\n%s", command[0], command, out)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
Brian E. Granger
Fixing review comments:...
r12281 return self.run_command(self.latex_command, filename,
self.latex_count, log_error)
def run_bib(self, filename):
"""Run bibtex self.latex_count times."""
filename = os.path.splitext(filename)[0]
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
def log_error(command, out):
Brian E. Granger
Fixing review comments:...
r12281 self.log.warn('%s had problems, most likely because there were no citations',
command[0])
self.log.debug(u"%s output: %s\n%s", command[0], command, out)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
Brian E. Granger
Fixing review comments:...
r12281 return self.run_command(self.bib_command, filename, 1, log_error)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269
def clean_temp_files(self, filename):
"""Remove temporary files created by pdflatex/bibtext."""
self.log.info("Removing temporary LaTeX files")
Brian E. Granger
Fixing review comments:...
r12281 filename = os.path.splitext(filename)[0]
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 for ext in self.temp_file_exts:
try:
os.remove(filename+ext)
except OSError:
pass
Brian E. Granger
Fixing review comments:...
r12281
jakobgager
Adress comments...
r12902 def open_pdf(self, filename):
"""Open the pdf in the default viewer."""
jakobgager
Open pdf after compiling (configurable)
r12899 if sys.platform.startswith('darwin'):
jakobgager
Adress comments...
r12902 subprocess.call(('open', filename))
jakobgager
Open pdf after compiling (configurable)
r12899 elif os.name == 'nt':
jakobgager
Adress comments...
r12902 os.startfile(filename)
jakobgager
Open pdf after compiling (configurable)
r12899 elif os.name == 'posix':
jakobgager
Adress comments...
r12902 subprocess.call(('xdg-open', filename))
jakobgager
Open pdf after compiling (configurable)
r12899 return
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 def postprocess(self, filename):
"""Build a PDF by running pdflatex and bibtex"""
self.log.info("Building PDF")
Brian E. Granger
Fixing review comments:...
r12281 cont = self.run_latex(filename)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 if cont:
Brian E. Granger
Fixing review comments:...
r12281 cont = self.run_bib(filename)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 else:
self.clean_temp_files(filename)
return
if cont:
Brian E. Granger
Fixing review comments:...
r12281 cont = self.run_latex(filename)
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 self.clean_temp_files(filename)
Brian E. Granger
Fixing review comments:...
r12281 filename = os.path.splitext(filename)[0]
if os.path.isfile(filename+'.pdf'):
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 self.log.info('PDF successfully created')
jakobgager
Open pdf after compiling (configurable)
r12899 if self.pdf_open:
self.log.info('Viewer called')
jakobgager
Adress comments...
r12902 self.open_pdf(filename+'.pdf')
Brian E. Granger
Adding better logic to the PDF postprocessor.
r12269 return
jakobgager
Open pdf after compiling (configurable)
r12899