This happens when trying to convert a notebook with svg graphics embedded.
I have a hunch that the svg2pdf.py code can not handle a blank in the program name of inkscape as it is the case on my machine ("C:\Program Files\Inkscape\bin\inkscape.exe"). Also the text before the exception "'C:\Program' is not recognized as an internal or external command, operable program or batch file." gives this impression.
Environment
Steps to reproduce
(Rather) minimal notebook: Gantt_Minimal_SVG.txt
Nbconvert version: 5.6.1
The alpha for nbconvert -- 6.0.0a4 -- should fix the issue with inkscape 1.0 on windows, if you want to give that a try.
Thanks. I've upgraded an anaconda env to nbconvert 6.0.0.a4. After that I've got this error message when trying to export to pdf:
[E 08:02:48.932 NotebookApp] nbconvert failed: [WinError 2] The system cannot find the file specified
Traceback (most recent call last):
File "...anaconda env...\lib\site-packages\traitlets\traitlets.py", line 528, in get
value = obj._trait_values[self.name]
KeyError: 'command'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "...anaconda env...\lib\site-packages\traitlets\traitlets.py", line 528, in get
value = obj._trait_values[self.name]
KeyError: 'inkscape_version'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "...anaconda env...\lib\site-packages\notebook\nbconvert\handlers.py", line 132, in get
resources=resource_dict
File "...anaconda env...\lib\site-packages\nbconvert\exporters\pdf.py", line 176, in from_notebook_node
nb, resources=resources, **kw
File "...anaconda env...\lib\site-packages\nbconvert\exporters\latex.py", line 77, in from_notebook_node
return super().from_notebook_node(nb, resources, **kw)
File "...anaconda env...\lib\site-packages\nbconvert\exporters\templateexporter.py", line 340, in from_notebook_node
nb_copy, resources = super().from_notebook_node(nb, resources, **kw)
File "...anaconda env...\lib\site-packages\nbconvert\exporters\exporter.py", line 143, in from_notebook_node
nb_copy, resources = self._preprocess(nb_copy, resources)
File "...anaconda env...\lib\site-packages\nbconvert\exporters\exporter.py", line 320, in _preprocess
nbc, resc = preprocessor(nbc, resc)
File "...anaconda env...\lib\site-packages\nbconvert\preprocessors\base.py", line 47, in __call__
return self.preprocess(nb, resources)
File "...anaconda env...\lib\site-packages\nbconvert\preprocessors\base.py", line 69, in preprocess
nb.cells[index], resources = self.preprocess_cell(cell, resources, index)
File "...anaconda env...\lib\site-packages\nbconvert\preprocessors\convertfigures.py", line 46, in preprocess_cell
self.from_format, output.data[self.from_format])
File "...anaconda env...\lib\site-packages\nbconvert\preprocessors\svg2pdf.py", line 126, in convert_figure
shell = self.command.format(from_filename=input_filename,
File "...anaconda env...\lib\site-packages\traitlets\traitlets.py", line 556, in __get__
return self.get(obj, cls)
File "...anaconda env...\lib\site-packages\traitlets\traitlets.py", line 535, in get
value = self._validate(obj, dynamic_default())
File "...anaconda env...\lib\site-packages\nbconvert\preprocessors\svg2pdf.py", line 78, in _command_default
major_verison = self.inkscape_version.split('.')[0]
File "...anaconda env...\lib\site-packages\traitlets\traitlets.py", line 556, in __get__
return self.get(obj, cls)
File "...anaconda env...\lib\site-packages\traitlets\traitlets.py", line 535, in get
value = self._validate(obj, dynamic_default())
File "...anaconda env...\lib\site-packages\nbconvert\preprocessors\svg2pdf.py", line 60, in _inkscape_version_default
stderr=subprocess.PIPE)
File "...anaconda env...\lib\subprocess.py", line 800, in __init__
restore_signals, start_new_session)
File "...anaconda env...\lib\subprocess.py", line 1207, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
[W 08:02:48.939 NotebookApp] 500 GET /nbconvert/pdf/Gantt_Spielereien/Gantt_Minimal_SVG.ipynb?download=true (::1): nbconvert failed: [WinError 2] The system cannot find the file specified
btw, exporting to pdf without SVG works in this environment.
I did a little research with the svg2pdf.py of the above mentioned alpha and found the following:
My registry contains the string value "C:\Program Files\Inkscape\bin\inkscape.exe,0" (without quotation marks). When you enter that text in a command line prompt, the trailing ",0" leads to
'"C:\Program Files\Inkscape\bin\inkscape.exe,0"' is not recognized as an internal or external command, operable program or batch file."
Second, the blank in "Program Files" causes problems.
If I modify svg2pdf.py to remove the ",0" when getting the string from the registry, e.g., by
inkscape = winreg.QueryValueEx(rkey, "")[0].split(',')[0]
and change the command string from
return '{inkscape}{gui_option}{export_option}='.format(
inkscape=self.inkscape, export_option=export_option, gui_option=gui_option
) + '"{to_filename}" "{from_filename}"'
to
return '"{inkscape}"{gui_option}{export_option}='.format(
inkscape=self.inkscape, export_option=export_option, gui_option=gui_option
) + '"{to_filename}" "{from_filename}"'
, then svg conversion with inkscape works for me.
As I don't know if these changes will work for all OS (and not only for my Win10), I'll leave it here for someone to pick it up, include it, and test it properly.
@MSeal theoky was quicker. :)
I had the exact same problem on Win10 and 6.0.0.a4, with the message: nbconvert failed: Inkscape svg to pdf conversion failed
The server showed an exception, something like: 'C:\Program' is not recognized as a command.
Quick solution for beginners: reinstall Inkscape in a path with no whitespace.
Ahh thanks for finding the existing issue :+1:
I've been swamped and my free time has been limited so I'm not sure when I'll get to this. Would love to have a new contributor try to put this into a PR with a test improvement.
I did a little research with the svg2pdf.py of the above mentioned alpha and found the following:
My registry contains the string value "C:\Program Files\Inkscape\bin\inkscape.exe,0" (without quotation marks). When you enter that text in a command line prompt, the trailing ",0" leads to
'"C:\Program Files\Inkscape\bin\inkscape.exe,0"' is not recognized as an internal or external command, operable program or batch file."Second, the blank in "Program Files" causes problems.
If I modify svg2pdf.py to remove the ",0" when getting the string from the registry, e.g., by
inkscape = winreg.QueryValueEx(rkey, "")[0].split(',')[0]and change the command string from
return '{inkscape}{gui_option}{export_option}='.format( inkscape=self.inkscape, export_option=export_option, gui_option=gui_option ) + '"{to_filename}" "{from_filename}"'to
return '"{inkscape}"{gui_option}{export_option}='.format( inkscape=self.inkscape, export_option=export_option, gui_option=gui_option ) + '"{to_filename}" "{from_filename}"', then svg conversion with inkscape works for me.
As I don't know if these changes will work for all OS (and not only for my Win10), I'll leave it here for someone to pick it up, include it, and test it properly.
Hi @theoky, I'm trying to follow your solution. Could you please explain how to locate the file svg2pdf.py?
Hi @theoky, I'm trying to follow your solution. Could you please explain how to locate the file
svg2pdf.py?
I can find it on my machine here:
Hope that helps.
Hi @theoky, I'm trying to follow your solution. Could you please explain how to locate the file
svg2pdf.py?I can find it on my machine here:
\python-3.#.#.amd64\Lib\site-packages\nbconvert\preprocessors \ \Lib\site-packages\nbconvert\preprocessors Hope that helps.
Thank you so much. I've just found it. It's sad that the content of the file is changed and I'm unable to apply your method.
"""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")
I stumbled on the same issued and found #244. I created the pull request #1469 for this.
I created the pull request #1469 for this.
Thanks for creating the pull request.
Most helpful comment
I did a little research with the svg2pdf.py of the above mentioned alpha and found the following:
My registry contains the string value "C:\Program Files\Inkscape\bin\inkscape.exe,0" (without quotation marks). When you enter that text in a command line prompt, the trailing ",0" leads to
Second, the blank in "Program Files" causes problems.
If I modify svg2pdf.py to remove the ",0" when getting the string from the registry, e.g., by
and change the command string from
to
, then svg conversion with inkscape works for me.
As I don't know if these changes will work for all OS (and not only for my Win10), I'll leave it here for someone to pick it up, include it, and test it properly.