root/galaxy-central/eggs/docutils-0.4-py2.6.egg/docutils/transforms/__init__.py @ 3

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

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

行番号 
1# Authors: David Goodger, Ueli Schlaepfer
2# Contact: goodger@users.sourceforge.net
3# Revision: $Revision: 3892 $
4# Date: $Date: 2005-09-20 22:04:53 +0200 (Tue, 20 Sep 2005) $
5# Copyright: This module has been placed in the public domain.
6
7"""
8This package contains modules for standard tree transforms available
9to Docutils components. Tree transforms serve a variety of purposes:
10
11- To tie up certain syntax-specific "loose ends" that remain after the
12  initial parsing of the input plaintext. These transforms are used to
13  supplement a limited syntax.
14
15- To automate the internal linking of the document tree (hyperlink
16  references, footnote references, etc.).
17
18- To extract useful information from the document tree. These
19  transforms may be used to construct (for example) indexes and tables
20  of contents.
21
22Each transform is an optional step that a Docutils Reader may choose to
23perform on the parsed document, depending on the input context. A Docutils
24Reader may also perform Reader-specific transforms before or after performing
25these standard transforms.
26"""
27
28__docformat__ = 'reStructuredText'
29
30
31from docutils import languages, ApplicationError, TransformSpec
32
33
34class TransformError(ApplicationError): pass
35
36
37class Transform:
38
39    """
40    Docutils transform component abstract base class.
41    """
42
43    default_priority = None
44    """Numerical priority of this transform, 0 through 999 (override)."""
45
46    def __init__(self, document, startnode=None):
47        """
48        Initial setup for in-place document transforms.
49        """
50
51        self.document = document
52        """The document tree to transform."""
53
54        self.startnode = startnode
55        """Node from which to begin the transform.  For many transforms which
56        apply to the document as a whole, `startnode` is not set (i.e. its
57        value is `None`)."""
58
59        self.language = languages.get_language(
60            document.settings.language_code)
61        """Language module local to this document."""
62
63    def apply(self, **kwargs):
64        """Override to apply the transform to the document tree."""
65        raise NotImplementedError('subclass must override this method')
66
67
68class Transformer(TransformSpec):
69
70    """
71    Stores transforms (`Transform` classes) and applies them to document
72    trees.  Also keeps track of components by component type name.
73    """
74
75    def __init__(self, document):
76        self.transforms = []
77        """List of transforms to apply.  Each item is a 3-tuple:
78        ``(priority string, transform class, pending node or None)``."""
79
80        self.unknown_reference_resolvers = []
81        """List of hook functions which assist in resolving references"""
82
83        self.document = document
84        """The `nodes.document` object this Transformer is attached to."""
85
86        self.applied = []
87        """Transforms already applied, in order."""
88
89        self.sorted = 0
90        """Boolean: is `self.tranforms` sorted?"""
91
92        self.components = {}
93        """Mapping of component type name to component object.  Set by
94        `self.populate_from_components()`."""
95
96        self.serialno = 0
97        """Internal serial number to keep track of the add order of
98        transforms."""
99
100    def add_transform(self, transform_class, priority=None, **kwargs):
101        """
102        Store a single transform.  Use `priority` to override the default.
103        `kwargs` is a dictionary whose contents are passed as keyword
104        arguments to the `apply` method of the transform.  This can be used to
105        pass application-specific data to the transform instance.
106        """
107        if priority is None:
108            priority = transform_class.default_priority
109        priority_string = self.get_priority_string(priority)
110        self.transforms.append(
111            (priority_string, transform_class, None, kwargs))
112        self.sorted = 0
113
114    def add_transforms(self, transform_list):
115        """Store multiple transforms, with default priorities."""
116        for transform_class in transform_list:
117            priority_string = self.get_priority_string(
118                transform_class.default_priority)
119            self.transforms.append(
120                (priority_string, transform_class, None, {}))
121        self.sorted = 0
122
123    def add_pending(self, pending, priority=None):
124        """Store a transform with an associated `pending` node."""
125        transform_class = pending.transform
126        if priority is None:
127            priority = transform_class.default_priority
128        priority_string = self.get_priority_string(priority)
129        self.transforms.append(
130            (priority_string, transform_class, pending, {}))
131        self.sorted = 0
132
133    def get_priority_string(self, priority):
134        """
135        Return a string, `priority` combined with `self.serialno`.
136
137        This ensures FIFO order on transforms with identical priority.
138        """
139        self.serialno += 1
140        return '%03d-%03d' % (priority, self.serialno)
141
142    def populate_from_components(self, components):
143        """
144        Store each component's default transforms, with default priorities.
145        Also, store components by type name in a mapping for later lookup.
146        """
147        for component in components:
148            if component is None:
149                continue
150            self.add_transforms(component.get_transforms())
151            self.components[component.component_type] = component
152        self.sorted = 0
153        # Set up all of the reference resolvers for this transformer. Each
154        # component of this transformer is able to register its own helper
155        # functions to help resolve references.
156        unknown_reference_resolvers = []
157        for i in components:
158            unknown_reference_resolvers.extend(i.unknown_reference_resolvers)
159        decorated_list = [(f.priority, f) for f in unknown_reference_resolvers]
160        decorated_list.sort()
161        self.unknown_reference_resolvers.extend([f[1] for f in decorated_list])
162
163    def apply_transforms(self):
164        """Apply all of the stored transforms, in priority order."""
165        self.document.reporter.attach_observer(
166            self.document.note_transform_message)
167        while self.transforms:
168            if not self.sorted:
169                # Unsorted initially, and whenever a transform is added.
170                self.transforms.sort()
171                self.transforms.reverse()
172                self.sorted = 1
173            priority, transform_class, pending, kwargs = self.transforms.pop()
174            transform = transform_class(self.document, startnode=pending)
175            transform.apply(**kwargs)
176            self.applied.append((priority, transform_class, pending, kwargs))
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。