python-sphinxrestructuredtext

How to prevent sphinx replacing upper-case letters with lower-case in the target of a cross-reference?


This came to be, because I am currently changing our old documentation to a new one using sphinx. The old documentation used t2t files in which I have a lot of references written with capital letters in it. I converted the t2t to rst and had to make some adaptions, so most of it works. But one issue is unresolved: Sphinx changes capital letters of reference targets to lowercase when converting to .tex files, but not the ones from the hyperrefs.

Now i have converted my testfile.t2t to testfile.rst, also using some scripts and most of it works. The problem is sphinx-build changes a reference target like:

.. _test-ONE:

to a lower case version:

\label{\detokenize{testfile:test-one}}

but the references within the text itself stays the same with its capital letters, like:

`test_ONE <#test-ONE>`__ 

becomes:

{\hyperref[\detokenize{testfile:test-ONE}]{\sphinxsamedocref{test_ONE}}}

As a result, the hyper-refs don't work.

(This conversion also happens for html output)

Now I was thinking writing a script, that just changes all the links of the .rst file to lowercase would be too much and there must be a simple solution using sphinx itself, but I haven't found any by myself that works.

So I either need sphinx to prevent converting the targets to lowercase OR to also convert the hyperrefs to lowercase.

...

I found one solution stating that I should add the following to my conf.py, which prevents sphinx from converting to lower case, but it didn't work:

latex_elements = {
    'preamble': r'''
        \usepackage{textcase}
        \let\MakeUppercase\relax
        \let\MakeTextUppercase\relax
    '''

I have not found a solution that converts the hyperrefs to lowercase.


Solution

  • The downcasing of reference names is a reStructuredText feature.

    The problem is not limited to LaTeX, in HTML it would be:

    <p id="test-one">The problem is sphinx-build changes a reference target
    to a lower case version.</p>
    <p>The references within the text itself stays the same
    with its capital letters,
    like: <a class="reference external" href="#test-ONE">test_ONE</a>.</p>
    

    The solution is to replace the embedded URI reference with an embedded alias (this also helps for references with characters that are not supported in an ID):

    The references within the text are normalized, too,
    if they use an alias 
    like: `see the first test <test-ONE_>`__.
    

    If the reference text and the reference name are identic, there is no need to embed a target (backticks are optional with simple references):

    Use the reference name (with any casing) 
    in a simple reference or reference phrase, 
    like test-one_, `Test-one`_ or `test-ONE`_.