How to make an internal link to a heading in sphinx restructuredtext without creating arbitrary labels?

20,394

Solution 1

reStructuredText supports implicit hyperlink targets. From the reStructuredText quick reference:

Section titles, footnotes, and citations automatically generate hyperlink targets (the title text or footnote/citation label is used as the hyperlink name).

So the following text (lifted from the reStructuredText quick reference, spelling mistakes and all):

Titles are targets, too
=======================
Implict references, like `Titles are targets, too`_.

produces HTML similar to the following:

<strong><a name="title">Titles are targets, too</a></strong>

<p>Implict references, like <a href="#title">Titles are targets, too</a>.</p>

Solution 2

New, better answer for 2016!

The autosection extension lets you do this easily, with real cross references.

=============
Some Document
=============


Internal Headline
=================

then, later...

===============
Some Other Doc
===============


A link-  :ref:`Internal Headline`

This extension is built-in, so all you need is to edit conf.py

extensions = [
    .
    . other
    . extensions
    . already
    . listed
    .
    'sphinx.ext.autosectionlabel',
]

The only thing you have to be careful of is that now you can't duplicate internal headlines across the doc collection. (Worth it.)

Solution 3

A small addition to the answer by Chris:

If you want to link to headings without using the exact name of that heading for the link, you can do it like this:

Titles are targets, too
=======================

See `here <#titles-are-targets-too>`_

This will render as:

<h1 id="titles-are-targets-too">Titles are targets, too</h1>

<p>See <a href="#titles-are-targets-too">here</a></p>

Solution 4

Using the headline text isn't a good choice. Headlines may change or might get corrected. There is now easy way to figure out who many and where links are broken after a change.

Using ref is advised over standard reStructuredText links to sections (like `Section title`_) because it works across files, when section headings are changed, will raise warnings if incorrect, and works for all builders that support cross-references.
Source: https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-ref

Using the sphinx.ext.autosectionlabel extension as proposed by Adam Michael Wood is at least a more structured approach then using implicitly defined anchors as proposed by Chris.


You should use explicit linking with references and symbolic target names (like LaTeX does since ages.)

  1. Use .. _refname: to create a target.
  2. Use :ref:`refname` to reference the target.

If a target is followed by a headline, this headline will be used als link text.

Share:
20,394
caduceus
Author by

caduceus

Updated on December 29, 2020

Comments

  • caduceus
    caduceus over 3 years

    I have a document with many headings and sub-headings. Further into the text I want to link back to one of the headings. How can I do this without the redundancy of :ref: labels? The contents seems to pick up headers just fine. I was hoping for something like this: `#polled-data-retrieval`_.

  • Mad Physicist
    Mad Physicist over 6 years
    Thank you. I kept thinking this was always enabled by default, couldn't figure out why some of my refs weren't working.
  • rvf
    rvf over 4 years
    A minor addition: :ref:`Short link <Very long headline that clutters your text otherwise>` is possible as well
  • Paebbels
    Paebbels over 4 years
    Using the headline text isn't a good choice. Headlines may change or might get corrected. There is now easy way to figure out who many and where links are broken after a change. You should use explicit linking with references (like LaTeX does since ages.)
  • Cecil Curry
    Cecil Curry about 4 years
    This is the most general-purpose answer. Most answers assume Sphinx, which is certainly fair enough for a question referencing Sphinx. Since Sphinx fails to apply to generic reStructuredText documents (e.g., README.rst in GitHub or GitLab repositories), however, answers assuming Sphinx-specific :ref: syntax fail to generalize. See also this authoritative answer elsewhere.
  • The Godfather
    The Godfather over 3 years
    Reading the first part of the answer I'm thinking "yeah, makes sense" but... when are the examples, how should one actually use it?
  • Peilonrayz
    Peilonrayz over 3 years
    @CecilCurry Unless you need the output to work in something that isn't a browser.
  • TheClem
    TheClem almost 3 years
    This option worked for me, thank you! However, it is not compatible with sphinx_togglebutton extension. Do you have any suggestion on it or should I compose a new question about it?