##// END OF EJS Templates
Backport PR #5459: Fix interact animation page jump FF...
Backport PR #5459: Fix interact animation page jump FF Firefox doesn't render images immediately as the data is available. When animating the way that we animate, this causes the output area to collapse quickly before returning to its original size. When the output area collapses, FireFox scrolls upwards in attempt to compensate for the lost vertical content (so it looks like you are on the same spot in the page, with respect to the contents below the image's prior location). The solution is to resize the image output after the `img onload` event has fired. This PR: - Releases the `clear_output` height lock after the image has been loaded (instead of immediately or using a timeout). - Removes a `setTimeout` call in the `append_output` method. - `clear_output` in zmqshell no longer sends `\r` to the stream outputs. closes #5128

File last commit:

r15384:b21888ff
r16229:ff1462d3
Show More
pdf.py
156 lines | 5.8 KiB | text/x-python | PythonLexer
"""
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
import sys
from IPython.utils.traitlets import Integer, List, Bool
from .base import PostProcessorBase
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
class PDFPostProcessor(PostProcessorBase):
"""Writer designed to write to PDF files"""
latex_count = Integer(3, config=True, help="""
How many times pdflatex will be called.
""")
latex_command = List([u"pdflatex", u"{filename}"], config=True, help="""
Shell command used to compile PDF.""")
bib_command = List([u"bibtex", u"{filename}"], config=True, help="""
Shell command used to run bibtex.""")
verbose = Bool(False, config=True, help="""
Whether or not to display the output of the compile call.
""")
temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'],
config=True, help="""
Filename extensions of temp files to remove after running.
""")
pdf_open = Bool(False, config=True, help="""
Whether or not to open the pdf after the compile call.
""")
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
-------
continue : bool
A boolean indicating if the command was successful (True)
or failed (False).
"""
command = [c.format(filename=filename) for c in command_list]
#In windows and python 2.x there is a bug in subprocess.Popen and
# 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)
command = [c.encode('cp1252') for c in command]
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
def open_pdf(self, filename):
"""Open the pdf in the default viewer."""
if sys.platform.startswith('darwin'):
subprocess.call(('open', filename))
elif os.name == 'nt':
os.startfile(filename)
elif os.name == 'posix':
subprocess.call(('xdg-open', filename))
return
def postprocess(self, filename):
"""Build a PDF by running pdflatex and bibtex"""
self.log.info("Building PDF")
cont = self.run_latex(filename)
if cont:
cont = self.run_bib(filename)
else:
self.clean_temp_files(filename)
return
if cont:
cont = self.run_latex(filename)
self.clean_temp_files(filename)
filename = os.path.splitext(filename)[0]
if os.path.isfile(filename+'.pdf'):
self.log.info('PDF successfully created')
if self.pdf_open:
self.log.info('Viewer called')
self.open_pdf(filename+'.pdf')
return