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.
1. 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:
Annotating a syntax block with
(target)=
Annotating a syntax block/inline/span with an
{#id}
attribute (using the attrs_block and attrs_inline extensions)Adding a
name
option to a directive
(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](#heading-target), [reference2](#paragraph-target),
[reference3](#span-target), [reference4](#directive-target)
Heading
This is a paragraph, with an id
attribute.
This is a span with an id
attribute.
备注
This is a directive with a name
option
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:
{.glossary}
my other term
: Definition of the term
[Link to a term](<#my other term>)
```{py:class} mypackage.MyClass
:nocontentsentry:
Docstring content
```
[Link to a class](#mypackage.MyClass)
- my other term
Definition of the term
- class mypackage.MyClass#
Docstring content
参见
The footnotes section, covers how to create and link to footnotes, and the sphinxcontrib.bibtex extension provides a means to reference bibliographies.
2. 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
:
## A heading with slug
## A heading with slug
<project:#a-heading-with-slug>
[Explicit title](#a-heading-with-slug-1)
For more information see the auto-generated header anchors section.
警告
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.
3. 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"
参见
3.1. 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:
Destination beginning with a scheme (e.g.
xxx:
), will be handled according to that scheme:Destinations beginning with
project:
will be treated as internal referencesDestinations beginning with
path:
will be treated as downloadable filesDestinations beginning with
inv:
will be treated as intersphinx referencesAutolinks or destinations beginning with
http:
,https:
,ftp:
, ormailto:
will be treated as external URL links.
Destinations which point to a local file path are treated as links to that file.
If the destination is a relative path, it is resolved relative to the current file.
If the destination is an absolute path (starts with
/
), it is resolved relative to the root of the project (i.e. the source directory).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.Links to project documents can also include a
#
fragment identifier, to link to a specific heading in that document.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.
Destinations beginning with
#
will be treated as internal references.First, explicit targets in the same file are searched for, if not found
Then, implicit targets in the same file are searched for, if not found
Then, explicit targets across the whole project are searched for, if not found
Then, intersphinx references are searched for, if not found
A warning is emitted and the destination is left as an external link.
备注
Local file path resolution and cross-project references are not available in single page builds
3.2. 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)
.
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.
3.3. Examples#
Autolinks#
: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>
- External URL:
- Internal target reference:
- Internal file reference:
- Internal file -> heading reference:
- Downloadable file:
- Intersphinx reference:
Inline links with implicit text#
:External URL: [](https://example.com)
:Internal target reference: [](#cross-references)
:Internal file reference: [](../intro.md)
:Internal file -> heading reference: [](../intro.md#-get-started)
:Downloadable file: [](example.txt)
:Intersphinx reference: [](inv:sphinx:std#index)
- External URL:
- Internal target reference:
- Internal file reference:
- Internal file -> heading reference:
- Downloadable file:
- Intersphinx reference:
Inline links with explicit text#
:External URL: [Explicit text](https://example.com)
:Internal target reference: [Explicit text](#cross-references)
:Internal file reference: [Explicit text](../intro.md)
:Internal file -> heading reference: [Explicit text](../intro.md#-get-started)
:Downloadable file: [Explicit text](example.txt)
:Intersphinx reference: [Explicit text](inv:sphinx:std#index)
- External URL:
- Internal target reference:
- Internal file reference:
- Internal file -> heading reference:
- Downloadable file:
- Intersphinx reference:
3.4. Customising external URL resolution#
Added in version 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.
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 Issue #639
小技巧
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
.
3.5. Cross-project (intersphinx) links#
Added in version 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),
}
Docutils configuration
Use the docutils.conf
configuration file, for more details see Single Page Builds.
[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 more 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:
Type |
Syntax |
Rendered |
---|---|---|
Autolink, full |
|
|
Link, full |
|
|
Autolink, no type |
|
|
Autolink, no domain |
|
|
Autolink, only name |
|
4. 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.
- {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>`
---
- <project:#syntax/referencing>, [][syntax], [Explicit text][syntax]
- [](<#my other term>)
- <project:../intro.md>, [Explicit text](../intro.md)
- <path:example.txt>, [Explicit text](example.txt)
- <project:#mypackage.MyClass>, [Explicit text](#mypackage.MyClass)
- <inv:#*Sphinx>, [Explicit text](#sphinx.application.Sphinx)
- <inv:sphinx#code-examples>, [Explicit text](inv:sphinx#code-examples)
[syntax]: #syntax/referencing
5. 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 nitpick_ignore
and nitpick_ignore_regex
configuration options.
nitpick_ignore = [("myst", "reference")]
To handle ambiguous references,
for intersphinx references see the Cross-project (intersphinx) links 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"]