# reST modifications

Last update: 19.03.2009 (note about rst2html)

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

# Roles

In order to use own roles you have to modify a file .../doctuils/parsers/rst/roles.py — simply append myroles.py at end of roles.py, and copy roles_aux.py to the same directory where roles.py 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.

Syntax:

```:math:`expression`
:cmath:`expression`
```

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

# Directives

• locate .../doctuils/parsers/rst/directives/__init__.py
• add new entry to dictionary _directive_registry: key is name of directive, value is pair: module name, name of function that implements directive; for pycode you have to add following code: 'pycode': ('pycode', 'py_getdef'),

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.

Syntax

```.. pycode:: path&filename
:def:    function_or_class_name
:lineno:
:unindent:
: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.

Examples

Get top-level function:

```.. pycode:: pycode.py
:def:    def:py_getdef
```

Result:

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

filename = arguments
numbers  = 'lineno' 	in options
unindent = 'unindent'	in options
pattern  = options['def']
try:
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)]
else:
lines = [(lineno+1, line.rstrip().expandtabs(tabstop))\
for (lineno, line) in enumerate(f)]

f.close()

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(”, ”)]
else:
if unindent:
# get first line indention
n = len(lines) - len(lines.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)
else:
text = '\n'.join( (line for (lineno,line) in lines) )

return [nodes.literal_block(text, text)]
```

Get local function defined inside py_getblock:

```.. pycode:: pycode.py
:def:    def:py_getblock def:get_indention
:lineno:
```

Result:

```  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:

```try:
import locale
locale.setlocale(locale.LC_ALL, ”)
except:
pass

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)