summaryrefslogtreecommitdiff
path: root/sandbox/OpenDocument/docs/plugins_proposal.txt
blob: 5d3564ace2ad5e3d7679d18c01c32abc8fe5bb30 (plain)
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
157
158
159
160
161
162
163
164
========================================================
A Proposal for User Plugins for Docutils Readers/Writers
========================================================

:Author: Dave Kuhlman
:address: dkuhlman@rexx.com
    http://www.rexx.com/~dkuhlman

:date: March 21, 2007

.. contents::


Abstract
========

This proposal describes a standard for support of user directives for
Docutils readers/writers.  It is intended that Docutils writers (for
example, rst2html.py, rst2latex.py, rst2odt.py, etc.) would attempt to
load and register directives as described by this proposal.


Rationale
=========

Directives are a Docutils extension mechanism.  In particular,
directives enable us to implement a class that adds nodes to the
document node tree as that tree is being constructed and before the
tree is processed by a writer.

This proposal describes a way to make directive implementations
automatically loadable.  It is intended that this mechanism would
enable users to add their own directives and even to provide different
directive implementations for different documents.


The Proposal
============

The following items describe this proposal:

- Each writer will attempt to import a directive module containing
  directive implementation classes.

- The default directive module name is ``docutils_directives.py``.
  Each writer will also implement a command line flag
  ``--plugins-module-name`` that will enable users to override the
  default directive module name.  But see note on problems with using
  a command line flag below.

- All classes in the directive module which contain the class variable
  ``directive_name`` will be treated as directive implementation
  classes.  Each such class will be registered as a directive using
  the value of ``directive_name`` as the directive name.

- Each directive implementation class must follow the directive class
  implementation guidelines given at
  `Creating reStructuredText Directives`_.

Notes:

- I'd like users to be able to pass in the name of the plugins module
  on the command line.  However, this seems difficult, because the
  writer class, which has access to configuration variables, does not
  get control until after the node tree has been constructed, and it
  is during construction of the node tree that plugins (directive
  classes) are run.

- The mechanism described above registers all classes in a module, if
  the class has the class variable named ``directive_name``.
  Therefore, that module could "include" directive implementations
  from other modules using the following::

      from my_other_module import *

  or::

      from my_other_module import MyDirectiveClass1, MyDirectiveClass2

- This proposal supports the implementation of directives by *classes*
  but not by *functions*.  But, I can't find any documentation on
  implementing a directive as a function, anyway.  See:
  `Creating reStructuredText Directives`_.


Alternatives
============

Lea Wiemann also has a proposal for extensions.  That proposal seems
more oriented toward adding extensions to an installation of Docutils
rather than, as in this proposal, enabling users to load and register
directives automatically, on the fly.  So, for example, under Lea's
plugins proposal, in order to change the implementation of a
directive, the user must perform some sort of install operation.  Am I
right about that?

Lea's proposal also appears to be much more general and powerful
than this one.  It covers the ability to add other types of extensions
besides directives.  A quote from Lea's proposal:

    "Specifically, this document covers the addition of Docutils components
    (readers, parsers, and writers), and the addition of reStructuredText
    roles and directives."

See:

- http://svn.berlios.de/viewcvs/docutils/branches/plugins/docs/howto/

- "How To Create Extensions to Docutils" --
  http://svn.berlios.de/viewcvs/docutils/branches/plugins/docs/howto/extensions.txt?view=markup



A Sample Implementation
=======================

The following code could be added near the top of a Docutils writer in
order to implement this proposal.  This code is provided for
discussion.  Note that it does not support a command line flag that
can pass in the directive module name. ::

    import inspect

    #
    # Register directives defined in a module named "odtwriter_plugins".
    #
    def load_plugins():
        plugin_mod = None
        count = 0
        try:
            import odtwriter_plugins
            plugin_mod = odtwriter_plugins
        except ImportError, e:
            pass
        if plugin_mod is None:
            return count
        klasses = inspect.getmembers(plugin_mod, inspect.isclass)
        for klass in klasses:
            if register_plugin(*klass):
                count += 1
        return count

    def register_plugin(name, klass):
        plugin_name = getattr(klass, 'plugin_name', None)
        if plugin_name is not None:
            rst.directives.register_directive(plugin_name, klass)

    load_plugins()



Copyright
=========

This document has been placed in the public domain.



.. _`Creating reStructuredText Directives`:
   http://docutils.sourceforge.net/docs/howto/rst-directives.html