reST / Sphinx 中链接中的替换

23

我正在使用Sphinx来记录一个将部署在不同服务器的Web服务。文档中充满了用户可以点击并应该正常工作的URL示例。但我的问题是主机、端口和部署根目录将会变化,每次部署都需要重新生成文档。

我尝试像这样定义替换:

|base_url|/path
.. |base_url| replace:: http://localhost:8080

但是生成的HTML并不是我想要的(在生成的链接中不包括“/path”):

<a href="http://localhost:8080">http://localhost:8080</a>/path

有人知道如何解决这个问题吗?


不确定这是否与此问题相关,但可能是:https://dev59.com/Dm445IYBdhLWcg3wq8Pp#4836544。 - Mad Physicist
4个回答

31

Sphinx v1.0的新功能:

sphinx.ext.extlinks——用于缩短外部链接的标记

https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html

该扩展添加了一个新的配置值:

extlinks

该配置值必须是一个外部站点的字典,将唯一的短别名映射到基本URL和前缀。例如,要为上述问题创建别名,您可以添加:

extlinks = {'issue': 
    ('http://bitbucket.org/birkenfeld/sphinx/issue/%s', 'issue ')}
现在,你可以将别名用作新角色,例如:issue:`123`。 这将插入一个链接到http://bitbucket.org/birkenfeld/sphinx/issue/123。 如您所见,在角色中给定的目标替换了基本URL中的%s
链接标题取决于元组中的第二个项目,即前缀:
如果前缀为None,则链接标题为完整的URL。 如果前缀为空字符串,则链接标题为角色内容中给出的部分URL(在此示例中为123)。 如果前缀是非空字符串,则链接标题为部分URL,前面加上前缀 - 在上面的示例中,链接标题将为问题123。 您还可以使用其他生成链接的角色支持的常规“显式标题”语法,即: issue:`this issue <123>` 。 在这种情况下,前缀无关紧要。

这是Sphinx的一个很好的补充。感谢您提供的信息! - Martin Blech
6
显而易见的是,你需要将以下内容添加到你的conf.py文件中:extensions = ['sphinx.ext.extlinks']。不得不查看别人的conf.py文件才找到这个答案。 - ideasman42
1
请注意,这并不适用于包含未参数化的一般URL的情况,特别是如果该URL巧合地包含字符序列“%s”。 - shadowtalker

5

我遇到了类似的问题,需要替换图像目标中的URL。当将extlinks用作图片:target:属性的值时,它们不会展开。 最终,我编写了一个自定义的sphinx转换器,可以重写以给定前缀开头的URL,例如:http://mybase/。以下是conf.py的相关代码:

from sphinx.transforms import SphinxTransform

class ReplaceMyBase(SphinxTransform):

    default_priority = 750
    prefix = 'http://mybase/'

    def apply(self):
        from docutils.nodes import reference, Text
        baseref = lambda o: (
            isinstance(o, reference) and
            o.get('refuri', '').startswith(self.prefix))
        basetext = lambda o: (
            isinstance(o, Text) and o.startswith(self.prefix))
        base = self.config.mybase.rstrip('/') + '/'
        for node in self.document.traverse(baseref):
            target = node['refuri'].replace(self.prefix, base, 1)
            node.replace_attr('refuri', target)
            for t in node.traverse(basetext):
                t1 = Text(t.replace(self.prefix, base, 1), t.rawsource)
                t.parent.replace(t, t1)
        return

# end of class

def setup(app):
    app.add_config_value('mybase', 'https://en.wikipedia.org/wiki', 'env')
    app.add_transform(ReplaceMyBase)
    return

这将扩展以下rst源以指向英语维基百科。 当conf.py设置mybase="https://es.wikipedia.org/wiki"时,链接将指向西班牙语维基百科。
* inline link http://mybase/Helianthus
* `link with text <http://mybase/Helianthus>`_
* `link with separate definition`_
* image link |flowerimage|

.. _link with separate definition: http://mybase/Helianthus

.. |flowerimage| image:: https://upload.wikimedia.org/wikipedia/commons/f/f1/Tournesol.png
   :target: http://mybase/Helianthus

谢谢,有趣的方法,我正在尝试使用它来处理自定义链接作为间接引用的替换(无法找到在类似.. _some_link: mylink:/some/where中使用extlinks的方法) - Mekk

4

好的,这是我做的方法。首先,apilinks.py(Sphinx扩展):

from docutils import nodes, utils

def setup(app):
    def api_link_role(role, rawtext, text, lineno, inliner, options={},
                      content=[]):
        ref = app.config.apilinks_base + text
        node = nodes.reference(rawtext, utils.unescape(ref), refuri=ref,
                               **options)
        return [node], []
    app.add_config_value('apilinks_base', 'http://localhost/', False)
    app.add_role('apilink', api_link_role)

现在,在conf.py文件中,将'apilinks'添加到扩展列表中,并为'apilinks_base'设置适当的值(否则,默认值为'http://localhost/')。我的文件看起来像这样:
extensions = ['sphinx.ext.autodoc', 'apilinks']
# lots of other stuff
apilinks_base = 'http://host:88/base/'

使用方法:

:apilink:`path`

输出:

<a href="http://host:88/base/path">http://host:88/base/path</a>

1

你可以编写一个Sphinx 扩展, 创建一个类似于角色的功能

:apilink:`path` 

然后从中生成链接。我从未这样做过,所以除了提供这个指针外,我无法提供更多帮助,抱歉。您应该尝试查看各种角色的实现方式。许多角色与您需要的非常相似,我认为。


@thoriann:感谢你的指引,检查我的答案以查看完整的实现。 - Martin Blech
11年过去了。链接失效了。答案也失效了吗? - keepAlive
1
@keepAlive 你可以轻松找到已移动的文档,例如,第一个链接请参见 https://sphinx.readthedocs.io/en/2.0/usage/extensions/index.html,第二个链接请参见 https://www.sphinx-doc.org/en/2.0/usage/restructuredtext/roles.html。 - Yaroslav Nikitenko
“容易”是相对的。感谢您找到那些文件(我自己永远找不到)。 - shadowtalker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接