Skip to content

Latest commit

 

History

History
440 lines (312 loc) · 15.8 KB

cross-referencing.md

File metadata and controls

440 lines (312 loc) · 15.8 KB

(syntax/referencing)=

Cross-references

MyST-Parser offers powerful cross-referencing features, to link to URLs, documents, headers, figures and more, that are portable across output formats and generate warnings when broken.

This page covers the basics of setting up referenceable targets for content and how to reference them.

(syntax/targets)=

Creating explicit targets

Targets are used to define custom anchors that you can refer to elsewhere in your documentation.

There are three primary ways to create targets:

  1. Annotating a syntax block with (target)=
  2. Annotating a syntax bloc/inline/span with an {#id} attribute (using the attrs_block and attrs_inline extensions)
  3. Adding a name option to a directive

::::{myst-example}

(heading-target)=

Heading

{#paragraph-target} This is a paragraph, with an id attribute.

This is a [span with an id attribute]{#span-target}.

:::{note} :name: directive-target

This is a directive with a name option :::

reference1, reference2, reference3, reference4

::::

There are also other ways to create targets, specific to certain directives, such as glossaries create targets for terms, and code APIs create targets for objects:

::::{myst-example} {.glossary} my other term : Definition of the term

Link to a term

:nocontentsentry:
Docstring content

Link to a class ::::

:::{seealso} The footnotes section, covers how to create and link to footnotes, and the sphinxcontrib.bibtex extension provides a means to reference bibliographies. :::

(syntax/implicit-targets)=

Implicit targets

Whole documents can be referenced by path. Headings within documents can also be assigned an implicit target, by setting the myst_heading_anchors configuration option. This is should be set to an integer, between 1 and 6, indicating the depth of headings to assign targets to.

The anchor "slugs" are created according to the GitHub implementation: heading titles are lower cased, punctuation is removed, spaces are replaced with -, and uniqueness is enforced by suffix enumeration.

For example, using myst_heading_anchors = 2:

::::{myst-example}

A heading with slug

A heading with slug

project:#a-heading-with-slug

Explicit title ::::

For more information see the auto-generated header anchors section.

:::{warning} In general, it is discouraged to rely on implicit targets, since they are easy to break, if for example a document/heading is moved or renamed. :::

Markdown link syntax

Markdown links come in three forms:

Autolinks are URIs surrounded by < and >, which must always have a scheme:

<scheme:path?query#fragment>

Inline links allow for optional explicit text and titles (in HTML titles are rendered as tooltips):

[Explicit *Markdown* text](destination "optional explicit title")

or, if the destination contains spaces,

[Explicit *Markdown* text](<a destination> "optional explicit title")

Reference links define the destination separately in the document, and can be used multiple times:

[Explicit *Markdown* text][label]
[Another link][label]

[label]: destination "optional explicit title"

:::{seealso} The CommonMark specification :::

Default destination resolution

The destination of a link can resolve to either an external target, such as a URL to another website, or an internal target, such as a file, heading or figure within the same project.

By default, MyST will resolve link destinations according to the following rules:

  1. Destination beginning with a scheme (e.g. xxx:), will be handled according to that scheme:

    {style=lower-roman}

    1. Destinations beginning with project: will be treated as internal references
    2. Destinations beginning with path: will be treated as downloadable files
    3. Destinations beginning with inv: will be treated as intersphinx references
    4. Autolinks or destinations beginning with http:, https:, ftp:, or mailto: will be treated as external URL links.
  2. Destinations which point to a local file path are treated as links to that file.

    {style=lower-roman}

    1. If the destination is a relative path, it is resolved relative to the current file.
    2. If the destination is an absolute path (starts with /), it is resolved relative to the root of the project (i.e. the source directory).
    3. If that path relates to another document in the project (e.g. a .md or .rst file), then it will link to the first heading in that document.
    4. Links to project documents can also include a # fragment identifier, to link to a specific heading in that document.
    5. If the path is to a non-source file (e.g. a .png or .pdf file), then the link will be to the file itself, e.g. to download it.
  3. Destinations beginning with # will be treated as internal references.

    {style=lower-roman}

    1. First, explicit targets in the same file are searched for, if not found
    2. Then, implicit targets in the same file are searched for, if not found
    3. Then, explicit targets across the whole project are searched for, if not found
    4. Then, intersphinx references are searched for, if not found
    5. A warning is emitted and the destination is left as an external link.

:::{note} Local file path resolution and cross-project references are not available in single page builds :::

Explicit vs implicit link text

If the link text is explicitly given, e.g. [text](#dest), then the rendered text will be that. This text can contain nested inline markup, such as [*emphasis*](#syntax/emphasis){l=md}.

If no text is given or it is an auto-link, e.g. [](#dest) or <project:#dest>, then MyST will attempt to resolve an implicit text. For example, if the destination is a heading, then the heading text will be used as the link text, or if the destination is a figure/table then the caption will be used as the link text. Otherwise, the link text will be the destination itself.

Examples

Autolinks

:::{myst-example}

:External URL: https://example.com :Internal target reference: project:#cross-references :Internal file reference: project:../intro.md :Internal file -> heading reference: project:../intro.md#-get-started :Downloadable file: path:example.txt :Intersphinx reference: inv:sphinx:std#index

:::

Inline links with implicit text

:::{myst-example}

:External URL: :Internal target reference: :Internal file reference: :Internal file -> heading reference: :Downloadable file: :Intersphinx reference:

:::

Inline links with explicit text

:::{myst-example}

:External URL: Explicit text :Internal target reference: Explicit text :Internal file reference: Explicit text :Internal file -> heading reference: Explicit text :Downloadable file: Explicit text :Intersphinx reference: Explicit text

:::

Customising external URL resolution

:::{versionadded} 0.19 myst_url_schemes now allows for customising how the links are converted to URLs, and the attrs_inline extension can be used to specify certain links as external. :::

By default, all links which begin with http:, https:, ftp:, or mailto: will be treated as external URL links. You can customise this behaviour in a number of ways using configuration options.

Most simply, by setting the myst_all_links_external configuration option to True, all links will be treated as external URL links.

To apply selectively to specific links, you can enable the attrs_inline extension, then add an external class to the link.
For example, [my-external-link](my-external-link){.external} becomes my-external-link{.external}.

To specify a custom list of URL schemes, you can set the myst_url_schemes configuration option. By default this is set to ["http", "https", "ftp", "mailto"].

As well as being a list of strings, myst_url_schemes can also be a dictionary, where the keys are the URL schemes, and the values define how the links are converted to URLs. This allows you to customise the conversion of links to URLs for specific schemes, for example:

myst_url_schemes = {
    "http": None,
    "https": None,
    "wiki": "https://en.wikipedia.org/wiki/{{path}}#{{fragment}}",
    "doi": "https://doi.org/{{path}}",
    "gh-issue": {
        "url": "https://github.com/executablebooks/MyST-Parser/issue/{{path}}#{{fragment}}",
        "title": "Issue #{{path}}",
        "classes": ["github"],
    },
}

Allows for links such as:

  • [URI](wiki:Uniform_Resource_Identifier#URI_references) is converted to URI
  • <doi:10.1186/gm483> is converted to doi:10.1186/gm483
  • <gh-issue:639> is converted to gh-issue:639

:::{tip} You can also use the sphinx-tippy extension to add rich "hover" tooltips to links.

Adding the github class above integrates well the pydata-sphinx-theme's GitHub link formatting :::

The value of each scheme can be:

  • None: the link is converted directly to an external URL.
  • A string: the link is converted to an external URL using the string as a template.
  • A dictionary: the link is converted to an external URL using the dictionary’s url key as a template.
    • The (optional) title key is a template for the link’s implicit title, i.e. it is used if the link has no explicit title.
    • The (optional) classes key is a list of classes to add to the link.

The templates for url and title can use variables (enclosed by {{ }}), which are substituted for the corresponding parts of the link <scheme>://<netloc>/<path>;<params>?<query>#<fragment> (or the full link using uri). For example:

  • scheme: the URL scheme, e.g. wiki.
  • path: the path part of the URL, e.g. Uniform_Resource_Identifier.
  • fragment: the fragment part of the URL, e.g. URI_references.

(syntax/inv_links)=

Cross-project (intersphinx) links

:::{versionadded} 0.19 :::

Each Sphinx HTML build creates a file named objects.inv that contains a mapping from referenceable objects to URIs relative to the HTML set’s root. Each object is uniquely identified by a domain, type, and name. As well as the relative location, the object can also include implicit text for the reference (like the text for a heading).

You can use the myst-inv command line tool (installed with myst_parser) to visualise and filter any remote URL or local file path to this inventory file (or its parent):

# $ myst-inv https://www.sphinx-doc.org/en/master -n index
name: Sphinx
version: 6.2.0
base_url: https://www.sphinx-doc.org/en/master
objects:
  rst:
    role:
      index:
        loc: usage/restructuredtext/directives.html#role-index
        text: null
  std:
    doc:
      index:
        loc: index.html
        text: Welcome

To load external inventories into your Sphinx project, you must load the sphinx.ext.intersphinx extension, and set the intersphinx_mapping configuration option.

extensions = ["myst_parser", "sphinx.ext.intersphinx"]
intersphinx_mapping = {
    "sphinx": ("https://www.sphinx-doc.org/en/master", None),
}

:::{admonition} Docutils configuration :class: note dropdown

Use the docutils.conf configuration file, for more details see .

[general]
myst-inventories:
  sphinx: ["https://www.sphinx-doc.org/en/master", null]

:::

you can then reference inventory objects by prefixing the inv schema to the destination URI: inv:key:domain:type#name.

key, domain and type are optional, e.g. for inv:#name, all inventories, domains and types will be searched, with a warning emitted if multiple matches are found.

Additionally, * is a wildcard which matches zero or characters, e.g. inv:*:std:doc#a* will match all std:doc objects in all inventories, with a name beginning with a. Note, to match to a literal * use \*.

Here are some examples:

:::{list-table} :header-rows: 1

    • Type
    • Syntax
    • Rendered
    • Autolink, full
    • <inv:sphinx:std:doc#index>{l=myst}
    • inv:sphinx:std:doc#index
    • Link, full
    • [Sphinx](inv:sphinx:std:doc#index){l=myst}
    • Sphinx
    • Autolink, no type
    • <inv:sphinx:std#index>{l=myst}
    • inv:sphinx:std#index
    • Autolink, no domain
    • <inv:sphinx:*:doc#index>{l=myst}
    • inv:sphinx:*:doc#index
    • Autolink, only name
    • <inv:#*.Sphinx>{l=myst}
    • inv:#*.Sphinx

:::

Reference roles

Sphinx offers numerous roles for referencing specific objects.

These can also within MyST documents, although it is recommended to use the Markdown syntax where possible, which is more portable and native to MyST.

:::{myst-example}

  • {ref}syntax/referencing, {ref}Explicit text <syntax/referencing>
  • {term}my other term
  • {doc}../intro, {doc}Explicit text <../intro>
  • {download}example.txt, {download}Explicit text <example.txt>
  • {py:class}mypackage.MyClass, {py:class}Explicit text <mypackage.MyClass>
  • {external:class}sphinx.application.Sphinx, {external:class}Explicit text <sphinx.application.Sphinx>
  • {external+sphinx:ref}code-examples, {external+sphinx:ref}Explicit text <code-examples>

:::

Handling invalid references

When building your documentation, it is recommended to run in nitpicky mode, which will emit warnings for any invalid references.

you may encounter warnings such as:

intro.md:1: WARNING: 'myst' cross-reference target not found: 'reference' [myst.xref_missing]

intro.md:2: WARNING: Multiple matches found for 'duplicate': inter:py:module:duplicate, inter:std:label:duplicate [myst.iref_ambiguous]

To fully suppress a specific warning type, you can use the suppress_warnings configuration option, in Sphinx’s conf.py file:

suppress_warnings = ["myst.xref_missing", "myst.iref_ambiguous"]

or in docutils.conf or command-line tool:

[general]
myst-suppress-warnings = myst.xref_missing, myst.iref_ambiguous

In Sphinx specific reference warnings can also be suppressed, using the inv:sphinx#nitpick_ignore and inv:sphinx#nitpick_ignore_regex configuration options.

nitpick_ignore = [("myst", "reference")]

To handle ambiguous references, for intersphinx references see the section, or the domains searched for all Markdown references can be restricted globally or per-document using the myst_ref_domains configuration.

myst_ref_domains = ["std", "py"]