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)) |
