~ubuntu-branches/ubuntu/jaunty/python-docutils/jaunty

« back to all changes in this revision

Viewing changes to docs/howto/rst-directives.txt

  • Committer: Bazaar Package Importer
  • Author(s): martin f. krafft
  • Date: 2006-07-10 11:45:05 UTC
  • mfrom: (2.1.4 edgy)
  • Revision ID: james.westby@ubuntu.com-20060710114505-otkhqcslevewxmz5
Tags: 0.4-3
Added build dependency on python-central (closes: #377580).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
======================================
 
2
 Creating reStructuredText Directives
 
3
======================================
 
4
 
 
5
:Authors: Dethe Elza, David Goodger
 
6
:Contact: delza@enfoldingsystems.com
 
7
:Date: $Date: 2005-03-15 01:33:59 +0100 (Tue, 15 Mar 2005) $
 
8
:Revision: $Revision: 3045 $
 
9
:Copyright: This document has been placed in the public domain.
 
10
 
 
11
Directives are the primary extension mechanism of reStructuredText.
 
12
This document aims to make the creation of new directives as easy and
 
13
understandable as possible.  There are only a couple of
 
14
reStructuredText-specific features the developer needs to know to
 
15
create a basic directive.
 
16
 
 
17
The syntax of directives is detailed in the `reStructuredText Markup
 
18
Specification`_, and standard directives are described in
 
19
`reStructuredText Directives`_.
 
20
 
 
21
Directives are a reStructuredText markup/parser concept.  There is no
 
22
"directive" element, no single element that corresponds exactly to the
 
23
concept of directives.  Instead, choose the most appropriate elements
 
24
from the existing Docutils elements.  Directives build structures
 
25
using the existing building blocks.  See `The Docutils Document Tree`_
 
26
and the ``docutils.nodes`` module for more about the building blocks
 
27
of Docutils documents.
 
28
 
 
29
.. _reStructuredText Markup Specification:
 
30
   ../ref/rst/restructuredtext.html#directives
 
31
.. _reStructuredText Directives: ../ref/rst/directives.html
 
32
.. _The Docutils Document Tree: ../ref/doctree.html
 
33
 
 
34
 
 
35
.. contents:: Table of Contents
 
36
 
 
37
 
 
38
Define the Directive Function
 
39
=============================
 
40
 
 
41
The directive function does any processing that the directive
 
42
requires.  This may require the use of other parts of the
 
43
reStructuredText parser.  This is where the directive actually *does*
 
44
something.
 
45
 
 
46
The directive implementation itself is a callback function whose
 
47
signature is as follows::
 
48
 
 
49
    def directive_fn(name, arguments, options, content, lineno,
 
50
                     content_offset, block_text, state, state_machine):
 
51
        code...
 
52
 
 
53
    # Set function attributes:
 
54
    directive_fn.arguments = ...
 
55
    directive_fn.options = ...
 
56
    direcitve_fn.content = ...
 
57
 
 
58
Function attributes are described below (see `Specify Directive
 
59
Arguments, Options, and Content`_).  The directive function parameters
 
60
are as follows:
 
61
 
 
62
- ``name`` is the directive type or name.
 
63
 
 
64
- ``arguments`` is a list of positional arguments, as specified in the
 
65
  ``arguments`` function attribute.
 
66
 
 
67
- ``options`` is a dictionary mapping option names to values.  The
 
68
  options handled by a directive function are specified in the
 
69
  ``options`` function attribute.
 
70
 
 
71
- ``content`` is a list of strings, the directive content.  Use the
 
72
  ``content`` function attribute to allow directive content.
 
73
 
 
74
- ``lineno`` is the line number of the first line of the directive.
 
75
 
 
76
- ``content_offset`` is the line offset of the first line of the
 
77
  content from the beginning of the current input.  Used when
 
78
  initiating a nested parse.
 
79
 
 
80
- ``block_text`` is a string containing the entire directive.  Include
 
81
  it as the content of a literal block in a system message if there is
 
82
  a problem.
 
83
 
 
84
- ``state`` is the state which called the directive function.
 
85
 
 
86
- ``state_machine`` is the state machine which controls the state
 
87
  which called the directive function.
 
88
 
 
89
Directive functions return a list of nodes which will be inserted into
 
90
the document tree at the point where the directive was encountered.
 
91
This can be an empty list if there is nothing to insert.  For ordinary
 
92
directives, the list must contain body elements or structural
 
93
elements.  Some directives are intended specifically for substitution
 
94
definitions, and must return a list of ``Text`` nodes and/or inline
 
95
elements (suitable for inline insertion, in place of the substitution
 
96
reference).  Such directives must verify substitution definition
 
97
context, typically using code like this::
 
98
 
 
99
    if not isinstance(state, states.SubstitutionDef):
 
100
        error = state_machine.reporter.error(
 
101
            'Invalid context: the "%s" directive can only be used '
 
102
            'within a substitution definition.' % (name),
 
103
            nodes.literal_block(block_text, block_text), line=lineno)
 
104
        return [error]
 
105
 
 
106
 
 
107
Specify Directive Arguments, Options, and Content
 
108
=================================================
 
109
 
 
110
Function attributes are interpreted by the directive parser (from the
 
111
``docutils.parsers.rst.states.Body.run_directive()`` method).  If
 
112
unspecified, directive function attributes are assumed to have the
 
113
value ``None``.  Three directive function attributes are recognized:
 
114
 
 
115
- ``arguments``: A 3-tuple specifying the expected positional
 
116
  arguments, or ``None`` if the directive has no arguments.  The 3
 
117
  items in the tuple are:
 
118
 
 
119
  1. The number of required arguments.
 
120
  2. The number of optional arguments.
 
121
  3. A boolean, indicating if the final argument may contain whitespace.
 
122
 
 
123
  Arguments are normally single whitespace-separated words.  The final
 
124
  argument may contain whitespace when indicated by the value 1 (True)
 
125
  for the third item in the argument spec tuple.  In this case, the
 
126
  final argument in the ``arguments`` parameter to the directive
 
127
  function will contain spaces and/or newlines, preserved from the
 
128
  input text.
 
129
 
 
130
  If the form of the arguments is more complex, specify only one
 
131
  argument (either required or optional) and indicate that final
 
132
  whitespace is OK (1/True); the client code must do any
 
133
  context-sensitive parsing.
 
134
 
 
135
- ``options``: The option specification.  ``None`` or an empty dict
 
136
  implies no options to parse.
 
137
 
 
138
  An option specification must be defined detailing the options
 
139
  available to the directive.  An option spec is a mapping of option
 
140
  name to conversion function; conversion functions are applied to
 
141
  each option value to check validity and convert them to the expected
 
142
  type.  Python's built-in conversion functions are often usable for
 
143
  this, such as ``int``, ``float``, and ``bool`` (included in Python
 
144
  from version 2.2.1).  Other useful conversion functions are included
 
145
  in the ``docutils.parsers.rst.directives`` package (in the
 
146
  ``__init__.py`` module):
 
147
 
 
148
  - ``flag``: For options with no option arguments.  Checks for an
 
149
    argument (raises ``ValueError`` if found), returns ``None`` for
 
150
    valid flag options.
 
151
 
 
152
  - ``unchanged_required``: Returns the text argument, unchanged.
 
153
    Raises ``ValueError`` if no argument is found.
 
154
 
 
155
  - ``unchanged``: Returns the text argument, unchanged.  Returns an
 
156
    empty string ("") if no argument is found.
 
157
 
 
158
  - ``path``: Returns the path argument unwrapped (with newlines
 
159
    removed).  Raises ``ValueError`` if no argument is found.
 
160
 
 
161
  - ``uri``: Returns the URI argument with whitespace removed.  Raises
 
162
    ``ValueError`` if no argument is found.
 
163
 
 
164
  - ``nonnegative_int``: Checks for a nonnegative integer argument,
 
165
    and raises ``ValueError`` if not.
 
166
 
 
167
  - ``class_option``: Converts the argument into an ID-compatible
 
168
    string and returns it.  Raises ``ValueError`` if no argument is
 
169
    found.
 
170
 
 
171
  - ``unicode_code``: Convert a Unicode character code to a Unicode
 
172
    character.
 
173
 
 
174
  - ``single_char_or_unicode``: A single character is returned as-is.
 
175
    Unicode characters codes are converted as in ``unicode_code``.
 
176
 
 
177
  - ``single_char_or_whitespace_or_unicode``: As with
 
178
    ``single_char_or_unicode``, but "tab" and "space" are also
 
179
    supported.
 
180
 
 
181
  - ``positive_int``: Converts the argument into an integer.  Raises
 
182
    ValueError for negative, zero, or non-integer values.
 
183
 
 
184
  - ``positive_int_list``: Converts a space- or comma-separated list
 
185
    of integers into a Python list of integers.  Raises ValueError for
 
186
    non-positive-integer values.
 
187
 
 
188
  - ``encoding``: Verfies the encoding argument by lookup.  Raises
 
189
    ValueError for unknown encodings.
 
190
 
 
191
  A further utility function, ``choice``, is supplied to enable
 
192
  options whose argument must be a member of a finite set of possible
 
193
  values.  A custom conversion function must be written to use it.
 
194
  For example::
 
195
 
 
196
      from docutils.parsers.rst import directives
 
197
 
 
198
      def yesno(argument):
 
199
          return directives.choice(argument, ('yes', 'no'))
 
200
 
 
201
  For example, here is an option spec for a directive which allows two
 
202
  options, "name" and "value", each with an option argument::
 
203
 
 
204
      directive_fn.options = {'name': unchanged, 'value': int}
 
205
 
 
206
- ``content``: A boolean; true if content is allowed.  Directive
 
207
  functions must handle the case where content is required but not
 
208
  present in the input text (an empty content list will be supplied).
 
209
 
 
210
The final step of the ``run_directive()`` method is to call the
 
211
directive function itself.
 
212
 
 
213
 
 
214
Register the Directive
 
215
======================
 
216
 
 
217
If the directive is a general-use addition to the Docutils core, it
 
218
must be registered with the parser and language mappings added:
 
219
 
 
220
1. Register the new directive using its canonical name in
 
221
   ``docutils/parsers/rst/directives/__init__.py``, in the
 
222
   ``_directive_registry`` dictionary.  This allows the
 
223
   reStructuredText parser to find and use the directive.
 
224
 
 
225
2. Add an entry to the ``directives`` dictionary in
 
226
   ``docutils/parsers/rst/languages/en.py`` for the directive, mapping
 
227
   the English name to the canonical name (both lowercase).  Usually
 
228
   the English name and the canonical name are the same.
 
229
 
 
230
3. Update all the other language modules as well.  For languages in
 
231
   which you are proficient, please add translations.  For other
 
232
   languages, add the English directive name plus "(translation
 
233
   required)".
 
