blockdiag / nwdiag

Apache License 2.0
115 stars 18 forks source link

Exception combining Sphinx nwdiag `:caption:` directive with `:figwidth: image` #31

Open ncoghlan opened 2 years ago

ncoghlan commented 2 years ago

When I try to use the nwdiag :caption: directive in Sphinx, the associated blockdiag method throws an exception claiming that fontpath isn't defined, even though fontpath, blockdiag_fontpath, and nwdiag_fontpath are all set.

It looks like global_options is supposed to be set by calling the setup functions in the respective modules, but nothing ever seems to actually call those (adding a sys.exit() call didn't terminate the Sphinx run early)

# Sphinx version: 3.3.1
# Python version: 3.5.10 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 2.11.2
# Last messages:
[snip]
# Loaded extensions:
#   recommonmark (0.6.0)
#   alabaster (0.7.12)
#   sphinxcontrib.qthelp (1.0.3)
#   sphinx.ext.autodoc (3.3.1)
#   sphinxcontrib.blockdiag (2.0.1)
#   sphinx.ext.mathjax (3.3.1)
#   sphinxcontrib.serializinghtml (1.1.4)
#   sphinxcontrib.actdiag (2.0.0)
#   sphinxcontrib.packetdiag (2.0.0)
#   sphinxcontrib.devhelp (1.0.2)
#   sphinxcontrib.rackdiag (2.0.0)
#   sphinxcontrib.applehelp (1.0.2)
#   sphinxcontrib.htmlhelp (1.0.3)
#   sphinx.ext.autodoc.type_comment (3.3.1)
#   sphinxcontrib.nwdiag (2.0.0)
#   sphinxcontrib.seqdiag (2.0.0)
Traceback (most recent call last):
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/cmd/build.py", line 280, in build_main
    app.build(args.force_all, filenames)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/application.py", line 352, in build
    self.builder.build_update()
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/builders/__init__.py", line 299, in build_update
    len(to_build))
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/builders/__init__.py", line 311, in build
    updated_docnames = set(self.read())
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/builders/__init__.py", line 418, in read
    self._read_serial(docnames)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/builders/__init__.py", line 439, in _read_serial
    self.read_doc(docname)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/builders/__init__.py", line 479, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/io.py", line 223, in read_doc
    pub.publish()
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/core.py", line 218, in publish
    self.settings)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/io.py", line 128, in read
    self.parse()
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/readers/__init__.py", line 77, in parse
    self.parser.parse(self.input, document)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/sphinx/parsers.py", line 102, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 171, in run
    input_source=document['source'])
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/statemachine.py", line 242, in run
    context, state, transitions)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/statemachine.py", line 242, in run
    context, state, transitions)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/statemachine.py", line 242, in run
    context, state, transitions)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2097, in directive
    directive_class, match, type_name, option_presets)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/blockdiag/utils/rst/directives.py", line 54, in decorator
    return fn(*args)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/blockdiag/utils/rst/directives.py", line 195, in run
    width = self.get_actual_width(node, diagram)
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/blockdiag/utils/rst/directives.py", line 226, in get_actual_width
    fontmap = self.create_fontmap()
  File "/home/ncoghlan/.local/share/virtualenvs/.../lib/python3.5/site-packages/blockdiag/utils/rst/directives.py", line 276, in create_fontmap
    fontpath = self.global_options['fontpath']
KeyError: 'fontpath'
ncoghlan commented 2 years ago

Looking at https://www.sphinx-doc.org/en/master/extdev/appapi.html#extension-setup it seems the setup function certainly should be getting called, so I'm going to close as almost certainly indicating that there is something wrong with my build environment.

ncoghlan commented 2 years ago

Reopening, as I had misunderstood which setup functions Sphinx called automatically - it only calls the setup hooks in the sphinxcontrib submodules, not the ones in the directives implementation modules.

ncoghlan commented 2 years ago

Checking behaviour with and without the :caption: directive, it's clear that without the caption specified, get_actual_width() never gets called. Looking at the code then shows that the error is specific to the case where the figure width is set to the special value "image".

So my workaround is to avoid that dynamic sizing setting.