ReST strikethrough

Viewed 16652

Is it possible to strike text through in Restructured Text?

Something that for example renders as a <strike> tag when converted to HTML, like: ReSTructuredText

8 Answers

Here's a Python definition of a del role, which works better than the accepted answer if you want to use the role in multiple pages of a Pelican blog or a Sphinx documentation project:

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)

Even better would be to extend the HTML writer to produce a proper <del> tag, like this:

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)

You can trivially adjust it to produce an <s>, of course.

Consider the user may have a different background, so here is no one solution that can be suitable for everyone.

1.Only one file

If you only use it only on one file. For example, you published a simple project to PyPI, and you may probably just only one README.rst file. The following may you want.

.. |ss| raw:: html

    <strike>

.. |se| raw:: html

    </strike>

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

|ss| abc\ |se|\defg

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

|ss|  
line 1

line 2
|se|

789

you can copy and paste it on this website: https://livesphinx.herokuapp.com/

and will see the picture as the following:

enter image description here

It's simple, and you can on directly see the preview on some IDE, for example, PyCharm.


bellow is writing for the users of Sphinx

2.beginner of Sphinx

If you are a beginner of Sphinx. ( I mean maybe you want to use Sphinx to create a document, but Python is not familiar for you ) then try as following:

# 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;}

With the rst_prolog, It can auto-add the role on each rst files, but if you change the content( that file, it contains a format that you define), then you must rebuild to make the render is correct.

3.Create roles

You can create an extension to achieve it.

# 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 ...`

The full architecture:

  • conf.py
  • _ext/
    • rst_roles.py
  • _static/
    • css/
      • user.define.css

about the rules, you can reference this link rst-roles

And I vary recommended you to see the docutils.parsers.rst.roles.py .

Since Docutils 0.17, the HTML5-writer uses <del> if a matching class value is found in inline, literal, or container elements:

.. role:: del

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

.. container:: del

  This paragraph has been deleted.
Related