##// END OF EJS Templates
move test_lexers to lib/tests...
move test_lexers to lib/tests to match the module it tests

File last commit:

r21122:f42c9edb
r21232:77e5eee4
Show More
pdf.py
149 lines | 5.4 KiB | text/x-python | PythonLexer
MinRK
remove PDF post processor
r16418 """Export to PDF via latex"""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
MinRK
add PDFExporter...
r16265
import subprocess
import os
import sys
Min RK
use py3compat.which in common locations
r21122 from IPython.utils.py3compat import which
MinRK
remove PDF post processor
r16418 from IPython.utils.traitlets import Integer, List, Bool, Instance
from IPython.utils.tempdir import TemporaryWorkingDirectory
from .latex import LatexExporter
MinRK
add PDFExporter...
r16265
MinRK
remove PDF post processor
r16418 class PDFExporter(LatexExporter):
MinRK
add PDFExporter...
r16265 """Writer designed to write to PDF files"""
MinRK
remove PDF post processor
r16418 latex_count = Integer(3, config=True,
help="How many times latex will be called."
)
MinRK
add PDFExporter...
r16265
MinRK
remove PDF post processor
r16418 latex_command = List([u"pdflatex", u"{filename}"], config=True,
help="Shell command used to compile latex."
)
MinRK
add PDFExporter...
r16265
MinRK
remove PDF post processor
r16418 bib_command = List([u"bibtex", u"{filename}"], config=True,
help="Shell command used to run bibtex."
)
MinRK
add PDFExporter...
r16265
MinRK
remove PDF post processor
r16418 verbose = Bool(False, config=True,
help="Whether to display the output of latex commands."
)
MinRK
add PDFExporter...
r16265
MinRK
remove PDF post processor
r16418 temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'], config=True,
help="File extensions of temp files to remove after running."
)
Min RK
s/IPython.nbconvert/jupyter_nbconvert/...
r20908 writer = Instance("jupyter_nbconvert.writers.FilesWriter", args=())
MinRK
add PDFExporter...
r16265
def run_command(self, command_list, filename, count, log_function):
"""Run command_list count times.
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
-------
MinRK
remove PDF post processor
r16418 success : bool
MinRK
add PDFExporter...
r16265 A boolean indicating if the command was successful (True)
or failed (False).
"""
command = [c.format(filename=filename) for c in command_list]
AnneTheAgile
[NBConvert]: Error out if command is missing.
r18734
# On windows with python 2.x there is a bug in subprocess.Popen and
MinRK
add PDFExporter...
r16265 # unicode commands are not supported
if sys.platform == 'win32' and sys.version_info < (3,0):
#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)
Min RK
use py3compat.which in common locations
r21122 command = [c.encode('cp1252') for c in command]
AnneTheAgile
[NBConvert]: Error out if command is missing.
r18734
Thomas Kluyver
Use our own find_cmd instead of shutil.which
r19914 # This will throw a clearer error if the command is not found
Min RK
use py3compat.which in common locations
r21122 cmd = which(command_list[0])
if cmd is None:
raise OSError("%s not found on PATH" % command_list[0])
AnneTheAgile
[NBConvert]: Error out if command is missing.
r18734
MinRK
add PDFExporter...
r16265 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):
p = subprocess.Popen(command, stdout=stdout, stdin=null)
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
def run_latex(self, filename):
"""Run pdflatex self.latex_count times."""
def log_error(command, out):
self.log.critical(u"%s failed: %s\n%s", command[0], command, out)
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]
def log_error(command, out):
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)
return self.run_command(self.bib_command, filename, 1, log_error)
def clean_temp_files(self, filename):
"""Remove temporary files created by pdflatex/bibtex."""
self.log.info("Removing temporary LaTeX files")
filename = os.path.splitext(filename)[0]
for ext in self.temp_file_exts:
try:
os.remove(filename+ext)
except OSError:
pass
MinRK
remove PDF post processor
r16418 def from_notebook_node(self, nb, resources=None, **kw):
latex, resources = super(PDFExporter, self).from_notebook_node(
nb, resources=resources, **kw
)
with TemporaryWorkingDirectory() as td:
notebook_name = "notebook"
tex_file = self.writer.write(latex, resources, notebook_name=notebook_name)
self.log.info("Building PDF")
rc = self.run_latex(tex_file)
if not rc:
rc = self.run_bib(tex_file)
if not rc:
rc = self.run_latex(tex_file)
pdf_file = notebook_name + '.pdf'
if not os.path.isfile(pdf_file):
raise RuntimeError("PDF creating failed")
MinRK
add PDFExporter...
r16265 self.log.info('PDF successfully created')
MinRK
remove PDF post processor
r16418 with open(pdf_file, 'rb') as f:
pdf_data = f.read()
# convert output extension to pdf
# the writer above required it to be tex
Thomas Kluyver
Add the . into file_extension
r19027 resources['output_extension'] = '.pdf'
MinRK
remove PDF post processor
r16418
return pdf_data, resources