root/galaxy-central/eggs/docutils-0.4-py2.6.egg/docutils/parsers/rst/directives/__init__.py

リビジョン 3, 15.5 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# Author: David Goodger
2# Contact: goodger@python.org
3# Revision: $Revision: 4229 $
4# Date: $Date: 2005-12-23 00:46:16 +0100 (Fri, 23 Dec 2005) $
5# Copyright: This module has been placed in the public domain.
6
7"""
8This package contains directive implementation modules.
9
10The interface for directive functions is as follows::
11
12    def directive_fn(name, arguments, options, content, lineno,
13                     content_offset, block_text, state, state_machine):
14        code...
15
16    # Set function attributes:
17    directive_fn.arguments = ...
18    directive_fn.options = ...
19    direcitve_fn.content = ...
20
21Parameters:
22
23- ``name`` is the directive type or name (string).
24
25- ``arguments`` is a list of positional arguments (strings).
26
27- ``options`` is a dictionary mapping option names (strings) to values (type
28  depends on option conversion functions; see below).
29
30- ``content`` is a list of strings, the directive content.
31
32- ``lineno`` is the line number of the first line of the directive.
33
34- ``content_offset`` is the line offset of the first line of the content from
35  the beginning of the current input.  Used when initiating a nested parse.
36
37- ``block_text`` is a string containing the entire directive.  Include it as
38  the content of a literal block in a system message if there is a problem.
39
40- ``state`` is the state which called the directive function.
41
42- ``state_machine`` is the state machine which controls the state which called
43  the directive function.
44
45Function attributes, interpreted by the directive parser (which calls the
46directive function):
47
48- ``arguments``: A 3-tuple specifying the expected positional arguments, or
49  ``None`` if the directive has no arguments.  The 3 items in the tuple are
50  ``(required, optional, whitespace OK in last argument)``:
51
52  1. The number of required arguments.
53  2. The number of optional arguments.
54  3. A boolean, indicating if the final argument may contain whitespace.
55
56  Arguments are normally single whitespace-separated words.  The final
57  argument may contain whitespace if the third item in the argument spec tuple
58  is 1/True.  If the form of the arguments is more complex, specify only one
59  argument (either required or optional) and indicate that final whitespace is
60  OK; the client code must do any context-sensitive parsing.
61
62- ``options``: A dictionary, mapping known option names to conversion
63  functions such as `int` or `float`.  ``None`` or an empty dict implies no
64  options to parse.  Several directive option conversion functions are defined
65  in this module.
66
67  Option conversion functions take a single parameter, the option argument (a
68  string or ``None``), validate it and/or convert it to the appropriate form.
69  Conversion functions may raise ``ValueError`` and ``TypeError`` exceptions.
70
71- ``content``: A boolean; true if content is allowed.  Client code must handle
72  the case where content is required but not supplied (an empty content list
73  will be supplied).
74
75Directive functions return a list of nodes which will be inserted into the
76document tree at the point where the directive was encountered (can be an
77empty list).
78
79See `Creating reStructuredText Directives`_ for more information.
80
81.. _Creating reStructuredText Directives:
82   http://docutils.sourceforge.net/docs/howto/rst-directives.html
83"""
84
85__docformat__ = 'reStructuredText'
86
87import re
88import codecs
89from docutils import nodes
90from docutils.parsers.rst.languages import en as _fallback_language_module
91
92
93_directive_registry = {
94      'attention': ('admonitions', 'attention'),
95      'caution': ('admonitions', 'caution'),
96      'danger': ('admonitions', 'danger'),
97      'error': ('admonitions', 'error'),
98      'important': ('admonitions', 'important'),
99      'note': ('admonitions', 'note'),
100      'tip': ('admonitions', 'tip'),
101      'hint': ('admonitions', 'hint'),
102      'warning': ('admonitions', 'warning'),
103      'admonition': ('admonitions', 'admonition'),
104      'sidebar': ('body', 'sidebar'),
105      'topic': ('body', 'topic'),
106      'line-block': ('body', 'line_block'),
107      'parsed-literal': ('body', 'parsed_literal'),
108      'rubric': ('body', 'rubric'),
109      'epigraph': ('body', 'epigraph'),
110      'highlights': ('body', 'highlights'),
111      'pull-quote': ('body', 'pull_quote'),
112      'compound': ('body', 'compound'),
113      'container': ('body', 'container'),
114      #'questions': ('body', 'question_list'),
115      'table': ('tables', 'table'),
116      'csv-table': ('tables', 'csv_table'),
117      'list-table': ('tables', 'list_table'),
118      'image': ('images', 'image'),
119      'figure': ('images', 'figure'),
120      'contents': ('parts', 'contents'),
121      'sectnum': ('parts', 'sectnum'),
122      'header': ('parts', 'header'),
123      'footer': ('parts', 'footer'),
124      #'footnotes': ('parts', 'footnotes'),
125      #'citations': ('parts', 'citations'),
126      'target-notes': ('references', 'target_notes'),
127      'meta': ('html', 'meta'),
128      #'imagemap': ('html', 'imagemap'),
129      'raw': ('misc', 'raw'),
130      'include': ('misc', 'include'),
131      'replace': ('misc', 'replace'),
132      'unicode': ('misc', 'unicode_directive'),
133      'class': ('misc', 'class_directive'),
134      'role': ('misc', 'role'),
135      'default-role': ('misc', 'default_role'),
136      'title': ('misc', 'title'),
137      'date': ('misc', 'date'),
138      'restructuredtext-test-directive': ('misc', 'directive_test_function'),}
139"""Mapping of directive name to (module name, function name).  The directive
140name is canonical & must be lowercase.  Language-dependent names are defined
141in the ``language`` subpackage."""
142
143_modules = {}
144"""Cache of imported directive modules."""
145
146_directives = {}
147"""Cache of imported directive functions."""
148
149def directive(directive_name, language_module, document):
150    """
151    Locate and return a directive function from its language-dependent name.
152    If not found in the current language, check English.  Return None if the
153    named directive cannot be found.
154    """
155    normname = directive_name.lower()
156    messages = []
157    msg_text = []
158    if _directives.has_key(normname):
159        return _directives[normname], messages
160    canonicalname = None
161    try:
162        canonicalname = language_module.directives[normname]
163    except AttributeError, error:
164        msg_text.append('Problem retrieving directive entry from language '
165                        'module %r: %s.' % (language_module, error))
166    except KeyError:
167        msg_text.append('No directive entry for "%s" in module "%s".'
168                        % (directive_name, language_module.__name__))
169    if not canonicalname:
170        try:
171            canonicalname = _fallback_language_module.directives[normname]
172            msg_text.append('Using English fallback for directive "%s".'
173                            % directive_name)
174        except KeyError:
175            msg_text.append('Trying "%s" as canonical directive name.'
176                            % directive_name)
177            # The canonical name should be an English name, but just in case:
178            canonicalname = normname
179    if msg_text:
180        message = document.reporter.info(
181            '\n'.join(msg_text), line=document.current_line)
182        messages.append(message)
183    try:
184        modulename, functionname = _directive_registry[canonicalname]
185    except KeyError:
186        # Error handling done by caller.
187        return None, messages
188    if _modules.has_key(modulename):
189        module = _modules[modulename]
190    else:
191        try:
192            module = __import__(modulename, globals(), locals())
193        except ImportError, detail:
194            messages.append(document.reporter.error(
195                'Error importing directive module "%s" (directive "%s"):\n%s'
196                % (modulename, directive_name, detail),
197                line=document.current_line))
198            return None, messages
199    try:
200        function = getattr(module, functionname)
201        _directives[normname] = function
202    except AttributeError:
203        messages.append(document.reporter.error(
204            'No function "%s" in module "%s" (directive "%s").'
205            % (functionname, modulename, directive_name),
206            line=document.current_line))
207        return None, messages
208    return function, messages
209
210def register_directive(name, directive_function):
211    """
212    Register a nonstandard application-defined directive function.
213    Language lookups are not needed for such functions.
214    """
215    _directives[name] = directive_function
216
217def flag(argument):
218    """
219    Check for a valid flag option (no argument) and return ``None``.
220    (Directive option conversion function.)
221
222    Raise ``ValueError`` if an argument is found.
223    """
224    if argument and argument.strip():
225        raise ValueError('no argument is allowed; "%s" supplied' % argument)
226    else:
227        return None
228
229def unchanged_required(argument):
230    """
231    Return the argument text, unchanged.
232    (Directive option conversion function.)
233
234    Raise ``ValueError`` if no argument is found.
235    """
236    if argument is None:
237        raise ValueError('argument required but none supplied')
238    else:
239        return argument  # unchanged!
240
241def unchanged(argument):
242    """
243    Return the argument text, unchanged.
244    (Directive option conversion function.)
245
246    No argument implies empty string ("").
247    """
248    if argument is None:
249        return u''
250    else:
251        return argument  # unchanged!
252
253def path(argument):
254    """
255    Return the path argument unwrapped (with newlines removed).
256    (Directive option conversion function.)
257
258    Raise ``ValueError`` if no argument is found.
259    """
260    if argument is None:
261        raise ValueError('argument required but none supplied')
262    else:
263        path = ''.join([s.strip() for s in argument.splitlines()])
264        return path
265
266def uri(argument):
267    """
268    Return the URI argument with whitespace removed.
269    (Directive option conversion function.)
270
271    Raise ``ValueError`` if no argument is found.
272    """
273    if argument is None:
274        raise ValueError('argument required but none supplied')
275    else:
276        uri = ''.join(argument.split())
277        return uri
278
279def nonnegative_int(argument):
280    """
281    Check for a nonnegative integer argument; raise ``ValueError`` if not.
282    (Directive option conversion function.)
283    """
284    value = int(argument)
285    if value < 0:
286        raise ValueError('negative value; must be positive or zero')
287    return value
288
289length_units = ['em', 'ex', 'px', 'in', 'cm', 'mm', 'pt', 'pc']
290
291def get_measure(argument, units):
292    """
293    Check for a positive argument of one of the units and return a
294    normalized string of the form "<value><unit>" (without space in
295    between).
296   
297    To be called from directive option conversion functions.
298    """
299    match = re.match(r'^([0-9.]+) *(%s)$' % '|'.join(units), argument)
300    try:
301        assert match is not None
302        float(match.group(1))
303    except (AssertionError, ValueError):
304        raise ValueError(
305            'not a positive measure of one of the following units:\n%s'
306            % ' '.join(['"%s"' % i for i in units]))
307    return match.group(1) + match.group(2)
308
309def length_or_unitless(argument):
310    return get_measure(argument, length_units + [''])
311
312def length_or_percentage_or_unitless(argument):
313    return get_measure(argument, length_units + ['%', ''])
314
315def class_option(argument):
316    """
317    Convert the argument into a list of ID-compatible strings and return it.
318    (Directive option conversion function.)
319
320    Raise ``ValueError`` if no argument is found.
321    """
322    if argument is None:
323        raise ValueError('argument required but none supplied')
324    names = argument.split()
325    class_names = []
326    for name in names:
327        class_name = nodes.make_id(name)
328        if not class_name:
329            raise ValueError('cannot make "%s" into a class name' % name)
330        class_names.append(class_name)
331    return class_names
332
333unicode_pattern = re.compile(
334    r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE)
335
336def unicode_code(code):
337    r"""
338    Convert a Unicode character code to a Unicode character.
339    (Directive option conversion function.)
340
341    Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``,
342    ``x``, ``\x``, ``U+``, ``u``, or ``\u``; e.g. ``U+262E``), or XML-style
343    numeric character entities (e.g. ``&#x262E;``).  Other text remains as-is.
344
345    Raise ValueError for illegal Unicode code values.
346    """
347    try:
348        if code.isdigit():                  # decimal number
349            return unichr(int(code))
350        else:
351            match = unicode_pattern.match(code)
352            if match:                       # hex number
353                value = match.group(1) or match.group(2)
354                return unichr(int(value, 16))
355            else:                           # other text
356                return code
357    except OverflowError, detail:
358        raise ValueError('code too large (%s)' % detail)
359
360def single_char_or_unicode(argument):
361    """
362    A single character is returned as-is.  Unicode characters codes are
363    converted as in `unicode_code`.  (Directive option conversion function.)
364    """
365    char = unicode_code(argument)
366    if len(char) > 1:
367        raise ValueError('%r invalid; must be a single character or '
368                         'a Unicode code' % char)
369    return char
370
371def single_char_or_whitespace_or_unicode(argument):
372    """
373    As with `single_char_or_unicode`, but "tab" and "space" are also supported.
374    (Directive option conversion function.)
375    """
376    if argument == 'tab':
377        char = '\t'
378    elif argument == 'space':
379        char = ' '
380    else:
381        char = single_char_or_unicode(argument)
382    return char
383
384def positive_int(argument):
385    """
386    Converts the argument into an integer.  Raises ValueError for negative,
387    zero, or non-integer values.  (Directive option conversion function.)
388    """
389    value = int(argument)
390    if value < 1:
391        raise ValueError('negative or zero value; must be positive')
392    return value
393
394def positive_int_list(argument):
395    """
396    Converts a space- or comma-separated list of values into a Python list
397    of integers.
398    (Directive option conversion function.)
399
400    Raises ValueError for non-positive-integer values.
401    """
402    if ',' in argument:
403        entries = argument.split(',')
404    else:
405        entries = argument.split()
406    return [positive_int(entry) for entry in entries]
407
408def encoding(argument):
409    """
410    Verfies the encoding argument by lookup.
411    (Directive option conversion function.)
412
413    Raises ValueError for unknown encodings.
414    """
415    try:
416        codecs.lookup(argument)
417    except LookupError:
418        raise ValueError('unknown encoding: "%s"' % argument)
419    return argument
420
421def choice(argument, values):
422    """
423    Directive option utility function, supplied to enable options whose
424    argument must be a member of a finite set of possible values (must be
425    lower case).  A custom conversion function must be written to use it.  For
426    example::
427
428        from docutils.parsers.rst import directives
429
430        def yesno(argument):
431            return directives.choice(argument, ('yes', 'no'))
432
433    Raise ``ValueError`` if no argument is found or if the argument's value is
434    not valid (not an entry in the supplied list).
435    """
436    try:
437        value = argument.lower().strip()
438    except AttributeError:
439        raise ValueError('must supply an argument; choose from %s'
440                         % format_values(values))
441    if value in values:
442        return value
443    else:
444        raise ValueError('"%s" unknown; choose from %s'
445                         % (argument, format_values(values)))
446
447def format_values(values):
448    return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]),
449                            values[-1])
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。