diff --git a/docs/faq/index.md b/docs/faq/index.md index 55333e34..aed98f38 100644 --- a/docs/faq/index.md +++ b/docs/faq/index.md @@ -54,7 +54,7 @@ The [MyST-NB](https://myst-nb.readthedocs.io) tool provides a Sphinx extension f ### Include a file from outside the docs folder (like README.md) :::{seealso} -[...](#organising-content/include) + ::: You can include a file, including one from outside the project using e.g.: @@ -118,7 +118,7 @@ See [](#syntax/implicit-targets) for this information. ### Suppress warnings -See [...](#myst-warnings) for this information. +See for this information. ### Sphinx-specific page front matter diff --git a/docs/intro.md b/docs/intro.md index 8308ec36..92772bae 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -107,7 +107,7 @@ There are a range of great HTML themes that work well with MyST, such as [sphinx ## Configuring MyST-Parser -The [...](configuration.md) section contains a complete list of configuration options for the MyST-Parser. +The section contains a complete list of configuration options for the MyST-Parser. These can be applied globally, e.g. in the sphinx `conf.py`: diff --git a/docs/syntax/code_and_apis.md b/docs/syntax/code_and_apis.md index 1f53d685..771b843d 100644 --- a/docs/syntax/code_and_apis.md +++ b/docs/syntax/code_and_apis.md @@ -170,7 +170,7 @@ Sphinx and MyST provide means to analyse source code and automatically generate As opposed to `sphinx.ext.autodoc`, `sphinx-autodoc2` performs static (rather than dynamic) analysis of the source code, integrates full package documenting, and also allows for docstrings to be written in both RestructureText and MyST. -The `auto_mode` will automatically generate the full API documentation, as shown [...](/apidocs/index.rst). +The `auto_mode` will automatically generate the full API documentation, as shown . Alternatively, the `autodoc2-object` directive can be used to generate documentation for a single object. To embed in a MyST document the MyST `render_plugin` should be specified, for example: diff --git a/docs/syntax/cross-referencing.md b/docs/syntax/cross-referencing.md index aedd77c2..c9e47705 100644 --- a/docs/syntax/cross-referencing.md +++ b/docs/syntax/cross-referencing.md @@ -78,7 +78,7 @@ For example, using `myst_heading_anchors = 2`: ## A heading with slug -[...](#a-heading-with-slug) + [Explicit title](#a-heading-with-slug-1) :::: @@ -136,25 +136,31 @@ or an **internal** target, such as a file, heading or figure within the same pro By default, MyST will resolve link destinations according to the following rules: -1. Destinations beginning with `inv:` will be treated as links to intersphinx references ([see below](#syntax/inv_links)). +1. Destination beginning with a scheme (e.g. `xxx:`), will be handled according to that scheme: -2. Autolinks or destinations beginning with `http:`, `https:`, `ftp:`, or `mailto:` will be treated as external [URL] links. + {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. -3. Destinations which point to a local file path are treated as links to that file. +2. 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. + {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. -4. Destinations beginning with `#` will be treated as internal references. +3. Destinations beginning with `#` will be treated as internal references. - - First, explicit target 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. + {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](#myst-docutils) @@ -162,48 +168,52 @@ Local file path resolution and cross-project references are not available in [si ### Explicit vs implicit link text -If the link text is explicitly given, e.g. `[text](dest)`, then the link text will be the given 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 or `...` is given, e.g. `[](dest)` or `[...](dest)`, then MyST will attempt to resolve an implicit text. +If no text is given or it is an auto-link, e.g. `[](#dest)` or ``, 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. -### Some examples +### Examples -Here are some examples: +#### Autolinks -:::{list-table} -:header-rows: 1 +:::{myst-example} -* - Type - - Syntax - - Rendered +:External URL: +:Internal target reference: +:Internal file reference: +:Internal file -> heading reference: +:Downloadable file: +:Intersphinx reference: -* - Autolink - - `` - - +::: + +#### Inline links with implicit text + +:::{myst-example} -* - External URL - - `[example.com](https://example.com)` - - [example.com](https://example.com) +: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) -* - Document file - - `[Source file](../intro.md)` - - [Source file](../intro.md) +::: -* - Non-document file - - `[Non-source file](example.txt)` - - [Non-source file](example.txt) +#### Inline links with explicit text -* - Local heading - - `[...](#cross-references)` - - [...](#cross-references) +:::{myst-example} -* - Heading in other file - - `[Heading](../intro.md#installation)` - - [Heading](../intro.md#installation) +: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) ::: @@ -341,23 +351,23 @@ Here are some examples: - Rendered * - Autolink, full - - `` + - ``{l=myst} - * - Link, full - - `[Sphinx](inv:sphinx:std:doc#index)` + - `[Sphinx](inv:sphinx:std:doc#index)`{l=myst} - [Sphinx](inv:sphinx:std:doc#index) * - Autolink, no type - - `` + - ``{l=myst} - * - Autolink, no domain - - `` + - ``{l=myst} - * - Autolink, only name - - `` + - ``{l=myst} - ::: @@ -371,21 +381,21 @@ These can also within MyST documents, although it is recommended to use the Mark :::{myst-example} - {ref}`syntax/referencing`, {ref}`Explicit text ` - {term}`my other term` -- {doc}`../intro` -- {download}`example.txt` -- {py:class}`mypackage.MyClass` -- {external:class}`sphinx.application.Sphinx` -- {external+sphinx:ref}`code-examples` +- {doc}`../intro`, {doc}`Explicit text <../intro>` +- {download}`example.txt`, {download}`Explicit text ` +- {py:class}`mypackage.MyClass`, {py:class}`Explicit text ` +- {external:class}`sphinx.application.Sphinx`, {external:class}`Explicit text ` +- {external+sphinx:ref}`code-examples`, {external+sphinx:ref}`Explicit text ` --- -- [...][syntax], [Explicit text][syntax] -- [...](<#my other term>) -- [...](../intro.md) -- [...](example.txt) -- [...](#mypackage.MyClass) -- [...](#sphinx.application.Sphinx), [...](inv:#*Sphinx) -- [...](inv:sphinx#code-examples) +- , [][syntax], [Explicit text][syntax] +- [](<#my other term>) +- , [Explicit text](../intro.md) +- , [Explicit text](example.txt) +- , [Explicit text](#mypackage.MyClass) +- , [Explicit text](#sphinx.application.Sphinx) +- , [Explicit text](inv:sphinx#code-examples) [syntax]: #syntax/referencing ::: diff --git a/docs/syntax/images_and_figures.md b/docs/syntax/images_and_figures.md index 8aada76d..3fb093ce 100644 --- a/docs/syntax/images_and_figures.md +++ b/docs/syntax/images_and_figures.md @@ -119,7 +119,7 @@ figclass : text :::::{seealso} -See the [...](#syntax/md-figures) section for information on how to create figures that use native Markdown images. +See the section for information on how to create figures that use native Markdown images. ::::{myst-example} :::{figure-md} diff --git a/myst_parser/_docs.py b/myst_parser/_docs.py index db2df873..7a39244c 100644 --- a/myst_parser/_docs.py +++ b/myst_parser/_docs.py @@ -107,7 +107,6 @@ def field_type(field): class MystConfigDirective(_ConfigBase): - option_spec = { "sphinx": directives.flag, "extensions": directives.flag, @@ -120,7 +119,6 @@ def run(self): text = self.table_header() count = 0 for name, value, field in config.as_triple(): - if field.metadata.get("deprecated"): continue @@ -378,7 +376,7 @@ def run(self): # TODO when some more work and testing, this should be made available publicly from pygments import token # noqa: E402 -from pygments.lexer import bygroups, inherit # noqa: E402 +from pygments.lexer import bygroups, inherit, this, using # noqa: E402 from pygments.lexers.markup import MarkdownLexer # noqa: E402 @@ -412,12 +410,12 @@ class MystLexer(MarkdownLexer): ), # :name: value ( - r"^(\:)([^\n]+)(\:)([^\n]+)(\n)", + r"^(\:)([^\n\:]+)(\:)([^\n]+)(\n)", bygroups( token.Punctuation, - token.Name.Label, + token.Generic.Strong, token.Punctuation, - token.Text, + using(this, state="inline"), token.Text, ), ), @@ -429,7 +427,18 @@ class MystLexer(MarkdownLexer): # {name} ( r"(\{)([a-zA-Z0-9+:-]+)(\})", - bygroups(token.Punctuation, token.Name.Label, token.Punctuation), + bygroups(token.Punctuation, token.Operator.Word, token.Punctuation), + ), + # + ( + r"(<)(http|https|mailto|project|path|inv)(\:)([^\s>]+)(>)", + bygroups( + token.Punctuation, + token.String.Other, + token.String.Other, + token.Name.Label, + token.Punctuation, + ), ), inherit, ], diff --git a/myst_parser/mdit_to_docutils/base.py b/myst_parser/mdit_to_docutils/base.py index 61c8d72d..5b893cb6 100644 --- a/myst_parser/mdit_to_docutils/base.py +++ b/myst_parser/mdit_to_docutils/base.py @@ -887,46 +887,49 @@ def render_heading(self, token: SyntaxTreeNode) -> None: def render_link(self, token: SyntaxTreeNode) -> None: """Parse `` or `[text](link "title")` syntax to docutils AST: - - If `myst_all_links_external` is True, forward to `render_external_url` + - If `myst_all_links_external` is True, forward to `render_link_url` - If the link token has a class attribute containing `external`, - forward to `render_external_url` - - If the link is an id link (e.g. `#id`), forward to `render_id_link` + forward to `render_link_url` + - If the link is an id link (e.g. `#id`), forward to `render_link_anchor` - If the link has a schema, and the schema is in `url_schemes` (e.g. `http:`), - forward to `render_external_url` - - If the link has an `inv:` schema, - forward to `render_inventory_link` - - If the link is an autolink/linkify type link, forward to `render_external_url` - - Otherwise, forward to `render_internal_link` + forward to `render_link_url` + - If the link has an `inv:` schema, forward to `render_link_inventory` + - If the link is an autolink/linkify type link, forward to `render_link_url` + - Otherwise, forward to `render_link_internal` """ if ( self.md_config.commonmark_only or self.md_config.gfm_only or self.md_config.all_links_external ): - return self.render_external_url(token) + return self.render_link_url(token) if "class" in token.attrs and "external" in str(token.attrs["class"]).split(): - return self.render_external_url(token) + return self.render_link_url(token) href = cast(str, token.attrGet("href") or "") if href.startswith("#"): - return self.render_id_link(token) + return self.render_link_anchor(token, href) scheme_match = REGEX_SCHEME.match(href) scheme = None if scheme_match is None else scheme_match.group(1) if scheme in self.md_config.url_schemes: - return self.render_external_url(token, self.md_config.url_schemes[scheme]) + return self.render_link_url(token, self.md_config.url_schemes[scheme]) if scheme == "inv": - return self.render_inventory_link(token) + return self.render_link_inventory(token) + if scheme == "path": + return self.render_link_path(token) + if scheme == "project": + return self.render_link_project(token) if token.info == "auto": - # handles both autolink and linkify, these are currently never internal - return self.render_external_url(token) + # handles both autolink and linkify + return self.render_link_url(token) - return self.render_internal_link(token) + return self.render_link_unknown(token) - def render_external_url( + def render_link_url( self, token: SyntaxTreeNode, conversion: None | UrlSchemeType = None ) -> None: """Render link token (including autolink and linkify), @@ -986,21 +989,49 @@ def render_external_url( with self.current_node_context(ref_node, append=True): self.render_children(token) - def render_id_link(self, token: SyntaxTreeNode) -> None: - """Render link token like `[text](#id)`, to a local target.""" + def render_link_path(self, token: SyntaxTreeNode) -> None: + """Render a link token like ``.""" + self.create_warning( + "`path:` scheme not yet supported in docutils", + MystWarnings.NOT_SUPPORTED, + line=token_line(token, 0), + append_to=self.current_node, + ) + return self.render_link_url(token) + + def render_link_project(self, token: SyntaxTreeNode) -> None: + """Render a link token like ``.""" + destination = cast(str, token.attrGet("href") or "") + if destination.startswith("project:"): + destination = destination[8:] + if destination.startswith("#"): + return self.render_link_anchor(token, destination) + self.create_warning( + "`project:` scheme for file paths not yet supported in docutils", + MystWarnings.NOT_SUPPORTED, + line=token_line(token, 0), + append_to=self.current_node, + ) + return self.render_link_url(token) + + def render_link_anchor(self, token: SyntaxTreeNode, target: str) -> None: + """Render link token like `[text](#target)`, to a local target. + + :target: the target id, e.g. `#target` + """ ref_node = nodes.reference() self.add_line_and_source_path(ref_node, token) ref_node["id_link"] = True - ref_node["refuri"] = self.md.normalizeLinkText(str(token.attrGet("href") or "")) + ref_node["refuri"] = self.md.normalizeLinkText(target) self.copy_attributes( token, ref_node, ("class", "id", "reftitle"), aliases={"title": "reftitle"} ) self.current_node.append(ref_node) - if token.info != "auto" and not is_ellipsis(token): + if token.info != "auto": with self.current_node_context(ref_node): self.render_children(token) - def render_internal_link(self, token: SyntaxTreeNode) -> None: + def render_link_unknown(self, token: SyntaxTreeNode) -> None: """Render link token `[text](link "title")`, where the link has not been identified as an external URL:: @@ -1021,7 +1052,7 @@ def render_internal_link(self, token: SyntaxTreeNode) -> None: with self.current_node_context(ref_node, append=True): self.render_children(token) - def render_inventory_link(self, token: SyntaxTreeNode) -> None: + def render_link_inventory(self, token: SyntaxTreeNode) -> None: r"""Create a link to an inventory object. This assumes the href is of the form `:#`. @@ -1037,9 +1068,7 @@ def render_inventory_link(self, token: SyntaxTreeNode) -> None: href = self.md.normalizeLinkText(cast(str, token.attrGet("href") or "")) # note if the link had explicit text or not (autolinks are always implicit) - explicit = ( - (token.info != "auto") and bool(token.children) and not is_ellipsis(token) - ) + explicit = (token.info != "auto") and bool(token.children) # split the href up into parts uri_parts = urlparse(href) @@ -1938,12 +1967,3 @@ def compute_unique_slug( slug = f"{slug}-{i}" i += 1 return slug - - -def is_ellipsis(token: SyntaxTreeNode) -> bool: - """Check if a token content only contains an ellipsis.""" - return ( - len(token.children) == 1 - and token.children[0].type == "text" - and token.children[0].content in ("...", "…") - ) diff --git a/myst_parser/mdit_to_docutils/sphinx_.py b/myst_parser/mdit_to_docutils/sphinx_.py index 36497194..71942aff 100644 --- a/myst_parser/mdit_to_docutils/sphinx_.py +++ b/myst_parser/mdit_to_docutils/sphinx_.py @@ -4,7 +4,6 @@ import os from pathlib import Path from typing import cast -from urllib.parse import unquote from uuid import uuid4 from docutils import nodes @@ -16,7 +15,8 @@ from sphinx.util import logging from myst_parser import inventory -from myst_parser.mdit_to_docutils.base import DocutilsRenderer, is_ellipsis +from myst_parser.mdit_to_docutils.base import DocutilsRenderer, token_line +from myst_parser.warnings_ import MystWarnings LOGGER = logging.getLogger(__name__) @@ -32,21 +32,103 @@ class SphinxRenderer(DocutilsRenderer): def sphinx_env(self) -> BuildEnvironment: return self.document.settings.env - def render_internal_link(self, token: SyntaxTreeNode) -> None: - """Render link token `[text](link "title")`, - where the link has not been identified as an external URL. - """ - destination = unquote(cast(str, token.attrGet("href") or "")) + def _process_wrap_node( + self, + wrap_node: nodes.Element, + token: SyntaxTreeNode, + explicit: bool, + classes: list[str], + path_dest: str, + ): + """Process a wrap node, which is a node that wraps a link.""" + self.add_line_and_source_path(wrap_node, token) + self.copy_attributes(token, wrap_node, ("class", "id", "title")) + self.current_node.append(wrap_node) + + if explicit: + inner_node = nodes.inline("", "", classes=classes) + with self.current_node_context(inner_node): + self.render_children(token) + elif isinstance(wrap_node, addnodes.download_reference): + inner_node = nodes.literal(path_dest, path_dest, classes=classes) + else: + inner_node = nodes.inline("", "", classes=classes) - # make the path relative to an "including" document - # this is set when using the `relative-docs` option of the MyST `include` directive + wrap_node.append(inner_node) + + def _handle_relative_docs(self, destination: str) -> str: + """Make the path relative to an "including" document + + This is set when using the `relative-docs` option of the MyST `include` directive + """ relative_include = self.md_env.get("relative-docs", None) if relative_include is not None and destination.startswith(relative_include[0]): source_dir, include_dir = relative_include[1:] destination = os.path.relpath( os.path.join(include_dir, os.path.normpath(destination)), source_dir ) - explicit = len(token.children or []) > 0 and not is_ellipsis(token) + return destination + + def render_link_project(self, token: SyntaxTreeNode) -> None: + destination = cast(str, token.attrGet("href") or "") + if destination.startswith("project:"): + destination = destination[8:] + if destination.startswith("#"): + return self.render_link_anchor(token, destination) + + if not self.sphinx_env.srcdir: # not set in some test situations + return self.render_link_url(token) + + destination = self.md.normalizeLinkText(destination) + destination = self._handle_relative_docs(destination) + path_dest, *_path_ids = destination.split("#", maxsplit=1) + path_id = _path_ids[0] if _path_ids else None + explicit = (token.info != "auto") and (len(token.children or []) > 0) + _, abs_path = self.sphinx_env.relfn2path(path_dest, self.sphinx_env.docname) + docname = self.sphinx_env.path2doc(abs_path) + if not docname: + self.create_warning( + f"Could not find document: {abs_path}", + MystWarnings.XREF_MISSING, + line=token_line(token, 0), + append_to=self.current_node, + ) + return self.render_link_url(token) + wrap_node = addnodes.pending_xref( + refdomain="doc", + reftarget=docname, + reftargetid=path_id, + refdoc=self.sphinx_env.docname, + reftype="myst", + refexplicit=explicit, + ) + classes = ["xref", "myst"] + self._process_wrap_node(wrap_node, token, explicit, classes, destination) + + def render_link_path(self, token: SyntaxTreeNode) -> None: + destination = self.md.normalizeLinkText(cast(str, token.attrGet("href") or "")) + if destination.startswith("path:"): + destination = destination[5:] + destination = self._handle_relative_docs(destination) + explicit = (token.info != "auto") and (len(token.children or []) > 0) + wrap_node = addnodes.download_reference( + refdomain=None, + reftarget=destination, + refdoc=self.sphinx_env.docname, + reftype="myst", + refexplicit=explicit, + ) + classes = ["xref", "download", "myst"] + self._process_wrap_node(wrap_node, token, explicit, classes, destination) + + def render_link_unknown(self, token: SyntaxTreeNode) -> None: + """Render link token `[text](link "title")`, + where the link has not been identified as an external URL. + """ + destination = self.md.normalizeLinkText(cast(str, token.attrGet("href") or "")) + destination = self._handle_relative_docs(destination) + + explicit = (token.info != "auto") and (len(token.children or []) > 0) kwargs = { "refdoc": self.sphinx_env.docname, "reftype": "myst", @@ -55,24 +137,11 @@ def render_internal_link(self, token: SyntaxTreeNode) -> None: path_dest, *_path_ids = destination.split("#", maxsplit=1) path_id = _path_ids[0] if _path_ids else None - potential_path: None | Path - if path_dest.startswith("/"): - # here we are referencing a file relative to the source directory - potential_path = Path(self.sphinx_env.srcdir) / path_dest[1:] - elif path_dest == "./": - # this is a special case, where we want to reference the current document - potential_path = ( - Path(self.sphinx_env.doc2path(self.sphinx_env.docname)) - if self.sphinx_env.srcdir - else None - ) - else: - potential_path = ( - Path(self.sphinx_env.doc2path(self.sphinx_env.docname)).parent - / path_dest - if self.sphinx_env.srcdir # not set in some test situations - else None - ) + potential_path: None | Path = None + if self.sphinx_env.srcdir: # not set in some test situations + _, path_str = self.sphinx_env.relfn2path(path_dest, self.sphinx_env.docname) + potential_path = Path(path_str) + if potential_path and potential_path.is_file(): docname = self.sphinx_env.path2doc(str(potential_path)) if docname: @@ -91,20 +160,7 @@ def render_internal_link(self, token: SyntaxTreeNode) -> None: ) classes = ["xref", "myst"] - self.add_line_and_source_path(wrap_node, token) - self.copy_attributes(token, wrap_node, ("class", "id", "title")) - self.current_node.append(wrap_node) - - if explicit: - inner_node = nodes.inline("", "", classes=classes) - with self.current_node_context(inner_node): - self.render_children(token) - elif isinstance(wrap_node, addnodes.download_reference): - inner_node = nodes.literal(path_dest, path_dest, classes=classes) - else: - inner_node = nodes.inline("", "", classes=classes) - - wrap_node.append(inner_node) + self._process_wrap_node(wrap_node, token, explicit, classes, path_dest) def get_inventory_matches( self, diff --git a/myst_parser/warnings_.py b/myst_parser/warnings_.py index 2666f758..fc54024a 100644 --- a/myst_parser/warnings_.py +++ b/myst_parser/warnings_.py @@ -12,6 +12,8 @@ class MystWarnings(Enum): DEPRECATED = "deprecated" """Deprecated usage.""" + NOT_SUPPORTED = "not_supported" + """Functionality that is not yet supported in docutils.""" RENDER_METHOD = "render" """The render method is not implemented.""" diff --git a/tests/test_renderers/fixtures/docutil_link_resolution.md b/tests/test_renderers/fixtures/docutil_link_resolution.md index f5e39e74..e686e17c 100644 --- a/tests/test_renderers/fixtures/docutil_link_resolution.md +++ b/tests/test_renderers/fixtures/docutil_link_resolution.md @@ -18,7 +18,7 @@ [missing] . [](#test) -[...](#test) + [explicit](#test) [](<#name with spaces>) . @@ -59,7 +59,7 @@ ## Non-anchor heading [](#title) -[...](#longer-title-with-nested-syntax) + [explicit](#title) . @@ -94,7 +94,7 @@ # Test [](#target) -[...](#target) + [explicit](#target) . @@ -165,7 +165,7 @@ c | d ``` [](#table) -[...](#table) + [explicit](#table) . diff --git a/tests/test_renderers/fixtures/sphinx_link_resolution.md b/tests/test_renderers/fixtures/sphinx_link_resolution.md index d8616b38..e624b97a 100644 --- a/tests/test_renderers/fixtures/sphinx_link_resolution.md +++ b/tests/test_renderers/fixtures/sphinx_link_resolution.md @@ -18,7 +18,7 @@ [missing] . [](#test) -[...](#test) + [explicit](#test) . @@ -41,7 +41,7 @@ ## Non-anchor heading [](#title) -[...](#longer-title-with-nested-syntax) + [explicit](#title) . @@ -76,7 +76,7 @@ # Test [](#target) -[...](#target) + [explicit](#target) [](<#name with spaces>) . @@ -151,7 +151,7 @@ c | d ``` [](#table) -[...](#table) + [explicit](#table) . @@ -193,7 +193,7 @@ c | d [external-file] . [](test.txt) -[...](./test.txt) + [relative to source dir](/test.txt) . @@ -214,7 +214,7 @@ c | d [source-file] . [](other.rst) -[...](./other.rst) + [relative to source dir](/other.rst) . diff --git a/tests/test_sphinx/sourcedirs/references/index.md b/tests/test_sphinx/sourcedirs/references/index.md index ac1f0de0..74d0fd6a 100644 --- a/tests/test_sphinx/sourcedirs/references/index.md +++ b/tests/test_sphinx/sourcedirs/references/index.md @@ -45,7 +45,7 @@ subfolder/other2.md [](#title-anchors) -[](./#title-anchors) + [](./other.md#title-anchors) 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 20056086..58d73540 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_references.resolved.xml +++ b/tests/test_sphinx/test_sphinx_builds/test_references.resolved.xml @@ -98,7 +98,7 @@ Title anchors - + Title anchors diff --git a/tests/test_sphinx/test_sphinx_builds/test_references.xml b/tests/test_sphinx/test_sphinx_builds/test_references.xml index 68eca0cd..5069acec 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_references.xml +++ b/tests/test_sphinx/test_sphinx_builds/test_references.xml @@ -83,8 +83,9 @@ Title anchors - - + + + Title anchors