1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
======================================
How To Create Extensions to Docutils
======================================
:Author: Felix Wiemann
:Contact: Felix.Wiemann@ososo.de
:Date: $Date$
:Revision: $Revision$
:Copyright: This document has been placed in the public domain.
Since version 0.5, Docutils uses setuptools_ as its primary extension
mechanism. This document will walk you through the process of
creating an extension to Docutils using setuptools. You do not need
to have used setuptools before.
.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
Specifically, this document covers the addition of Docutils components
(readers, parsers, and writers), and the addition of reStructuredText
roles and directives.
.. contents::
Entry Points
============
Docutils defines several so-called *entry point groups*, which
extension packages can "hook into" by registering a new *entry point*
with setuptools.
The three entry point groups for adding new components are
``docutils.readers``, ``docutils.parsers``, and ``docutils.writers``.
(Note that these are entry point names, not Python package names.)
The reStructuredText parser uses two additional entry point groups,
``docutils.parsers.rst.directives`` and
``docutils.parsers.rst.roles``. These can be used to add new
directives and roles, respectively.
Registering entry points is done using ``setup.py``. This means that
your extension must supply its own setup script. This is easy though;
we will provide you with a template below.
If you look at Docutils' own setup.py file and search for
"entry_points", you will see that Docutils registers its own readers,
parsers, writers, and reStructuredText roles and directives just like
an extension package would do.
Package Structure
=================
The directory structure of your package should look like this::
newpackage/
README.txt (general information about your package)
setup.py (setup script, explained below)
docs/ (documentation -- optional)
test/ (tests -- optional; do not place an __init__.py here)
newpackage/ (source directory -- same name as parent directory)
__init__.py
some_module.py (the particular module structure is up to you)
Your module can create new readers, parsers, writers, `new roles`_ and
`new directives`_, by deriving from one of the following base classes:
* docutils.readers.Reader
* docutils.parsers.Parser
* docutils.writers.Writer
* docutils.parsers.rst.Directive (see the `directive how-to`)
* role functions are implemented using functions; see the `role
how-to`.
.. _role how-to:
.. _new roles: rst-roles.html
.. _directive how-to:
.. _new directives: rst-directives.html
setup.py
========
Your ``setup.py`` would look like this::
# $Id$
# Copyright: Your copyright note. (E.g. "This module has been
# placed in the public domain.")
from setuptools import setup, find_packages
# Map entry point groups to entry point definitions.
entry_points = {
'docutils.readers': 'newreader = newpackage:Reader',
'docutils.parsers': 'newparser = newpackage.some_module:Parser',
'docutils.writers': 'newwriter = newpackage:Writer',
'docutils.parsers.rst.directives': [
# register several directives by passing a list of entry points
'new-directive-1 = newpackage.some_module:FirstDirective',
'another-directive = newpackage.some_module:SecondDirective',
]
'docutils.parsers.rst.roles': 'some-role = newpackage:some_role_fn',
}
setup(
name = 'docutils-newpackage',
version = '0.1',
description = 'Short description',
author = 'Your Name',
author_email = '<email@example.org>',
license = 'the license of your extension package',
install_requires = ['docutils>=0.5'] # adjust to current Docutils version
packages = find_packages(),
include_package_data = True, # set to False to not include data files
entry_points = entry_points, # using the dictionary defined above
)
The entry point definitions above are lengthy for illustration
purposes; normally, you would only register, for example, one writer,
or one directive. Note that after each module name in the entry point
definitions, there is a colon followed by the name of a Python object
(typically a class). Do *not* register modules with Docutils;
register the appropriate classes inside these modules. Note again
that the module name and the class name are separated by a colon, not
by a dot.
The names of the entry points (in the example above, ``newreader``,
``newparser``, ``newwriter``, ``new-directive-1``,
``another-directive``, and ``some-role``) are the names by which the
components, roles, or directives are registered with Docutils or the
reStructuredText parser. (Unfortunately, there is no clean and
generic way yet to provide translations of directive and role names as
part of your extension package.)
In order to actually register your extension package, you need to run
the following command as root or administrator::
python setup.py develop
This will install a link to the source directory of your package in
Python's global ``site-packages`` directory and register the entry
points with the entry point groups. Every time you change your
setup.py file, you need to re-run ``python setup.py develop``.
If your users want to install your extension package permanently, you
should instruct them to run ::
python setup.py install
Beyond this setup.py file, no registration of your extensions is
necessary. Once the ``setup.py`` script has been run, all components,
roles, and directives are visible to Docutils. That means that you
can use the roles and directives in your reStructuredText documents as
if they were part of the Docutils core. For new components, you will
need to add a new `front-end tool`_ (like ``rst2newformat.py``). This
is not yet covered in this document.
.. _front-end tool: ../api/cmdline-tool.html
|