From fc64840b5f009021d64173d81c2f244fb0d8a43d Mon Sep 17 00:00:00 2001 From: Marjus Cako Date: Fri, 5 Jan 2024 18:13:26 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=8C=20IMPROVE:=20External=20links=20in?= =?UTF-8?q?=20new=20tab=20(#856)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support to enable external links to open in a new tab. Expose the configuration option myst_links_external_new_tab, which if set will set all URL links to open in a new tab on the browser. Besides that, we allow the user to set the target and rel attributes when using the extension inline_attrs (#820). Closes #820 Closes #856 Signed-off-by: Marjus Cako --- myst_parser/config/main.py | 8 ++++++++ myst_parser/mdit_to_docutils/base.py | 6 +++++- tests/test_renderers/fixtures/myst-config.txt | 20 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/myst_parser/config/main.py b/myst_parser/config/main.py index ae29dfad..a3faceb1 100644 --- a/myst_parser/config/main.py +++ b/myst_parser/config/main.py @@ -233,6 +233,14 @@ def __repr__(self) -> str: }, ) + links_external_new_tab: bool = dc.field( + default=False, + metadata={ + "validator": instance_of(bool), + "help": "Open all external links in a new tab", + }, + ) + url_schemes: Dict[str, Optional[UrlSchemeType]] = dc.field( default_factory=lambda: { "http": None, diff --git a/myst_parser/mdit_to_docutils/base.py b/myst_parser/mdit_to_docutils/base.py index 4a02459d..c4e59aed 100644 --- a/myst_parser/mdit_to_docutils/base.py +++ b/myst_parser/mdit_to_docutils/base.py @@ -952,8 +952,12 @@ def render_link_url( """ ref_node = nodes.reference() self.add_line_and_source_path(ref_node, token) + attribute_keys = ["class", "id", "reftitle", "target", "rel"] + if self.md_config.links_external_new_tab: + token.attrs["target"] = "_blank" + token.attrs["rel"] = "noreferer noopener" self.copy_attributes( - token, ref_node, ("class", "id", "reftitle"), aliases={"title": "reftitle"} + token, ref_node, attribute_keys, aliases={"title": "reftitle"} ) uri = cast(str, token.attrGet("href") or "") implicit_text: str | None = None diff --git a/tests/test_renderers/fixtures/myst-config.txt b/tests/test_renderers/fixtures/myst-config.txt index e0e69305..ccac6ea0 100644 --- a/tests/test_renderers/fixtures/myst-config.txt +++ b/tests/test_renderers/fixtures/myst-config.txt @@ -301,6 +301,10 @@ a [ref]{#id3 .e .f} [ref]: https://example.com + +[text3](https://example.com){target="g"} + +[text4](https://example.com){rel="h"} . @@ -319,6 +323,12 @@ a ref + + + text3 + + + text4 . [attrs_inline_image] --myst-enable-extensions=attrs_inline @@ -507,3 +517,13 @@ content :1: (WARNING/2) Unknown directive type: 'unknown' [myst.directive_unknown] :6: (WARNING/2) 'admonition': Unknown option keys: ['a'] (allowed: ['class', 'name']) [myst.directive_parse] . + +[links-external-new-tab] --myst-links-external-new-tab="true" +. +[text](https://example.com) +. + + + + text +.