Use version number in file links in Sphinx

1.9k views Asked by At

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?

2

There are 2 answers

1
Subbdue On BEST ANSWER

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.

0
Torxed On

The above doesn't work for PDF's as mentioned, a workaround for PDF's would be to lean in on the power of LaTeX without too much complexity.

In your config.py, we'll add a LaTeX function called \versionLink:

__version__ = 0.1 # Just an example of how to get it into the latex string dynamically
latex_prlog = rf"""
\newcommand{{\versionLink}}{{domain.local/name_of_file.{__version__}.min.js}}
"""

All it will do, is output a link text that you want to show.

We need to escape { and } by doing {{ and }} if we're using formatted strings, since LaTeX uses those for function definitions. (If you don't need string formatting, just don't use f"" and omit the double {{ }} and use { } instead.)

Then, in our documentation, we can generate links with:

.. This is needed, to be able to do inline latex:
.. role:: raw-latex(raw)
   :format: latex

Here's a version link :raw-latex:`\url{https://\versionLink}`.
It will have the same color throughout.

The ..role:: raw-latex(raw) just enables you to do inline LaTeX. And with that you can do \url{https://\versionLink} inline in your text. Tested with make latexpdf.