Skip to content

Commit

Permalink
Merge pull request ipython#3695 from minrk/nbconvert
Browse files Browse the repository at this point in the history
fix SVG2PDF

there were some logical issues, with SVG2PDF assuming it was run
both before and after figure extraction.

Also makes the inkscape command configurable,
in case it doesn't work some places.

Adds pdf block for output in latex templates.

closes ipython#3693
  • Loading branch information
minrk committed Jul 19, 2013
2 parents 254c007 + 462509f commit 142ec62
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 34 deletions.
2 changes: 1 addition & 1 deletion IPython/nbconvert/exporters/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def _init_filters(self):
def default_config(self):
c = Config({
'NbConvertBase': {
'display_data_priority' : ['latex', 'png', 'jpg', 'svg', 'jpeg', 'text']
'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
},
'ExtractFigureTransformer': {
'enabled':True
Expand Down
7 changes: 7 additions & 0 deletions IPython/nbconvert/templates/latex/base.tplx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ it introduces a new line
\end{center}
((*- endblock -*))

((*- block data_pdf -*))
\begin{center}
\includegraphics[width=0.7\textwidth]{(((output.pdf_filename[:-4])))}
\par
\end{center}
((*- endblock -*))

((* block pyout *))
((* block data_priority scoped *))((( super() )))((* endblock *))
((* endblock pyout *))
Expand Down
4 changes: 4 additions & 0 deletions IPython/nbconvert/templates/latex/sphinx_base.tplx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,10 @@ Note: For best display, use latex syntax highlighting. =))
((( conditionally_center_output(insert_graphics(output.svg_filename)) )))
((*- endblock -*))

((*- block data_pdf -*))
((( conditionally_center_output(insert_graphics(output.pdf_filename[:-4])) )))
((*- endblock -*))

((*- block data_latex *))
((* if resources.sphinx.centeroutput *))\begin{center}((* endif -*))((( output.latex | rm_math_space )))((*- if resources.sphinx.centeroutput *))\end{center} ((* endif -*))
((*- endblock -*))
Expand Down
29 changes: 7 additions & 22 deletions IPython/nbconvert/transformers/convertfigures.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,31 +49,16 @@ def transform_cell(self, cell, resources, cell_index):
#Loop through all of the datatypes of the outputs in the cell.
for index, cell_out in enumerate(cell.get('outputs', [])):
for data_type, data in cell_out.items():

#Get the name of the file exported by the extract figure
#transformer. Do not try to convert the figure if the extract
#fig transformer hasn't touched it
filename = cell_out.get(data_type + '_filename', None)
if filename:
figure_name = filename[:filename.rfind('.')]
self._convert_figure(cell_out, figure_name, resources, data_type, data)
# this must run *before* extract figures,
# so figure_name and filename do not exist
self._convert_figure(cell_out, resources, data_type, data)
return cell, resources


def _convert_figure(self, cell_out, resources, figure_name, data_type, data):
def _convert_figure(self, cell_out, resources, data_type, data):
"""
Convert a figure and output the results to the cell output
"""

if not self.to_format in cell_out:
if data_type == self.from_format:
filename = figure_name + '.' + self.to_format
if filename not in resources['figures']:

#On the cell, make the figure available via
# cell.outputs[i].pdf_filename ... etc (PDF in example)
cell_out[self.to_format + '_filename'] = filename

#In the resources, make the figure available via
# resources['figures']['filename'] = data
resources['figures'][filename] = self.convert_figure(data_type, data)
if not self.to_format in cell_out and data_type == self.from_format:
data = self.convert_figure(data_type, data)
cell_out[self.to_format] = data
37 changes: 26 additions & 11 deletions IPython/nbconvert/transformers/svg2pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# Imports
#-----------------------------------------------------------------------------

import base64
import os
import sys
import subprocess
Expand All @@ -37,41 +38,55 @@

class SVG2PDFTransformer(ConvertFiguresTransformer):
"""
Converts all of the outputs in a notebook from one format to another.
Converts all of the outputs in a notebook from SVG to PDF.
"""

from_format = Unicode('svg', config=True, help='Format the converter accepts')
to_format = Unicode('pdf', config=False, help='Format the converter writes')
command = Unicode(config=True,
help="""The command to use for converting SVG to PDF
This string is a template, which will be formatted with the keys
to_filename and from_filename.
The conversion call must read the SVG from {from_flename},
and write a PDF to {to_filename}.
""")

def _command_default(self):
if sys.platform == "darwin":
return INKSCAPE_OSX_COMMAND
elif sys.platform == "win32":
# windows not yet supported
return ""
else:
return INKSCAPE_COMMAND


def convert_figure(self, data_format, data):
"""
Convert a single Svg figure. Returns converted data.
Convert a single SVG figure to PDF. Returns converted data.
"""

#Work in a temporary directory
with TemporaryDirectory() as tmpdir:

#Write fig to temp file
input_filename = os.path.join(tmpdir, 'figure.' + data_format)
with open(input_filename, 'w') as f:
with open(input_filename, 'wb') as f:
f.write(data)

#Determine command (different on Mac OSX)
command = INKSCAPE_COMMAND
if sys.platform == 'darwin':
command = INKSCAPE_OSX_COMMAND

#Call conversion application
output_filename = os.path.join(tmpdir, 'figure.pdf')
shell = command.format(from_filename=input_filename,
shell = self.command.format(from_filename=input_filename,
to_filename=output_filename)
subprocess.call(shell, shell=True) #Shell=True okay since input is trusted.

#Read output from drive
# return value expects a filename
if os.path.isfile(output_filename):
with open(output_filename, 'rb') as f:
return f.read().encode("base64") #PDF is a nb supported binary
#data type, so base64 encode.
# PDF is a nb supported binary, data type, so base64 encode.
return base64.encodestring(f.read())
else:
return TypeError("Inkscape svg to png conversion failed")

0 comments on commit 142ec62

Please sign in to comment.