diff --git a/myst_parser/mdit_to_docutils/base.py b/myst_parser/mdit_to_docutils/base.py index 7f3d3c6a..f95105fa 100644 --- a/myst_parser/mdit_to_docutils/base.py +++ b/myst_parser/mdit_to_docutils/base.py @@ -1065,8 +1065,7 @@ def render_inventory_link(self, token: SyntaxTreeNode) -> None: # create the docutils node match = matches[0] - ref_node = nodes.reference() - ref_node["internal"] = False + ref_node = nodes.reference("", "", internal=False) ref_node["inv_match"] = inventory.filter_string( match.inv, match.domain, match.otype, match.name ) diff --git a/myst_parser/mdit_to_docutils/sphinx_.py b/myst_parser/mdit_to_docutils/sphinx_.py index 8f65f446..4e7aee1d 100644 --- a/myst_parser/mdit_to_docutils/sphinx_.py +++ b/myst_parser/mdit_to_docutils/sphinx_.py @@ -83,13 +83,13 @@ def render_internal_link(self, token: SyntaxTreeNode) -> None: text = "" else: wrap_node = addnodes.download_reference( - refdomain=None, reftarget=path_dest, refwarn=False, **kwargs + refdomain=None, reftarget=path_dest, **kwargs ) classes = ["xref", "download", "myst"] text = destination if not token.children else "" else: wrap_node = addnodes.pending_xref( - refdomain=None, reftarget=destination, refwarn=True, **kwargs + refdomain=None, reftarget=destination, **kwargs ) classes = ["xref", "myst"] text = "" diff --git a/myst_parser/mdit_to_docutils/transforms.py b/myst_parser/mdit_to_docutils/transforms.py index b193ebdc..3cf03bb8 100644 --- a/myst_parser/mdit_to_docutils/transforms.py +++ b/myst_parser/mdit_to_docutils/transforms.py @@ -116,7 +116,6 @@ def apply(self, **kwargs: t.Any) -> None: refdomain=None, reftype="myst", reftarget=target, - refwarn=True, refexplicit=bool(refnode.children), ) inner_node = nodes.inline( diff --git a/myst_parser/sphinx_ext/myst_refs.py b/myst_parser/sphinx_ext/myst_refs.py index 514e0507..e00afc4d 100644 --- a/myst_parser/sphinx_ext/myst_refs.py +++ b/myst_parser/sphinx_ext/myst_refs.py @@ -3,33 +3,30 @@ This is applied to MyST type references only, such as ``[text](target)``, and allows for nested syntax """ +from __future__ import annotations + import re -from typing import Any, List, Optional, Tuple, cast +from typing import Any, cast from docutils import nodes from docutils.nodes import Element, document +from markdown_it.common.normalize_url import normalizeLink from sphinx import addnodes from sphinx.addnodes import pending_xref from sphinx.domains.std import StandardDomain from sphinx.errors import NoUri -from sphinx.locale import __ +from sphinx.ext.intersphinx import InventoryAdapter from sphinx.transforms.post_transforms import ReferencesResolver from sphinx.util import docname_join, logging from sphinx.util.nodes import clean_astext, make_refnode +from myst_parser import inventory from myst_parser._compat import findall from myst_parser.warnings_ import MystWarnings LOGGER = logging.getLogger(__name__) -def log_warning(msg: str, subtype: MystWarnings, **kwargs: Any): - """Log a warning, with a myst type and specific subtype.""" - LOGGER.warning( - msg + f" [myst.{subtype.value}]", type="myst", subtype=subtype.value, **kwargs - ) - - class MystReferenceResolver(ReferencesResolver): """Resolves cross-references on doctrees. @@ -38,6 +35,41 @@ class MystReferenceResolver(ReferencesResolver): default_priority = 9 # higher priority than ReferencesResolver (10) + def log_warning( + self, target: None | str, msg: str, subtype: MystWarnings, **kwargs: Any + ): + """Log a warning, with a myst type and specific subtype.""" + + # MyST references are warned about by default (the same as the `any` role) + # However, warnings can also be ignored by adding ("myst", target) + # nitpick_ignore/nitpick_ignore_regex lists + # https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-nitpicky + if ( + target + and self.config.nitpick_ignore + and ("myst", target) in self.config.nitpick_ignore + ): + return + if ( + target + and self.config.nitpick_ignore_regex + and any( + ( + re.fullmatch(ignore_type, "myst") + and re.fullmatch(ignore_target, target) + ) + for ignore_type, ignore_target in self.config.nitpick_ignore_regex + ) + ): + return + + LOGGER.warning( + msg + f" [myst.{subtype.value}]", + type="myst", + subtype=subtype.value, + **kwargs, + ) + def run(self, **kwargs: Any) -> None: self.document: document for node in findall(self.document)(addnodes.pending_xref): @@ -48,41 +80,45 @@ def run(self, **kwargs: Any) -> None: self.resolve_myst_ref_doc(node) continue - contnode = cast(nodes.TextElement, node[0].deepcopy()) newnode = None - + contnode = cast(nodes.TextElement, node[0].deepcopy()) target = node["reftarget"] refdoc = node.get("refdoc", self.env.docname) + search_domains: None | list[str] = self.env.config.myst_ref_domains + # try to resolve the reference within the local project, + # this asks all domains to resolve the reference, + # return None if no domain could resolve the reference + # or returns the first result, and logs a warning if + # multiple domains resolved the reference try: - newnode = self.resolve_myst_ref_any(refdoc, node, contnode) - if newnode is None: - # no new node found? try the missing-reference event - # but first we change the the reftype to 'any' - # this means it is picked up by extensions like intersphinx - node["reftype"] = "any" - try: - newnode = self.app.emit_firstresult( - "missing-reference", - self.env, - node, - contnode, - allowed_exceptions=(NoUri,), - ) - finally: - node["reftype"] = "myst" - if newnode is None: - # still not found? warn if node wishes to be warned about or - # we are in nit-picky mode - self._warn_missing_reference(target, node) + newnode = self.resolve_myst_ref_any( + refdoc, node, contnode, search_domains + ) except NoUri: newnode = contnode + if newnode is None: + # If no local domain could resolve the reference, try to + # resolve it as an inter-sphinx reference + newnode = self._resolve_myst_ref_intersphinx( + node, contnode, target, search_domains + ) + if newnode is None: + # if still not resolved, log a warning, + self.log_warning( + target, + f"'myst' cross-reference target not found: {target!r}", + MystWarnings.XREF_MISSING, + location=node, + ) + # if the target could not be found, then default to using an external link if not newnode: newnode = nodes.reference() - newnode["refid"] = target + newnode["refid"] = normalizeLink(target) newnode.append(node[0].deepcopy()) + # ensure the output node has some content if ( len(newnode.children) == 1 and isinstance(newnode[0], nodes.inline) @@ -94,46 +130,17 @@ def run(self, **kwargs: Any) -> None: node.replace_self(newnode) - def _warn_missing_reference(self, target: str, node: pending_xref) -> None: - """Warn about a missing reference.""" - dtype = "myst" - if not node.get("refwarn"): - return - if ( - self.config.nitpicky - and self.config.nitpick_ignore - and (dtype, target) in self.config.nitpick_ignore - ): - return - if ( - self.config.nitpicky - and self.config.nitpick_ignore_regex - and any( - ( - re.fullmatch(ignore_type, dtype) - and re.fullmatch(ignore_target, target) - ) - for ignore_type, ignore_target in self.config.nitpick_ignore_regex - ) - ): - return - - log_warning( - f"'myst' cross-reference target not found: {target!r}", - MystWarnings.XREF_MISSING, - location=node, - ) - def resolve_myst_ref_doc(self, node: pending_xref): """Resolve a reference, from a markdown link, to another document, optionally with a target id within that document. """ from_docname = node.get("refdoc", self.env.docname) ref_docname: str = node["reftarget"] - ref_id: Optional[str] = node["reftargetid"] + ref_id: str | None = node["reftargetid"] if ref_docname not in self.env.all_docs: - log_warning( + self.log_warning( + ref_docname, f"Unknown source document {ref_docname!r}", MystWarnings.XREF_MISSING, location=node, @@ -148,7 +155,8 @@ def resolve_myst_ref_doc(self, node: pending_xref): if ref_id: slug_to_section = self.env.metadata[ref_docname].get("myst_slugs", {}) if ref_id not in slug_to_section: - log_warning( + self.log_warning( + ref_id, f"local id not found in doc {ref_docname!r}: {ref_id!r}", MystWarnings.XREF_MISSING, location=node, @@ -176,9 +184,13 @@ def resolve_myst_ref_doc(self, node: pending_xref): node.replace_self(ref_node) def resolve_myst_ref_any( - self, refdoc: str, node: pending_xref, contnode: Element - ) -> Element: - """Resolve reference generated by the "myst" role; ``[text](reference)``. + self, + refdoc: str, + node: pending_xref, + contnode: Element, + only_domains: None | list[str], + ) -> Element | None: + """Resolve reference generated by the "myst" role; ``[text](#reference)``. This builds on the sphinx ``any`` role to also resolve: @@ -189,7 +201,7 @@ def resolve_myst_ref_any( """ target: str = node["reftarget"] - results: List[Tuple[str, Element]] = [] + results: list[tuple[str, Element]] = [] # resolve standard references res = self._resolve_ref_nested(node, refdoc) @@ -201,13 +213,10 @@ def resolve_myst_ref_any( if res: results.append(("std:doc", res)) - # get allowed domains for referencing - ref_domains = self.env.config.myst_ref_domains - assert self.app.builder # next resolve for any other standard reference objects - if ref_domains is None or "std" in ref_domains: + if only_domains is None or "std" in only_domains: stddomain = cast(StandardDomain, self.env.get_domain("std")) for objtype in stddomain.object_types: key = (objtype, target) @@ -225,7 +234,7 @@ def resolve_myst_ref_any( for domain in self.env.domains.values(): if domain.name == "std": continue # we did this one already - if ref_domains is not None and domain.name not in ref_domains: + if only_domains is not None and domain.name not in only_domains: continue try: results.extend( @@ -237,7 +246,8 @@ def resolve_myst_ref_any( # the domain doesn't yet support the new interface # we have to manually collect possible references (SLOW) if not (getattr(domain, "__module__", "").startswith("sphinx.")): - log_warning( + self.log_warning( + None, f"Domain '{domain.__module__}::{domain.name}' has not " "implemented a `resolve_any_xref` method", MystWarnings.LEGACY_DOMAIN, @@ -260,11 +270,10 @@ def stringify(name, node): return f":{name}:`{reftitle}`" candidates = " or ".join(stringify(name, role) for name, role in results) - log_warning( - __( - f"more than one target found for 'myst' cross-reference {target}: " - f"could be {candidates}" - ), + self.log_warning( + target, + f"more than one target found for 'myst' cross-reference {target}: " + f"could be {candidates}", MystWarnings.XREF_AMBIGUOUS, location=node, ) @@ -283,7 +292,7 @@ def stringify(name, node): def _resolve_ref_nested( self, node: pending_xref, fromdocname: str, target=None - ) -> Optional[Element]: + ) -> Element | None: """This is the same as ``sphinx.domains.std._resolve_ref_xref``, but allows for nested syntax, rather than converting the inner node to raw text. """ @@ -311,7 +320,7 @@ def _resolve_ref_nested( def _resolve_doc_nested( self, node: pending_xref, fromdocname: str - ) -> Optional[Element]: + ) -> Element | None: """This is the same as ``sphinx.domains.std._resolve_doc_xref``, but allows for nested syntax, rather than converting the inner node to raw text. @@ -332,3 +341,58 @@ def _resolve_doc_nested( assert self.app.builder return make_refnode(self.app.builder, fromdocname, docname, "", innernode) + + def _resolve_myst_ref_intersphinx( + self, + node: nodes.Element, + contnode: nodes.Element, + target: str, + only_domains: list[str] | None, + ) -> None | nodes.reference: + """Resolve a myst reference to an intersphinx inventory.""" + matches = [ + m + for m in inventory.filter_sphinx_inventories( + InventoryAdapter(self.env).named_inventory, + targets=target, + ) + if only_domains is None or m.domain in only_domains + ] + if not matches: + return None + if len(matches) > 1: + # log a warning if there are multiple matches + show_num = 3 + matches_str = ", ".join( + [ + inventory.filter_string(m.inv, m.domain, m.otype, m.name) + for m in matches[:show_num] + ] + ) + if len(matches) > show_num: + matches_str += ", ..." + self.log_warning( + target, + f"Multiple matches found for {target!r}: {matches_str}", + MystWarnings.IREF_AMBIGUOUS, + location=node, + ) + # get the first match and create a reference node + match = matches[0] + newnode = nodes.reference("", "", internal=False, refuri=match.loc) + if "reftitle" in node: + newnode["reftitle"] = node["reftitle"] + else: + newnode["reftitle"] = f"{match.project} {match.version}".strip() + if node.get("refexplicit"): + newnode.append(contnode) + elif match.text: + newnode.append( + contnode.__class__(match.text, match.text, classes=["iref", "myst"]) + ) + else: + newnode.append( + contnode.__class__(match.name, match.name, classes=["iref", "myst"]) + ) + + return newnode diff --git a/tests/test_renderers/fixtures/sphinx_link_resolution.md b/tests/test_renderers/fixtures/sphinx_link_resolution.md index 85577ff2..85120769 100644 --- a/tests/test_renderers/fixtures/sphinx_link_resolution.md +++ b/tests/test_renderers/fixtures/sphinx_link_resolution.md @@ -23,13 +23,13 @@ . - + - + - + explicit . @@ -97,7 +97,7 @@ explicit - + . @@ -198,14 +198,14 @@ c | d . - + test.txt - + - + relative to source dir . diff --git a/tests/test_renderers/fixtures/sphinx_syntax_elements.md b/tests/test_renderers/fixtures/sphinx_syntax_elements.md index 2cca93bf..542f2422 100644 --- a/tests/test_renderers/fixtures/sphinx_syntax_elements.md +++ b/tests/test_renderers/fixtures/sphinx_syntax_elements.md @@ -400,7 +400,7 @@ Link Definition in directive: - + a . @@ -424,7 +424,7 @@ Link Definition in nested directives: - + ref1 @@ -769,6 +769,6 @@ a = 1 a = 1 - + . diff --git a/tests/test_sphinx/sourcedirs/references/conf.py b/tests/test_sphinx/sourcedirs/references/conf.py index 099510ac..99419a66 100644 --- a/tests/test_sphinx/sourcedirs/references/conf.py +++ b/tests/test_sphinx/sourcedirs/references/conf.py @@ -1,3 +1,9 @@ -extensions = ["myst_parser"] +extensions = ["myst_parser", "sphinx.ext.intersphinx"] exclude_patterns = ["_build"] myst_heading_anchors = 2 + +intersphinx_mapping = { + "inter": ("https://example.com", "objects.inv"), +} + +nitpick_ignore = [("myst", "unknown")] diff --git a/tests/test_sphinx/sourcedirs/references/index.md b/tests/test_sphinx/sourcedirs/references/index.md index c31bedbf..ac1f0de0 100644 --- a/tests/test_sphinx/sourcedirs/references/index.md +++ b/tests/test_sphinx/sourcedirs/references/index.md @@ -52,3 +52,18 @@ subfolder/other2.md [](other.md#title-anchors) [](subfolder/other2.md#title-anchors) + + +# Intersphinx via `#` + +Unknown [](#unknown) + +Unknown explicit [**hallo**](#unknown) + +Known no title [](#paragraph-target) + +Known explicit [**hallo**](#paragraph-target) + +Known with title [](#title-target) + +Ambiguous [](#duplicate) diff --git a/tests/test_sphinx/sourcedirs/references/objects.inv b/tests/test_sphinx/sourcedirs/references/objects.inv new file mode 100644 index 00000000..51ef5f81 --- /dev/null +++ b/tests/test_sphinx/sourcedirs/references/objects.inv @@ -0,0 +1,6 @@ +# Sphinx inventory version 2 +# Project: Example +# Version: 0.0.1 +# The remainder of this file is compressed using zlib. +xڅA +0E9E@.^`L$MŸce1}@y6<8Ž5J7ۑ)1HuZÉXOJ-szf'ɛb\%+j0|ޜBtHˮ6vWuv5\y^E1yx 4v?1fT J. \ No newline at end of file diff --git a/tests/test_sphinx/test_sphinx_builds.py b/tests/test_sphinx/test_sphinx_builds.py index 8ede05d7..b5b9acc6 100644 --- a/tests/test_sphinx/test_sphinx_builds.py +++ b/tests/test_sphinx/test_sphinx_builds.py @@ -90,8 +90,12 @@ def test_references( app.build() assert "build succeeded" in status.getvalue() # Build succeeded - warnings = warning.getvalue().strip() - assert warnings == "" + # should be one warning: + # WARNING: Multiple matches found for 'duplicate': + # inter:py:module:duplicate, inter:std:label:duplicate [myst.iref_ambiguous] + warnings = warning.getvalue().strip().splitlines() + assert len(warnings) == 1 + assert "[myst.iref_ambiguous]" in warnings[0] try: get_sphinx_app_doctree(app, docname="index", regress=True) diff --git a/tests/test_sphinx/test_sphinx_builds/test_basic.xml b/tests/test_sphinx/test_sphinx_builds/test_basic.xml index a3a1b65d..72397484 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_basic.xml +++ b/tests/test_sphinx/test_sphinx_builds/test_basic.xml @@ -35,7 +35,7 @@ Title with - <pending_xref refdoc="content" refdomain="True" refexplicit="True" reftarget="target2" reftype="myst" refwarn="True"> + <pending_xref refdoc="content" refdomain="True" refexplicit="True" reftarget="target2" reftype="myst"> <inline classes="xref myst"> link <paragraph> diff --git a/tests/test_sphinx/test_sphinx_builds/test_references.html b/tests/test_sphinx/test_sphinx_builds/test_references.html index 63297b93..666196dd 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_references.html +++ b/tests/test_sphinx/test_sphinx_builds/test_references.html @@ -190,6 +190,73 @@ <h2> </p> </section> </section> + <section class="tex2jax_ignore mathjax_ignore" id="intersphinx-via"> + <h1> + Intersphinx via + <code class="docutils literal notranslate"> + <span class="pre"> + # + </span> + </code> + <a class="headerlink" href="#intersphinx-via" title="Permalink to this heading"> + ¶ + </a> + </h1> + <p> + Unknown + <a class="reference internal" href="#unknown"> + <code class="xref myst docutils literal notranslate"> + <span class="pre"> + unknown + </span> + </code> + </a> + </p> + <p> + Unknown explicit + <a class="reference internal" href="#unknown"> + <span class="xref myst"> + <strong> + hallo + </strong> + </span> + </a> + </p> + <p> + Known no title + <a class="reference external" href="https://example.com/index.html#paragraph-target" title="Example 0.0.1"> + <span class="iref myst"> + paragraph-target + </span> + </a> + </p> + <p> + Known explicit + <a class="reference external" href="https://example.com/index.html#paragraph-target" title="Example 0.0.1"> + <span class="xref myst"> + <strong> + hallo + </strong> + </span> + </a> + </p> + <p> + Known with title + <a class="reference external" href="https://example.com/index.html#title-target" title="Example 0.0.1"> + <span class="iref myst"> + Title + </span> + </a> + </p> + <p> + Ambiguous + <a class="reference external" href="https://example.com/index.html#module-duplicate" title="Example 0.0.1"> + <span class="iref myst"> + duplicate + </span> + </a> + </p> + </section> </div> </div> </div> diff --git a/tests/test_sphinx/test_sphinx_builds/test_references.resolved.xml b/tests/test_sphinx/test_sphinx_builds/test_references.resolved.xml index 957af06c..b539bf39 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_references.resolved.xml +++ b/tests/test_sphinx/test_sphinx_builds/test_references.resolved.xml @@ -47,13 +47,13 @@ <emphasis> syntax <paragraph> - <download_reference filename="ab0d698fdd2b6a81c34b5ed380fe6f61/file_link.txt" refdoc="index" refdomain="True" refexplicit="True" reftarget="file_link.txt" reftype="myst" refwarn="False"> + <download_reference filename="ab0d698fdd2b6a81c34b5ed380fe6f61/file_link.txt" refdoc="index" refdomain="True" refexplicit="True" reftarget="file_link.txt" reftype="myst"> <inline classes="xref download myst"> download <strong> link <paragraph> - <download_reference filename="1952147a8403903cb78cecf56f049085/file_link2.txt" refdoc="index" refdomain="True" refexplicit="False" reftarget="subfolder/file_link2.txt" reftype="myst" refwarn="False"> + <download_reference filename="1952147a8403903cb78cecf56f049085/file_link2.txt" refdoc="index" refdomain="True" refexplicit="False" reftarget="subfolder/file_link2.txt" reftype="myst"> <inline classes="xref download myst"> subfolder/file_link2.txt <target refid="insidecodeblock"> @@ -113,3 +113,40 @@ <reference internal="True" refuri="subfolder/other2.html#title-anchors"> <inline classes="std std-ref"> Title anchors + <section classes="tex2jax_ignore mathjax_ignore" ids="intersphinx-via" names="intersphinx\ via\ #" slug="intersphinx-via-"> + <title> + Intersphinx via + <literal> + # + <paragraph> + Unknown + <reference refid="unknown"> + <literal classes="xref myst"> + unknown + <paragraph> + Unknown explicit + <reference refid="unknown"> + <inline classes="xref myst"> + <strong> + hallo + <paragraph> + Known no title + <reference internal="False" reftitle="Example 0.0.1" refuri="https://example.com/index.html#paragraph-target"> + <inline classes="iref myst"> + paragraph-target + <paragraph> + Known explicit + <reference internal="False" reftitle="Example 0.0.1" refuri="https://example.com/index.html#paragraph-target"> + <inline classes="xref myst"> + <strong> + hallo + <paragraph> + Known with title + <reference internal="False" reftitle="Example 0.0.1" refuri="https://example.com/index.html#title-target"> + <inline classes="iref myst"> + Title + <paragraph> + Ambiguous + <reference internal="False" reftitle="Example 0.0.1" refuri="https://example.com/index.html#module-duplicate"> + <inline classes="iref myst"> + duplicate diff --git a/tests/test_sphinx/test_sphinx_builds/test_references.xml b/tests/test_sphinx/test_sphinx_builds/test_references.xml index 4cb99ad3..b6fcdc9e 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_references.xml +++ b/tests/test_sphinx/test_sphinx_builds/test_references.xml @@ -19,14 +19,14 @@ <emphasis> syntax <paragraph> - <pending_xref refdoc="index" refdomain="True" refexplicit="False" reftarget="title" reftype="myst" refwarn="True"> + <pending_xref refdoc="index" refdomain="True" refexplicit="False" reftarget="title" reftype="myst"> <inline classes="xref myst"> <paragraph> - <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="title" reftype="myst" refwarn="True"> + <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="title" reftype="myst"> <inline classes="xref myst"> plain text <paragraph> - <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="title" reftype="myst" refwarn="True"> + <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="title" reftype="myst"> <inline classes="xref myst"> nested <emphasis> @@ -45,13 +45,13 @@ <emphasis> syntax <paragraph> - <download_reference filename="ab0d698fdd2b6a81c34b5ed380fe6f61/file_link.txt" refdoc="index" refdomain="True" refexplicit="True" reftarget="file_link.txt" reftype="myst" refwarn="False"> + <download_reference filename="ab0d698fdd2b6a81c34b5ed380fe6f61/file_link.txt" refdoc="index" refdomain="True" refexplicit="True" reftarget="file_link.txt" reftype="myst"> <inline classes="xref download myst"> download <strong> link <paragraph> - <download_reference filename="1952147a8403903cb78cecf56f049085/file_link2.txt" refdoc="index" refdomain="True" refexplicit="False" reftarget="subfolder/file_link2.txt" reftype="myst" refwarn="False"> + <download_reference filename="1952147a8403903cb78cecf56f049085/file_link2.txt" refdoc="index" refdomain="True" refexplicit="False" reftarget="subfolder/file_link2.txt" reftype="myst"> <inline classes="xref download myst"> subfolder/file_link2.txt <target refid="insidecodeblock"> @@ -68,7 +68,7 @@ insidecodeblock <paragraph> I am outside the - <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="insidecodeblock" reftype="myst" refwarn="True"> + <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="insidecodeblock" reftype="myst"> <inline classes="xref myst"> fence <section ids="title-anchors" names="title\ anchors" slug="title-anchors"> @@ -94,3 +94,36 @@ <paragraph> <pending_xref refdoc="index" refdomain="doc" refexplicit="False" reftarget="subfolder/other2" reftargetid="title-anchors" reftype="myst"> <inline classes="xref myst"> + <section classes="tex2jax_ignore mathjax_ignore" ids="intersphinx-via" names="intersphinx\ via\ #" slug="intersphinx-via-"> + <title> + Intersphinx via + <literal> + # + <paragraph> + Unknown + <pending_xref refdoc="index" refdomain="True" refexplicit="False" reftarget="unknown" reftype="myst"> + <inline classes="xref myst"> + <paragraph> + Unknown explicit + <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="unknown" reftype="myst"> + <inline classes="xref myst"> + <strong> + hallo + <paragraph> + Known no title + <pending_xref refdoc="index" refdomain="True" refexplicit="False" reftarget="paragraph-target" reftype="myst"> + <inline classes="xref myst"> + <paragraph> + Known explicit + <pending_xref refdoc="index" refdomain="True" refexplicit="True" reftarget="paragraph-target" reftype="myst"> + <inline classes="xref myst"> + <strong> + hallo + <paragraph> + Known with title + <pending_xref refdoc="index" refdomain="True" refexplicit="False" reftarget="title-target" reftype="myst"> + <inline classes="xref myst"> + <paragraph> + Ambiguous + <pending_xref refdoc="index" refdomain="True" refexplicit="False" reftarget="duplicate" reftype="myst"> + <inline classes="xref myst">