234
 
 
235
If the directive is application-specific, use the
 
236
``register_directive`` function::
 
237
 
 
238
    from docutils.parsers.rst import directives
 
239
    directives.register_directive(directive_name, directive_function)
 
240
 
 
241
 
 
242
Examples
 
243
========
 
244
 
 
245
For the most direct and accurate information, "Use the Source, Luke!".
 
246
All standard directives are documented in `reStructuredText
 
247
Directives`_, and the source code implementing them is located in the
 
248
``docutils/parsers/rst/directives`` package.  The ``__init__.py``
 
249
module contains a mapping of directive name to module & function name.
 
250
Several representative directives are described below.
 
251
 
 
252
 
 
253
Admonitions
 
254
-----------
 
255
 
 
256
Admonition directives, such as "note" and "caution", are quite simple.
 
257
They have no directive arguments or options.  Admonition directive
 
258
content is interpreted as ordinary reStructuredText.  The directive
 
259
function simply hands off control to a generic directive function::
 
260
 
 
261
   def note(*args):
 
262
       return admonition(nodes.note, *args)
 
263
 
 
264
   attention.content = 1
 
265
 
 
266
Note that the only thing distinguishing the various admonition
 
267
directives is the element (node class) generated.  In the code above,
 
268
the node class is passed as the first argument to the generic
 
