Search code examples
command-line-interfacepython-sphinxmermaid

Problem using mermaid.cli in Sphinx on Windows


I have a simple Sphinx project where I'd like to be able to render my Mermaid charts as png. To do so, I have installed the mermaid.cli via yarn, but I've not managed to get it to work.

My attempts

I've tried various combinations:

  • I've tried installing globally via npm and yarn, to no luck
  • I've tried to install locally in the root folder of my Sphinx project and referring to the .bin folder as an absolute path in my conf.py - but to no luck
  • I am able to use the mmdc from the command prompt as normal

My conf.py

My conf.py is located at C:\Users\marti\Documents\sphinx-test\docs and contains the below (amongst other things):

extensions = [
    "sphinxcontrib.mermaid",
]

mermaid_cmd = "C:\\Users\\marti\\Documents\\sphinx-test\\node_modules\\.bin\\mmdc"
mermaid_output_format = "png"

The traceback

When I use the above conf.py I get below traceback. If I remove \\mmdc from the path, I instead get a Permission Denied error.

# Sphinx version: 3.0.0
# Python version: 3.7.3 (CPython)
# Docutils version: 0.14 
# Jinja2 version: 2.11.1
# Last messages:
#   none found
#   pickling environment...
#   done
#   checking consistency...
#   done
#   preparing documents...
#   done
#   writing output... [ 33%] configure/configure
#   writing output... [ 66%] index
#   writing output... [100%] introduction/introduction
# Loaded extensions:
#   sphinx.ext.mathjax (3.0.0) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\ext\mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\applehelp\__init__.py
#   sphinxcontrib.devhelp (1.0.2) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\devhelp\__init__.py
#   sphinxcontrib.htmlhelp (1.0.3) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\htmlhelp\__init__.py
#   sphinxcontrib.serializinghtml (1.1.4) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\serializinghtml\__init__.py
#   sphinxcontrib.qthelp (1.0.3) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\qthelp\__init__.py
#   alabaster (0.7.12) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\alabaster\__init__.py
#   recommonmark (0.6.0) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\recommonmark\__init__.py
#   sphinx.ext.todo (3.0.0) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\ext\todo.py
#   sphinx.ext.githubpages (3.0.0) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\ext\githubpages.py
#   sphinxcontrib.mermaid (3.0.0) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\mermaid.py
#   romnnn_sphinx_press_theme (unknown version) from c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\romnnn_sphinx_press_theme\__init__.py
Traceback (most recent call last):
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\cmd\build.py", line 280, in build_main
    app.build(args.force_all, filenames)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\application.py", line 348, in build
    self.builder.build_update()
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\builders\__init__.py", line 299, in build_update
    len(to_build))
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\builders\__init__.py", line 361, in build
    self.write(docnames, list(updated_docnames), method)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\builders\__init__.py", line 535, in write
    self._write_serial(sorted(docnames))
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\builders\__init__.py", line 545, in _write_serial
    self.write_doc(docname, doctree)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\builders\html\__init__.py", line 597, in write_doc
    self.docwriter.write(doctree, destination)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\docutils\writers\__init__.py", line 80, in write
    self.translate()
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\writers\html.py", line 71, in translate
    self.document.walkabout(visitor)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\docutils\nodes.py", line 174, in walkabout
    if child.walkabout(visitor):
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\docutils\nodes.py", line 174, in walkabout
    if child.walkabout(visitor):
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\docutils\nodes.py", line 166, in walkabout
    visitor.dispatch_visit(self)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinx\util\docutils.py", line 468, in dispatch_visit
    method(node)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\mermaid.py", line 280, in html_visit_mermaid
    render_mm_html(self, node, node['code'], node['options'])
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\mermaid.py", line 251, in render_mm_html
    fname, outfn = render_mm(self, code, options, format, prefix)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\site-packages\sphinxcontrib\mermaid.py", line 182, in render_mm
    p = Popen(mm_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "c:\users\marti\appdata\local\programs\python\python37\lib\subprocess.py", line 1178, in _execute_child
    startupinfo)
OSError: [WinError 193] %1 is not a valid Win32 application

Solution

  • Modifying the below lines by adding shell=True resolved this, credit to Martín Gaitán:

    https://github.com/mgaitan/sphinxcontrib-mermaid/blob/master/sphinxcontrib/mermaid.py#L172-L174