ReST删除线

54

在 Restructured Text 中是否有办法划掉文字?

例如,当转换为 HTML 时,可以呈现为 <strike> 标签的内容,如:ReSTructuredText


当你使用Sphinx时,这可能会有所帮助:https://dev59.com/uGUq5IYBdhLWcg3wSehm#24932178 - Rolf
8个回答

46

我仔细查看了文档,就像Ville Säävuori建议的那样,我决定这样添加删除线:

.. role:: strike
    :class: strike
在文档中,可以按照如下方式应用:
:strike:`This text is crossed out`

然后在我的 css 文件中有以下条目:

.strike {
  text-decoration: line-through;
}

1
这种方法的问题在于,您必须在要使用删除线的每个reST文件中重复此定义,并且它不会在HTML端生成有意义的标记(最好生成<del><s>标记)。我已经发布了该代码(https://dev59.com/iGw15IYBdhLWcg3wmMx9#62493316) - Clément

17

至少有三种方法可以做到这一点:

.. role:: strike

An example of :strike:`strike through text`.

.. container:: strike

   Here the full block of test is striked through.

An undecorated paragraph.

.. class:: strike

This paragraph too is is striked through.

.. admonition:: cancelled
   :class: strike

I strike through cancelled text.

应用 rst2html 后,您会得到:

<p>An example of <span class="strike">strike through text</span>.</p>
<div class="strike container">
Here the full block of test is striked through.</div>
<p>An undecorated paragraph.</p>
<p class="strike">This paragraph too is is striked through.</p>
<div class="strike admonition">
<p class="first admonition-title">cancelled</p>
<p class="last">I strike through cancelled text.</p>
你可以用一种样式来使用它们。
.strike {
  text-decoration: line-through;
}

这里我以admonition指令为例,但任何允许使用:class:选项的指令都可以。

由于它生成了一个span,因此role指令是唯一可以将样式应用于段落部分的指令。

像Gozzilli建议的那样,给一个名为strike的指令添加一个strike类是多余的,因为指令名称是html输出的默认类。

我已经使用rest2htmlSphinx检查了这些语法。但是,虽然rest2html一切正常,但class指令在Sphinx中失败了。您必须将其替换为

.. rst-class:: strike

This paragraph too is is striked through.

这只在Sphinx reSt Primer的一个小脚注中提到。


你确定那个链接是正确的吗?它看起来并不像是你想要的目标链接。 - tshepang
2
@Tshepang,我检查了一下,链接最终指向一个脚注,其中说明:“当默认域包含类指令时,该指令将被遮盖。因此,Sphinx 将其重新导出为 rst-class。” - marcz

15

根据官方规范,在ReST中不存在删除线标记的指令。

但是,如果环境允许使用:raw:角色或您能够编写自己的角色,则可以编写自定义插件来添加删除线标记。


我在下面发布了插件代码(https://dev59.com/iGw15IYBdhLWcg3wmMx9#62493316) - Clément

5
这是一个Python中del角色的定义,如果你想在Pelican博客或Sphinx文档项目的多个页面中使用该角色,则此定义比接受的答案更好:
from docutils import nodes
from docutils.parsers.rst import roles

def deleted_role(_role, rawtext, text, _lineno, _inliner, options={}, _content=[]):
    roles.set_classes(options)
    options.setdefault('classes', []).append("del")
    return [nodes.inline(rawtext, text, **options)], []

roles.register_canonical_role('del', deleted_role)

更好的做法是扩展HTML编写器,以生成正确的<del>标签,例如:
from docutils import nodes
from docutils.parsers.rst import roles
from docutils.writers._html_base import HTMLTranslator

class delnode(nodes.inline):
    pass

def visit_delnode(self, node):
    self.body.append(self.starttag(node, 'del', ''))
def depart_delnode(self, node):
    self.body.append('</del>')

HTMLTranslator.visit_delnode = visit_delnode
HTMLTranslator.depart_delnode = depart_delnode

def deleted_role(_role, rawtext, text, _lineno, _inliner, options={}, _content=[]):
    roles.set_classes(options)
    return [delnode(rawtext, text, **options)], []

roles.register_canonical_role('del', deleted_role)

当然,您可以轻松地调整它以生成一个<s>


5
我发现其他回答非常有帮助。虽然我不太熟悉Sphinx,但我正在使用它进行项目开发。我也想要删除线的功能,并且已经根据先前的答案实现了它。需要明确的是,我像gozzilli提到的那样添加了我的删除线角色,但我将其保存在conf.py中,使用rst_prolog变量,如stack overflow主题这里所讨论的那样。这意味着该角色对于您所有的rest文件都是可用的。
然后,我通过在源目录下创建_templates目录中的layout.html,按上述描述扩展了基本的HTML模板。此文件的内容如下:
{% extends "!layout.html" %}
{% set css_files = css_files + ["_static/myStyle.css"] %}

这基本上是将自定义的CSS文件应用到所有默认的HTML文档中。

最后,在我的源目录中的 _static 目录中,我包含了一个名为 myStyle.css 的文件,其中包含以下内容:

.strike {
  text-decoration: line-through;
}

其他回答已经提供了答案。
我仅仅是写下这个答案,因为对于我这个经验有限的 Sphinx 用户来说并不明显需要编辑哪些文件。

4

考虑到用户可能具有不同的背景,因此没有一种适用于所有人的解决方案。

1.仅一个文件

如果您只在一个文件上使用它。例如,您将一个简单的项目发布到PyPI,并且您可能只有一个README.rst文件。您可能想要以下内容。

.. |ss| raw:: html

    <strike>

.. |se| raw:: html

    </strike>

single line
=============

|ss| abc\ |se|\defg

multiple line
=============

|ss|  
line 1

line 2
|se|

789

你可以将它复制并粘贴到此网站:https://livesphinx.herokuapp.com/

然后,您将看到以下图片:

enter image description here

这很简单,您可以直接在一些IDE上查看预览,例如PyCharm。


以下是针对Sphinx用户的撰写内容

2. Sphinx的入门级别

如果您是Sphinx的初学者(我是指您可能想使用Sphinx创建文档,但不熟悉Python),请按照以下步骤尝试:

# conf.py

from pathlib import Path
html_static_path = ['_static', ]
html_css_files = ['css/user.define.css']  # If you want to control which HTML should contain it, you can put it on the HTML, which is very like the answer by @Gregory Kuhn.

with open(Path(__file__).parent / Path('_static/css/user.define.rst'), 'r') as f:
    user_define_role = f.read()

rst_prolog = '\n'.join([ user_define_role + '\n',])  # will be included at the beginning of every source file that is read.
# rst_epilog = '\n'.join([ user_define_role + '\n',])  # it's ok if you put it on the end.

user.define.rst

.. role:: strike

user.define.css

.strike {text-decoration: line-through;}

通过使用 rst_prolog,可以在每个rst文件中自动添加角色,但是如果您更改内容(该文件包含您定义的格式),则必须重新生成以使渲染正确。

3. 创建角色

您可以创建一个扩展来实现这一功能。

# conf.py

extensions = ['_ext.rst_roles', ]
html_static_path = ['_static', ]
html_css_files = ['css/user.define.css']

# rst_roles.py
from sphinx.application import Sphinx
from docutils.parsers.rst import roles
from docutils import nodes
from docutils.parsers.rst.states import Inliner


def strike_role(role, rawtext, text, lineno, inliner: Inliner, options={}, content=[]):
    your_css_strike_name = 'strike'
    return nodes.inline(rawtext, text, **dict(classes=[your_css_strike_name])), []

def setup(app: Sphinx):
    roles.register_canonical_role('my-strike', strike_role)  # usage:  :my-strike:`content ...`


完整的架构:
  • conf.py
  • _ext/
    • rst_roles.py
  • _static/
    • css/
      • user.define.css
关于规则,您可以参考此链接rst-roles 并强烈建议您查看docutils.parsers.rst.roles.py

我不知道为什么我的答案让某人不高兴,然后给我投了反对票,希望你能告诉我原因,无论如何,我更新了我的解决方案,希望你能理解。 - Carson
这是目前的最佳答案。第一个“只有一个文件”的解决方案真的很优秀。它是唯一一个实际适用于在第三方站点上托管的reST文件(例如,GitHub或GitLab托管的README.rst)的常见情况的解决方案,而这些站点并不在您的直接控制之下。无论怎样,@Carson,讨厌者总是会讨厌的。我不会把这些踩票当成个人攻击。他们只是嫉妒罢了。 - Cecil Curry

2
我为此编写了一个扩展程序。
只需执行pip install sphinxnotes-strike,然后使用以下命令:
:strike:`text` 

或者

:del:`text` 

展示删除线文本的方法。

更多信息请参见:https://sphinx-notes.github.io/strike/


1
自从 Docutils 0.17 版本以来,如果在 inline、literal 或 container 元素中找到匹配的 class 值,HTML5-writer 将使用 <del>
.. role:: del

:del:`This text has been deleted`, here is the rest of the paragraph.

.. container:: del

  This paragraph has been deleted.

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