|
|
"""Module containing a preprocessor that converts outputs in the notebook from
|
|
|
one format to another.
|
|
|
"""
|
|
|
|
|
|
# Copyright (c) IPython Development Team.
|
|
|
# Distributed under the terms of the Modified BSD License.
|
|
|
|
|
|
import base64
|
|
|
import io
|
|
|
import os
|
|
|
import sys
|
|
|
import subprocess
|
|
|
|
|
|
from IPython.utils.tempdir import TemporaryDirectory
|
|
|
from IPython.utils.traitlets import Unicode
|
|
|
|
|
|
from .convertfigures import ConvertFiguresPreprocessor
|
|
|
|
|
|
|
|
|
INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
|
|
|
|
|
|
|
|
|
class SVG2PDFPreprocessor(ConvertFiguresPreprocessor):
|
|
|
"""
|
|
|
Converts all of the outputs in a notebook from SVG to PDF.
|
|
|
"""
|
|
|
|
|
|
def _from_format_default(self):
|
|
|
return 'image/svg+xml'
|
|
|
def _to_format_default(self):
|
|
|
return 'application/pdf'
|
|
|
|
|
|
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):
|
|
|
return self.inkscape + \
|
|
|
' --without-gui --export-pdf="{to_filename}" "{from_filename}"'
|
|
|
|
|
|
inkscape = Unicode(config=True, help="The path to Inkscape, if necessary")
|
|
|
def _inkscape_default(self):
|
|
|
if sys.platform == "darwin":
|
|
|
if os.path.isfile(INKSCAPE_APP):
|
|
|
return INKSCAPE_APP
|
|
|
return "inkscape"
|
|
|
|
|
|
|
|
|
def convert_figure(self, data_format, 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.svg')
|
|
|
# SVG data is unicode text
|
|
|
with io.open(input_filename, 'w', encoding='utf8') as f:
|
|
|
f.write(data)
|
|
|
|
|
|
#Call conversion application
|
|
|
output_filename = os.path.join(tmpdir, 'figure.pdf')
|
|
|
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:
|
|
|
# PDF is a nb supported binary, data type, so base64 encode.
|
|
|
return base64.encodestring(f.read())
|
|
|
else:
|
|
|
raise TypeError("Inkscape svg to pdf conversion failed")
|
|
|
|