documentation fix
[docutils.git] / sandbox / OpenDocument / docs / plugins_proposal.txt
blob5d3564ace2ad5e3d7679d18c01c32abc8fe5bb30
1 ========================================================
2 A Proposal for User Plugins for Docutils Readers/Writers
3 ========================================================
5 :Author: Dave Kuhlman
6 :address: dkuhlman@rexx.com
7     http://www.rexx.com/~dkuhlman
9 :date: March 21, 2007
11 .. contents::
14 Abstract
15 ========
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.
23 Rationale
24 =========
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.
37 The Proposal
38 ============
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`_.
60 Notes:
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
67   classes) are run.
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 *
76   or::
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`_.
86 Alternatives
87 ============
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
95 right about that?
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."
105 See:
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. ::
122     import inspect
124     #
125     # Register directives defined in a module named "odtwriter_plugins".
126     #
127     def load_plugins():
128         plugin_mod = None
129         count = 0
130         try:
131             import odtwriter_plugins
132             plugin_mod = odtwriter_plugins
133         except ImportError, e:
134             pass
135         if plugin_mod is None:
136             return count
137         klasses = inspect.getmembers(plugin_mod, inspect.isclass)
138         for klass in klasses:
139             if register_plugin(*klass):
140                 count += 1
141         return count
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)
148     load_plugins()
152 Copyright
153 =========
155 This document has been placed in the public domain.
159 .. _`Creating reStructuredText Directives`:
160    http://docutils.sourceforge.net/docs/howto/rst-directives.html