1 ========================================================
2 A Proposal for User Plugins for Docutils Readers/Writers
3 ========================================================
6 :address: dkuhlman@rexx.com
7 http://www.rexx.com/~dkuhlman
17 This proposal describes a standard for support of user directives for
18 Docutils readers/writers. It is intended that Docutils writers (for
19 example, rst2html.py, rst2latex.py, rst2odt.py, etc.) would attempt to
20 load and register directives as described by this proposal.
26 Directives are a Docutils extension mechanism. In particular,
27 directives enable us to implement a class that adds nodes to the
28 document node tree as that tree is being constructed and before the
29 tree is processed by a writer.
31 This proposal describes a way to make directive implementations
32 automatically loadable. It is intended that this mechanism would
33 enable users to add their own directives and even to provide different
34 directive implementations for different documents.
40 The following items describe this proposal:
42 - Each writer will attempt to import a directive module containing
43 directive implementation classes.
45 - The default directive module name is ``docutils_directives.py``.
46 Each writer will also implement a command line flag
47 ``--plugins-module-name`` that will enable users to override the
48 default directive module name. But see note on problems with using
49 a command line flag below.
51 - All classes in the directive module which contain the class variable
52 ``directive_name`` will be treated as directive implementation
53 classes. Each such class will be registered as a directive using
54 the value of ``directive_name`` as the directive name.
56 - Each directive implementation class must follow the directive class
57 implementation guidelines given at
58 `Creating reStructuredText Directives`_.
62 - I'd like users to be able to pass in the name of the plugins module
63 on the command line. However, this seems difficult, because the
64 writer class, which has access to configuration variables, does not
65 get control until after the node tree has been constructed, and it
66 is during construction of the node tree that plugins (directive
69 - The mechanism described above registers all classes in a module, if
70 the class has the class variable named ``directive_name``.
71 Therefore, that module could "include" directive implementations
72 from other modules using the following::
74 from my_other_module import *
78 from my_other_module import MyDirectiveClass1, MyDirectiveClass2
80 - This proposal supports the implementation of directives by *classes*
81 but not by *functions*. But, I can't find any documentation on
82 implementing a directive as a function, anyway. See:
83 `Creating reStructuredText Directives`_.
89 Lea Wiemann also has a proposal for extensions. That proposal seems
90 more oriented toward adding extensions to an installation of Docutils
91 rather than, as in this proposal, enabling users to load and register
92 directives automatically, on the fly. So, for example, under Lea's
93 plugins proposal, in order to change the implementation of a
94 directive, the user must perform some sort of install operation. Am I
97 Lea's proposal also appears to be much more general and powerful
98 than this one. It covers the ability to add other types of extensions
99 besides directives. A quote from Lea's proposal:
101 "Specifically, this document covers the addition of Docutils components
102 (readers, parsers, and writers), and the addition of reStructuredText
103 roles and directives."
107 - http://svn.berlios.de/viewcvs/docutils/branches/plugins/docs/howto/
109 - "How To Create Extensions to Docutils" --
110 http://svn.berlios.de/viewcvs/docutils/branches/plugins/docs/howto/extensions.txt?view=markup
114 A Sample Implementation
115 =======================
117 The following code could be added near the top of a Docutils writer in
118 order to implement this proposal. This code is provided for
119 discussion. Note that it does not support a command line flag that
120 can pass in the directive module name. ::
125 # Register directives defined in a module named "odtwriter_plugins".
131 import odtwriter_plugins
132 plugin_mod = odtwriter_plugins
133 except ImportError, e:
135 if plugin_mod is None:
137 klasses = inspect.getmembers(plugin_mod, inspect.isclass)
138 for klass in klasses:
139 if register_plugin(*klass):
143 def register_plugin(name, klass):
144 plugin_name = getattr(klass, 'plugin_name', None)
145 if plugin_name is not None:
146 rst.directives.register_directive(plugin_name, klass)
155 This document has been placed in the public domain.
159 .. _`Creating reStructuredText Directives`:
160 http://docutils.sourceforge.net/docs/howto/rst-directives.html