##// END OF EJS Templates
Merge pull request #7027 from takluyver/svg2pdf-test-fix...
Thomas Kluyver -
r19075:1da9421a merge
parent child Browse files
Show More
@@ -1,64 +1,58 b''
1 1 """Module containing a preprocessor that converts outputs in the notebook from
2 2 one format to another.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the Modified BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 from .base import Preprocessor
17 17 from IPython.utils.traitlets import Unicode
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22
23 23 class ConvertFiguresPreprocessor(Preprocessor):
24 24 """
25 25 Converts all of the outputs in a notebook from one format to another.
26 26 """
27 27
28 28 from_format = Unicode(config=True, help='Format the converter accepts')
29 29 to_format = Unicode(config=True, help='Format the converter writes')
30 30
31 31 def __init__(self, **kw):
32 32 """
33 33 Public constructor
34 34 """
35 35 super(ConvertFiguresPreprocessor, self).__init__(**kw)
36 36
37 37
38 38 def convert_figure(self, data_format, data):
39 39 raise NotImplementedError()
40 40
41 41
42 42 def preprocess_cell(self, cell, resources, cell_index):
43 43 """
44 44 Apply a transformation on each cell,
45 45
46 46 See base.py
47 47 """
48 48
49 49 # Loop through all of the datatypes of the outputs in the cell.
50 for index, cell_out in enumerate(cell.get('outputs', [])):
51 for data_type, data in list(cell_out.items()):
52 # this must run *before* extract outputs,
53 # so figure_name and filename do not exist
54 self._convert_figure(cell_out, resources, data_type, data)
55 return cell, resources
50 for output in cell.get('outputs', []):
51 if output.output_type in {'execute_result', 'display_data'} \
52 and self.from_format in output.data \
53 and self.to_format not in output.data:
56 54
55 output.data[self.to_format] = self.convert_figure(
56 self.from_format, output.data[self.from_format])
57 57
58 def _convert_figure(self, cell_out, resources, data_type, data):
59 """
60 Convert a figure and output the results to the cell output
61 """
62 if not self.to_format in cell_out and data_type == self.from_format:
63 data = self.convert_figure(data_type, data)
64 cell_out[self.to_format] = data
58 return cell, resources
@@ -1,82 +1,82 b''
1 1 """Module containing a preprocessor that converts outputs in the notebook from
2 2 one format to another.
3 3 """
4 4
5 5 # Copyright (c) IPython Development Team.
6 6 # Distributed under the terms of the Modified BSD License.
7 7
8 8 import base64
9 9 import io
10 10 import os
11 11 import sys
12 12 import subprocess
13 13
14 14 from IPython.utils.tempdir import TemporaryDirectory
15 15 from IPython.utils.traitlets import Unicode
16 16
17 17 from .convertfigures import ConvertFiguresPreprocessor
18 18
19 19
20 20 INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
21 21
22 22
23 23 class SVG2PDFPreprocessor(ConvertFiguresPreprocessor):
24 24 """
25 25 Converts all of the outputs in a notebook from SVG to PDF.
26 26 """
27 27
28 28 def _from_format_default(self):
29 29 return 'image/svg+xml'
30 30 def _to_format_default(self):
31 31 return 'application/pdf'
32 32
33 33 command = Unicode(config=True,
34 34 help="""The command to use for converting SVG to PDF
35 35
36 36 This string is a template, which will be formatted with the keys
37 37 to_filename and from_filename.
38 38
39 39 The conversion call must read the SVG from {from_flename},
40 40 and write a PDF to {to_filename}.
41 41 """)
42 42
43 43 def _command_default(self):
44 44 return self.inkscape + \
45 45 ' --without-gui --export-pdf="{to_filename}" "{from_filename}"'
46 46
47 47 inkscape = Unicode(config=True, help="The path to Inkscape, if necessary")
48 48 def _inkscape_default(self):
49 49 if sys.platform == "darwin":
50 50 if os.path.isfile(INKSCAPE_APP):
51 51 return INKSCAPE_APP
52 52 return "inkscape"
53 53
54 54
55 55 def convert_figure(self, data_format, data):
56 56 """
57 57 Convert a single SVG figure to PDF. Returns converted data.
58 58 """
59 59
60 60 #Work in a temporary directory
61 61 with TemporaryDirectory() as tmpdir:
62 62
63 63 #Write fig to temp file
64 input_filename = os.path.join(tmpdir, 'figure.' + data_format)
64 input_filename = os.path.join(tmpdir, 'figure.svg')
65 65 # SVG data is unicode text
66 66 with io.open(input_filename, 'w', encoding='utf8') as f:
67 67 f.write(data)
68 68
69 69 #Call conversion application
70 70 output_filename = os.path.join(tmpdir, 'figure.pdf')
71 71 shell = self.command.format(from_filename=input_filename,
72 72 to_filename=output_filename)
73 73 subprocess.call(shell, shell=True) #Shell=True okay since input is trusted.
74 74
75 75 #Read output from drive
76 76 # return value expects a filename
77 77 if os.path.isfile(output_filename):
78 78 with open(output_filename, 'rb') as f:
79 79 # PDF is a nb supported binary, data type, so base64 encode.
80 80 return base64.encodestring(f.read())
81 81 else:
82 82 raise TypeError("Inkscape svg to pdf conversion failed")
@@ -1,74 +1,73 b''
1 1 """Tests for the svg2pdf preprocessor"""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 from IPython.testing import decorators as dec
7 7 from IPython.nbformat import v4 as nbformat
8 8
9 9 from .base import PreprocessorTestsBase
10 10 from ..svg2pdf import SVG2PDFPreprocessor
11 11
12 12
13 13 class Testsvg2pdf(PreprocessorTestsBase):
14 14 """Contains test functions for svg2pdf.py"""
15 15
16 16 simple_svg = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
17 17 <!-- Created with Inkscape (http://www.inkscape.org/) -->
18 18 <svg
19 19 xmlns:svg="http://www.w3.org/2000/svg"
20 20 xmlns="http://www.w3.org/2000/svg"
21 21 version="1.0"
22 22 x="0.00000000"
23 23 y="0.00000000"
24 24 width="500.00000"
25 25 height="500.00000"
26 26 id="svg2">
27 27 <defs
28 28 id="defs4" />
29 29 <g
30 30 id="layer1">
31 31 <rect
32 32 width="300.00000"
33 33 height="300.00000"
34 34 x="100.00000"
35 35 y="100.00000"
36 36 style="opacity:1.0000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:8.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000"
37 37 id="rect5719" />
38 38 </g>
39 39 </svg>"""
40 40
41 41 def build_notebook(self):
42 42 """Build a reveal slides notebook in memory for use with tests.
43 43 Overrides base in PreprocessorTestsBase"""
44 44
45 outputs = [nbformat.new_output(output_type="image/svg+xml", output_svg=self.simple_svg)]
46
47 slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
48 subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
45 outputs = [nbformat.new_output(output_type='display_data',
46 data={'image/svg+xml':self.simple_svg})
47 ]
49 48
50 49 cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs)]
51 50
52 51 return nbformat.new_notebook(cells=cells)
53 52
54 53
55 54 def build_preprocessor(self):
56 55 """Make an instance of a preprocessor"""
57 56 preprocessor = SVG2PDFPreprocessor()
58 57 preprocessor.enabled = True
59 58 return preprocessor
60 59
61 60
62 61 def test_constructor(self):
63 62 """Can a SVG2PDFPreprocessor be constructed?"""
64 63 self.build_preprocessor()
65 64
66 65
67 66 @dec.onlyif_cmds_exist('inkscape')
68 67 def test_output(self):
69 68 """Test the output of the SVG2PDFPreprocessor"""
70 69 nb = self.build_notebook()
71 70 res = self.build_resources()
72 71 preprocessor = self.build_preprocessor()
73 72 nb, res = preprocessor(nb, res)
74 self.assertIn('application/pdf', nb.cells[0].outputs[0])
73 self.assertIn('application/pdf', nb.cells[0].outputs[0].data)
General Comments 0
You need to be logged in to leave comments. Login now