Detect output format in conf.py during sphinx-build documentation generation

Viewed 358

I'm adding workarounds to some of the Sphinx's problems straight into conf.py file. And I want to write code like this:

if documentation_will_be_generated_as_HTML():
    my_workaround_for_html_docs()
else:
    my_workaround_for_the_rest_of_the_formats()

How can predicate documentation_will_be_generated_as_HTML() be written for Sphinx?

P.S. I know that it's not good to make workarounds like this, and it's better to make them as extension, but deadlines are strict and tight.

2 Answers

You can check the contents of sys.argv inside conf.py to determine what buildername is being passed when you execute sphinx-build. (This is the easiest and direct approach).

What sys.argv contains depends on how you are calling sphinx-build. If you use make html basically you are calling the make file and passing the buildername html as the second argument (but the makfile will make one more change to your command-line invocation before calling sphinx-build).

Then Inside conf.py checking sys.argv[2] should contain html. (The makefile is usually generated by sphinx-quickstart and may be different between operating systems.)

An excerpt to highlight the relevant lines from a Sphinx make.bat batch file on Windows:

if "%SPHINXBUILD%" == "" (
    set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

Here's a more complicated example of running sphinx-build directly from the command-line with explicit arguments (not using the makefile), it would look like below and in this case sys.argv[3] contains the buildername.

>>> sys.argv
['C:/my_venv/Lib/site-packages/sphinx/cmd/build.py', '-E', '-b', 'html', '-d', 'build/doctrees', 'source', 'build/html']

>>> sys.argv[3]
html

In conclusion, depending on how you run Sphinx check what sys.argv contains in conf.py and write your conditions accordingly. In our example, depending on how exactly you invoke sphinx-build (or make html):

def documentation_will_be_generated_as_HTML():
    if sys.argv[3] == 'html'
        return True


if documentation_will_be_generated_as_HTML():
    my_workaround_for_html_docs()
else:
    my_workaround_for_the_rest_of_the_formats()

You can use Sphinx's application API and event handling features to determine which builder that is currently running. See https://www.sphinx-doc.org/en/master/extdev/appapi.html.

Here is what a handler for the source-read event could look like:

def workaround(app, docname, source):
    if app.builder.name == "html":
        my_workaround_for_html_docs()
    else:
        my_workaround_for_the_rest_of_the_formats()
 
def setup(app):
    app.connect("source-read", workaround)

Some other event might be more appropriate for your specific case.

Related