以下是针对同一问题的解决方案:
Open a link in a new window in reStructuredText
但是,当文档有很多链接时(特别是当链接在表格中时),此解决方案将无法正常工作。
还有其他解决方案吗?谢谢你的帮助!
答案 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()
的情况下,它更简单,更不脆弱。此外,它还可以与 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)