reST modifications

Last update: 19.03.2009 (note about rst2html)

The list of roles and directives I've added to "my" reST.



In order to use own roles you have to modify a file .../doctuils/parsers/rst/ — simply append at end of, and copy to the same directory where is located.

Simple math — math & cmath

Syntax of math expression has been borrowed from TeX; at the moment just subscripts and superscripts are supported. Small letters are italized, and some replacements are made.

Both roles math and cmath do the same thing, just produce nodes with different class names. For example my cmath style definition: display: block; text-align: center; font-size: larger.



Famous Einstein equation (e = m*c^2)

e = mc2

Determinant of matrix A4x4 (a_{11}*a_{22} - a_{12}*a_{21}):

det(A4x4) = a11a22a12a21

Cubic Bezier curve (p(t) = p_0 B^3_0(t) + p_1 B^3_1(t) + p_2 B^3_2(t) + p_3 B^3_3(t), 1 >= t >= 0):

p(t) = p0B30(t) + p1B31(t) + p2B32(t) + p3B33(t), 1 ≥ t ≥ 0

Polynomial of degree n (f(x) = a_0*x^n + a_1*x^{n-1} + ... + a_n*x^0):

f(x) = a0xn + a1xn − 1 + … + anx0

Trigonometry: sin^2x+cos^2x=1

sin2x + cos2x = 1


Installing new directives is also described in the reST documentation.

Python code snippets insertion

This directive allows to input selected functions or classes from Python source file.


.. pycode:: path&filename
        :def:    function_or_class_name
        :tabstop:       number

Line numbering is enabled if field lineno is present.

If field unindent is present then block's indention is set to 0; otherwise pycode keeps original source indention.

If field tabstop is set, then tabs are expanded with given tab stop.

Field def is a string of space separated code's block pointers, i.e. string "def" or "class" then colon then name of function or class.


Get top-level function:

.. pycode::
   :def:    def:py_getdef


def py_getdef(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine):

	filename = arguments[0]
	numbers  = 'lineno' 	in options
	unindent = 'unindent'	in options
	pattern  = options['def']
		tabstop = options['tabstop']
	except KeyError:
		tabstop = None

	# get source direcorty
	source     = state_machine.input_lines.source(lineno - state_machine.input_offset - 1)
	source_dir = os.path.dirname(os.path.abspath(source))

	f = open(os.path.join(source_dir, filename), 'r')
	if tabstop is None:
		lines = [(lineno+1, line.rstrip())\
		         for (lineno, line) in enumerate(f)]
		lines = [(lineno+1, line.rstrip().expandtabs(tabstop))\
		         for (lineno, line) in enumerate(f)]


	for block in pattern.replace('\t',' ').split(' '):
		kind, name = block.split(':')
		lines = py_grep(lines, name.strip(), kind.strip())

	if not lines:	# empty
		return [nodes.literal_block(”, ”)]
		if unindent:
			# get first line indention
			n = len(lines[0][1]) - len(lines[0][1].lstrip())
			for i, (lineno, line) in enumerate(lines):
				lines[i] = (lineno, line[n:])

		if numbers:
			text = '\n'.join("%4d %s" % item for item in lines)
			text = '\n'.join( (line for (lineno,line) in lines) )

		return [nodes.literal_block(text, text)]

Get local function defined inside py_getblock:

.. pycode::
   :def:    def:py_getblock def:get_indention


  86 	def get_indention(line, expandtabs=True):
  87 		"""Get line's indention"""
  88 		l = len(line)
  89 		if expandtabs:
  90 			t = len(line.expandtabs().lstrip())
  91 			return l-t
  92 		else:
  93 			t = len(line.lstrip())
  94 			return l-t

Other way to use additional roles and directives

Permanent installing role or directive require some changes in docutils sources — sometimes we don't have permissions to do it.

However it is quite simple to use additional roles and directives in scripts like rst2html:

        import locale
        locale.setlocale(locale.LC_ALL, ”)

from docutils.core import publish_cmdline, default_description

# directive
from pycode import py_getdef

import docutils.parsers.rst.directives as directives
directives._directive_registry["pycode"] = ("pycode", "py_getdef")

# roles
import myroles
import docutils.parsers.rst.roles as roles
roles.register_canonical_role('math',   myroles.inlinemath_role)
roles.register_canonical_role('cmath',  myroles.centermath_role)
roles.register_canonical_role('plwiki', myroles.plwiki_link_role)
roles.register_canonical_role('enwiki', myroles.enwiki_link_role)

description = ('Generates (X)HTML documents from standalone reStructuredText '
                           'sources.  ' + default_description)

publish_cmdline(writer_name='html', description=description)