在Sphinx / reStructuredText中添加open-in-new-tab链接

时间:2014-08-30 14:44:13

标签: hyperlink python-sphinx restructuredtext

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

Open a link in a new window in reStructuredText

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

还有其他解决方案吗?谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

如果要在新标签页中打开外部链接,请在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。

来源: http://jack.rosenth.al/hacking-docutils.html#external-links-in-new-tabs

答案 1 :(得分:1)

要将target="_blank"以及rel="noopener noreferrer"添加到外部链接,必须复制Sphinx的整个visit_reference()方法以将其修补:

atts['target'] = '_blank'
atts['rel'] = 'noopener noreferrer'`

Sphinx的原始代码不会处理可能设置为rel的{​​{1}}属性,而会应用node['rel'] = 'noopener noreferrer'属性(target)。

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

atts['target'] = node['target']

您可以将其直接粘贴到底部的from sphinx.writers.html import HTMLTranslator from docutils import nodes from docutils.nodes import Element class PatchedHTMLTranslator(HTMLTranslator): def visit_reference(self, node: Element) -> None: atts = {'class': 'reference'} if node.get('internal') or 'refuri' not in node: atts['class'] += ' internal' else: atts['class'] += ' external' # --------------------------------------------------------- # Customize behavior (open in new tab, secure linking site) atts['target'] = '_blank' atts['rel'] = 'noopener noreferrer' # --------------------------------------------------------- if 'refuri' in node: atts['href'] = node['refuri'] or '#' if self.settings.cloak_email_addresses and atts['href'].startswith('mailto:'): atts['href'] = self.cloak_mailto(atts['href']) self.in_mailto = True else: assert 'refid' in node, \ 'References must have "refuri" or "refid" attribute.' atts['href'] = '#' + node['refid'] if not isinstance(node.parent, nodes.TextElement): assert len(node) == 1 and isinstance(node[0], nodes.image) atts['class'] += ' image-reference' if 'reftitle' in node: atts['title'] = node['reftitle'] if 'target' in node: atts['target'] = node['target'] self.body.append(self.starttag(node, 'a', '', **atts)) if node.get('secnumber'): self.body.append(('%s' + self.secnumber_suffix) % '.'.join(map(str, node['secnumber']))) def setup(app): app.set_translator('html', PatchedHTMLTranslator) 中。

请注意,这会修补HTMLTranslator。如果使用HTML 5输出,则需要修改的HTML5Translator( sphinx / writers / html5.py )。

答案 2 :(得分:0)

虽然下面的解决方案不如 this answer 中的解决方案那么高效,但在未来修补 visit_reference() 的情况下,它更简单,更不脆弱。此外,它还可以与 htmlhtml5 翻译器无缝协作:

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)