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