269
directive function (early version), where the actual processing takes
 
270
place::
 
271
 
 
272
   def admonition(node_class, name, arguments, options, content, lineno,
 
273
                  content_offset, block_text, state, state_machine):
 
274
       text = '\n'.join(content)
 
275
       admonition_node = node_class(text)
 
276
       if text:
 
277
           state.nested_parse(content, content_offset, admonition_node)
 
278
           return [admonition_node]
 
279
       else:
 
280
           warning = state_machine.reporter.warning(
 
281
               'The "%s" admonition is empty; content required.'
 
282
               % (name), '',
 
283
               nodes.literal_block(block_text, block_text), line=lineno)
 
284
           return [warning]
 
285
 
 
286
Three things are noteworthy in the function above:
 
287
 
 
288
1. The ``admonition_node = node_class(text)`` line creates the wrapper
 
289
   element, using the class passed in from the initial (stub)
 
290
   directive function.
 
291
 
 
292
2. The call to ``state.nested_parse()`` is what does the actual
 
293
   processing.  It parses the directive content and adds any generated
 
294
   elements as child elements of ``admonition_node``.
 
295
 
 
296
3. If there was no directive content, a warning is generated and
 
297
   returned.  The call to ``state_machine.reporter.warning()``
 
298
   includes a literal block containing the entire directive text
 
