Search code examples
versioningpython-sphinx

Use version number in file links in Sphinx


In Sphinx, file links can be generated using the following syntax:

`name_of_file.js <some/location/name_of_file.js>`_

In the conf.py file, a version variable is defined that we can use in the .rst files like such:

|version|

Including the version into the file link using that syntax is not allowed:

`name_of_file.|version|.min.js <some/location/name_of_file.|version|.min.js>`_

So, how can I generate links to files named something like name_of_file.<version_num>.min.js and use the version number from conf.py?


Solution

  • I had a need for something similar and after much experimentation I have a workaround for this. Be warned, this is a crummy solution but it works.

    The short answer:

    You need to split the parts of the link to left and right of |version| and use raw html along with the |version|. Your .rst will look like this:

    Example of a link with version in it |link-pre|\ |version|\ |link-post|
    
    .. |link-pre| raw:: html
    
        <a href="some/location/name_of_file.
    
    .. |link-post| raw:: html
    
        .min.js">name_of_file.min.js</a>
    

    The long answer

    There are a couple of hurdles we need to overcome:

    Problem 1: Now, |version| is essentially a substitution definition. When you use a substitution reference in your document, it has to lead with a space like so |version|.

    So even in a regular rsT sentence, which is not a link, you can't do name_of_file.|version|.min.js. You will need to do name_of_file.\ |version|.min.js, i.e, escape the space with a \

    Problem 2: Nested inline markup is not supported in reST: http://docutils.sourceforge.net/FAQ.html#is-nested-inline-markup-possible

    So you can't make a substitution, |version|, within a link \`name_of_file.|version|.min.js`\. This is why we have to use raw-html and break it into parts, and we create 2 more substitution definitions |link-pre| and |link-post|, which will be replaced with their raw-html in the generated output.

    I tried using inline :raw-html: role but that did not help, so unfortunately the solution turned out to be verbose.