123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- """Module containing a preprocessor that converts outputs in the notebook from
- one format to another.
- """
- # Copyright (c) Jupyter Development Team.
- # Distributed under the terms of the Modified BSD License.
- import base64
- import io
- import os
- import sys
- import subprocess
- from ipython_genutils.py3compat import cast_unicode_py2
- from testpath.tempdir import TemporaryDirectory
- from traitlets import Unicode, default
- from .convertfigures import ConvertFiguresPreprocessor
- if sys.version_info >= (3,3):
- from shutil import which
- get_inkscape_path = which('inkscape')
- else:
- get_inkscape_path = None
- INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
- if sys.platform == "win32":
- try:
- import winreg
- except ImportError:
- import _winreg as winreg
- class SVG2PDFPreprocessor(ConvertFiguresPreprocessor):
- """
- Converts all of the outputs in a notebook from SVG to PDF.
- """
- @default('from_format')
- def _from_format_default(self):
- return 'image/svg+xml'
- @default('to_format')
- def _to_format_default(self):
- return 'application/pdf'
- command = Unicode(
- 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_filename},
- and write a PDF to {to_filename}.
- """).tag(config=True)
- @default('command')
- def _command_default(self):
- return self.inkscape + \
- ' --without-gui --export-pdf="{to_filename}" "{from_filename}"'
-
- inkscape = Unicode(help="The path to Inkscape, if necessary").tag(config=True)
- @default('inkscape')
- def _inkscape_default(self):
- if get_inkscape_path is not None:
- return get_inkscape_path
- if sys.platform == "darwin":
- if os.path.isfile(INKSCAPE_APP):
- return INKSCAPE_APP
- if sys.platform == "win32":
- wr_handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
- try:
- rkey = winreg.OpenKey(wr_handle, "SOFTWARE\\Classes\\inkscape.svg\\DefaultIcon")
- inkscape = winreg.QueryValueEx(rkey, "")[0]
- except FileNotFoundError:
- raise FileNotFoundError("Inkscape executable not found")
- return inkscape
- 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(cast_unicode_py2(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")
|