Hyperlink 在Sphinx/reStructuredText中添加“在新选项卡中打开”链接

Hyperlink 在Sphinx/reStructuredText中添加“在新选项卡中打开”链接,hyperlink,python-sphinx,restructuredtext,Hyperlink,Python Sphinx,Restructuredtext,以下是针对同一问题的解决方案: 但是,当文档有很多链接时(特别是当链接位于表中时),此解决方案将无法正常工作 还有其他解决办法吗?谢谢你的帮助 如果希望在新选项卡中打开外部链接,请将以下代码添加到您的conf.py: from sphinx.writers.html import HTMLTranslator class PatchedHTMLTranslator(HTMLTranslator): def visit_reference(self, node): if nod

以下是针对同一问题的解决方案:

但是,当文档有很多链接时(特别是当链接位于表中时),此解决方案将无法正常工作


还有其他解决办法吗?谢谢你的帮助

如果希望在新选项卡中打开外部链接,请将以下代码添加到您的
conf.py

from sphinx.writers.html import HTMLTranslator
class PatchedHTMLTranslator(HTMLTranslator):
   def visit_reference(self, node):
      if node.get('newtab') or not (node.get('target') or node.get('internal') 
         or 'refuri' not in node):
            node['target'] = '_blank'
            super().visit_reference(node)

def setup(app):
    app.set_translator('html', PatchedHTMLTranslator)
这还使您能够将newtab参数用于引用,使其显示为内部,但在新选项卡中打开。我用它来链接幻灯片PDF

来源:

要添加
target=“\u blank”
但也要将
rel=“noopener noreferrer”
添加到外部链接,需要复制Sphinx的整个
访问
方法来修补此链接:

atts['target'] = '_blank'
atts['rel'] = 'noopener noreferrer'
Sphinx的原始代码不处理
rel
属性,人们可能会像
node['rel']='noopener noreferrer'
那样设置该属性,但它确实应用了
target
属性(
atts['target']=node['target']

下面是我的解决方案。基本代码来自Sphinx 3.0.3(Sphinx/writers/html.py):

您可以将其直接粘贴到底部的
conf.py


请注意,这将修补HTMLTranslator。如果您使用html5输出,那么您需要一个经过修改的html5转换器(sphinx/writers/html5.py)。

虽然下面的解决方案不如来自的解决方案性能好,但在将来修补
visit\u reference()。此外,它还可与
html
html5
翻译器无缝配合使用:

from sphinx.writers.html import HTMLTranslator
from sphinx.writers.html5 import HTML5Translator
from sphinx.util.docutils import is_html5_writer_available


class PatchedHTMLTranslator(
    HTML5Translator if is_html5_writer_available() else HTMLTranslator
):
    def starttag(self, node, tagname, *args, **attrs):
        if (
            tagname == "a"
            and "target" not in attrs
            and (
                "external" in attrs.get("class", "")
                or "external" in attrs.get("classes", [])
            )
        ):
            attrs["target"] = "_blank"
            attrs["ref"] = "noopener noreferrer"
        return super().starttag(node, tagname, *args, **attrs)


def setup(app):
    app.set_translator("html", PatchedHTMLTranslator)

可能的复制品有点不同。当链接很少且不在表中时,解决方案将起作用。但是,如果文档包含大量链接,那就太糟糕了。问题是一样的。答案可能很糟糕,令人不快,但这只是意味着有人应该提供一个更好的答案(尽管不幸的是,似乎没有更好的答案,rst/sphinx只是缺少这个功能)。虽然这让我在新标签中打开了外部链接,但这破坏了我的整个TOC,许多内部链接,等等,@codemanx提供的答案使外部链接成为新的标签,而不破坏内部链接:这非常有效,应该是公认的答案。类函数的源文件链接用以下内容修补:谢谢@scriptautomation。我更新了我的答案,它是和
HTMLTranslator
,我必须对它进行修补,才能使
生成html
有效。我不确定如何或何时使用
html5.py
/
HTML5Translator
。根据代码顶部的注释,这似乎是实验性的
make html5
给了我一个错误:生成器名称html5未注册或通过入口点NICE catch可用。我忘了说我在做同样的事情,也有同样的困惑哈哈,
visit\u reference
的代码在html和html5中看起来与我上次查看时是一样的。我可能遗漏了一些东西,使这种方法有所不同。我注意到
html5.py
顶部有评论说它是实验性的。要使用它,我要在安装中用sphinx/writers/html5.py替换html5.py吗?你能提供一个使用这个的语法示例吗?谢谢。你需要修补这个类,而不是替换它。正如我在回答中所说:您可以将代码直接粘贴到底部的
conf.py
中使用它。
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.html5 import HTML5Translator
from sphinx.util.docutils import is_html5_writer_available


class PatchedHTMLTranslator(
    HTML5Translator if is_html5_writer_available() else HTMLTranslator
):
    def starttag(self, node, tagname, *args, **attrs):
        if (
            tagname == "a"
            and "target" not in attrs
            and (
                "external" in attrs.get("class", "")
                or "external" in attrs.get("classes", [])
            )
        ):
            attrs["target"] = "_blank"
            attrs["ref"] = "noopener noreferrer"
        return super().starttag(node, tagname, *args, **attrs)


def setup(app):
    app.set_translator("html", PatchedHTMLTranslator)