299
   (``block_text``) and the line (``lineno``) of the top of the
 
300
   directive.
 
301
 
 
302
 
 
303
"image"
 
304
-------
 
305
 
 
306
The "image" directive is used to insert a picture into a document.
 
307
This directive has one argument, the path to the image file, and
 
308
supports several options.  There is no directive content.  Here's an
 
309
early version of the image directive function::
 
310
 
 
311
    def image(name, arguments, options, content, lineno,
 
312
              content_offset, block_text, state, state_machine):
 
313
        reference = directives.uri(arguments[0])
 
314
        options['uri'] = reference
 
315
        image_node = nodes.image(block_text, **options)
 
316
        return [image_node]
 
317
 
 
318
    image.arguments = (1, 0, 1)
 
319
    image.options = {'alt': directives.unchanged,
 
320
                     'height': directives.nonnegative_int,
 
321
                     'width': directives.nonnegative_int,
 
322
                     'scale': directives.nonnegative_int,
 
323
                     'align': align}
 
324
 
 
325
Several things are noteworthy in the code above:
 
326
 
 
327
1. The "image" directive requires a single argument, which is allowed
 
328
   to contain whitespace (see the argument spec above,
 
329
   ``image.arguments = (1, 0, 1)``).  This is to allow for long URLs
 
330
   which may span multiple lines.  The first line of the ``image``
 
331
   function joins the URL, discarding any embedded whitespace.
 
332
 
 
333
2. The reference is added to the ``options`` dictionary under the
 
334
   "uri" key; this becomes an attribute of the ``nodes.image`` element
 
335
   object.  Any other attributes have already been set explicitly in
 
336
   the source text.
 
337
 
 
338
3. The "align" option depends on the following definitions (which
 
339
   actually occur earlier in the source code)::
 
340
 
 
341
       align_values = ('top', 'middle', 'bottom', 'left', 'center',
 
342
                       'right')
 
343
 
 
344
       def align(argument):
 
345
           return directives.choice(argument, align_values)
 
346
 
 
347
 
 
348
"contents"
 
349
----------
 
350
 
 
351
The "contents" directive is used to insert an auto-generated table of
 
352
contents (TOC) into a document.  It takes one optional argument, a
 
353
title for the TOC.  If no title is specified, a default title is used
 
354
instead.  The directive also handles several options.  Here's an early
 
355
version of the code::
 
356
 
 
357
    def contents(name, arguments, options, content, lineno,
 
358
                 content_offset, block_text, state, state_machine):
 
359
        """Table of contents."""
 
360
        if arguments:
 
361
            title_text = arguments[0]
 
362
            text_nodes, messages = state.inline_text(title_text, lineno)
 
363
            title = nodes.title(title_text, '', *text_nodes)
 
364
        else:
 
365
            messages = []
 
366
            title = None
 
367
        pending = nodes.pending(parts.Contents, {'title': title},
 
368
                                block_text)
 
369
        pending.details.update(options)
 
370
        state_machine.document.note_pending(pending)
 
371
        return [pending] + messages
 
372
 
 
373
    contents.arguments = (0, 1, 1)
 
374
    contents.options = {'depth': directives.nonnegative_int,
 
375
                        'local': directives.flag,
 
376
                        'backlinks': backlinks}
 
377
 
 
378
Aspects of note include:
 
379
 
 
380
1. The ``contents.arguments = (0, 1, 1)`` function attribute specifies
 
381
   a single, *optional* argument.  If no argument is present, the
 
382
   ``arguments`` parameter to the directive function will be an empty
 
383
   list.
 
384
 
 
385
2. If an argument *is* present, its text is passed to
 
386
   ``state.inline_text()`` for parsing.  Titles may contain inline
 
387
   markup, such as emphasis or inline literals.
 
388
 
 
389
3. The table of contents is not generated right away.  Typically, a
 
390
   TOC is placed near the beginning of a document, and is a summary or
 
391
   outline of the section structure of the document.  The entire
 
392
   document must already be processed before a summary can be made.
 
393
   This directive leaves a ``nodes.pending`` placeholder element in
 
394
   the document tree, marking the position of the TOC and including a
 
395
   ``details`` internal attribute containing all the directive
 
396
   options, effectively communicating the options forward.  The actual
 
397
   table of contents processing is performed by a transform,
 
398
   ``docutils.transforms.parts.Contents``, after the rest of the
 
399
   document has been parsed.