在reST中指定锚点名称

14

我正在使用docutils自带的rst2html工具将reST转换为HTML。似乎代码已经将id属性分配给了各个部分,这可以用作URL的片段标识符,即锚点,以跳转到页面的特定部分。这些id值基于节标题的文本。当我更改该标题的措辞时,标识符也会更改,从而使旧URL无效。

是否有一种方式指定要用作给定部分标识符的名称,以便我可以编辑标题而不使链接失效?如果我从自己的脚本中调用docutils publisher,是否有一种方法可行呢?

3个回答

4

我认为在reST部分中无法设置显式id,但我可能错了。

如果您更喜欢编号的id,这将取决于文档树中部分的排序而不是它们的标题,您可以通过对docutils / nodes.py中document.set_id()方法进行小修改来实现。

这里是补丁:

 def set_id(self, node, msgnode=None):
     for id in node['ids']:
         if id in self.ids and self.ids[id] is not node:
             msg = self.reporter.severe('Duplicate ID: "%s".' % id)
             if msgnode != None:
                 msgnode += msg
     if not node['ids']:
-        for name in node['names']:
-            id = self.settings.id_prefix + make_id(name)
-            if id and id not in self.ids:
-                break
-        else:
+        if True: #forcing numeric ids
             id = ''
             while not id or id in self.ids:
                 id = (self.settings.id_prefix +
                       self.settings.auto_id_prefix + str(self.id_start))
                 self.id_start += 1
         node['ids'].append(id)
     self.ids[id] = node
     return id

我刚刚测试了它,它生成的章节id为id1、id2……

如果你不想在整个系统中更改这个文件,你可以从自定义的rst2html命令中进行补丁操作。


1
数字ID在我的情况下并没有更好,但猴子补丁该函数仍然是一个有用的建议:我可以从我的章节标题中提取一个相当稳定的ID。对于我的当前应用程序很有效。如果有更优雅的建议,我会保留悬赏,但如果没有,那就归你了。 - MvG
默认的 ID 取决于章节标题,而不是它们的位置。数字 ID 取决于它们的位置,而不是它们的标题。一般情况下,除非您想出某种自定义代码并依赖于您命名章节的方式,否则我认为没有第三种方法。 - Tobia

4

我不确定是否真正理解了你的问题。

您可以创建明确的超链接目标,以引用文档中的任意位置,这些位置与docutils创建的隐式超链接目标无关:

.. _my_rstfile:

------------------
This is my rstfile
------------------

.. _a-section:

First Chapter
-------------

This a link to a-section_ which is located in my_rstfile_.

看起来您希望在多个rst文件之间创建链接,我建议使用Sphinx,因为它可以处理不同文件之间的任意位置的引用,并且具有更多的优势,例如toctree主题。您不仅可以使用Sphinx编写源代码文档,还可以进行一般文本处理。像Sphinx文档本身就是一个例子(在readthedocs上有数百个其他例子)。

使用sphinx-quickstart调用Sphinx很简单。您只需将现有的rst文件添加到index.rst的toctree中,然后运行make html。如果您想记录Python代码,可以使用sphinx-apidoc自动生成API文档。


1
这种显式超链接目标的问题在于自动生成的目录中的链接不会使用它们。因此,如果有人选择了目录项,然后复制了结果URL,那么该URL中的片段标识符可能会在以后变得无效。但至少对于外部文档中的链接来说,这是一种可能性。我将更仔细地研究Sphinx。 - MvG
所以我认为Sphinx是最好的选择,因为它是专门为此设计的。我稍微更新了我的答案。 - bmu
对于这个特定的任务,使用Sphinx进行htmlsinglehtml构建看起来非常有前途,尽管我仍然需要重写我的文档才能使其正常工作,因此我还不能确定结果是否令人满意。我仍然想了解如何调整基本的rst2html以使用自定义锚点。这意味着我可能最终会像你建议的那样使用Sphinx,并将赏金授予Tobia,因为他的答案更接近我的问题。希望你不要太介意。 - MvG
说实话:我认为引用编号部分不是一个好的方式,因为你可能会在之后更改排序。例如,在latex中你不会这样做。所以我认为我的解决方案更符合你的问题:显式超链接目标是更好的选择。Sphinx仍然是更好的选择,因为它可以自动处理一些事情,并且专门为此设计。此外,我认为你不需要重写你的文档,它们应该按原样工作(相反的情况并非都适用:sphinx引入了一些docutils不知道的角色)。 - bmu
好的,我只是将我的一个现有文档简单地拖放到快速启动创建的 index.rst 中。由自动生成的 TOC 使用的各个部分的锚点再次来自于部分标题,而不是来自于这些标题之前的显式链接目标。只有整个文档具有从文件名形成的锚点。因此,为了使其有用,我将不得不将我的文档拆分为每个函数一个文件。然后它可能会起作用,尽管我想找到一些方法在 singlehtml 构建中省略这个 document- 前缀。 - MvG
显示剩余4条评论

2
我制作了一个Sphinx扩展来解决这个问题。该扩展使用前面的内部目标作为该节的ID。例如(来自bmu的答案):
.. _a-section:

First Chapter
-------------

“第一章”的永久链接将指向#a-section而不是#first-chapter。如果有多个,则选择最后一个。

扩展链接:https://github.com/GeeTransit/sphinx-better-subsection


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