Total Complexity | 36 |
Total Lines | 306 |
Duplicated Lines | 0 % |
1 | """ |
||
13 | class Node: |
||
14 | """ |
||
15 | Abstract class for SDoc2 nodes. |
||
16 | """ |
||
17 | |||
18 | # ------------------------------------------------------------------------------------------------------------------ |
||
19 | def __init__(self, name, options=None, argument=''): |
||
20 | """ |
||
21 | Object constructor. |
||
22 | |||
23 | :param str name: The (command) name of this node. |
||
24 | :param dict[str,str] options: The options of this node. |
||
25 | :param str argument: The argument of this node (inline commands only). |
||
26 | """ |
||
27 | self.id = 0 |
||
|
|||
28 | """ |
||
29 | The ID of this SDoc2 node. |
||
30 | |||
31 | :type: int |
||
32 | """ |
||
33 | |||
34 | self.name = name |
||
35 | """ |
||
36 | The (command) name of this node. |
||
37 | |||
38 | :type: str |
||
39 | """ |
||
40 | |||
41 | self._argument = argument |
||
42 | """ |
||
43 | The argument of this node (inline commands only). |
||
44 | |||
45 | :type: str |
||
46 | """ |
||
47 | |||
48 | self._options = options if options else {} |
||
49 | """ |
||
50 | The options of this node. |
||
51 | |||
52 | :type: dict[str,int|str] |
||
53 | """ |
||
54 | |||
55 | self.child_nodes = [] |
||
56 | """ |
||
57 | The ID's of the SDoc2 child nodes of this SDoc2 node. |
||
58 | |||
59 | :type: list[int] |
||
60 | """ |
||
61 | |||
62 | self.position = None |
||
63 | """ |
||
64 | The position where this node is defined. |
||
65 | |||
66 | :type: None|sdoc.sdoc2.Position.Position |
||
67 | """ |
||
68 | |||
69 | self.labels = [] |
||
70 | """ |
||
71 | The list of labels in the node. |
||
72 | |||
73 | :type: |
||
74 | """ |
||
75 | |||
76 | # ------------------------------------------------------------------------------------------------------------------ |
||
77 | @property |
||
78 | def argument(self): |
||
79 | """ |
||
80 | Getter for argument. |
||
81 | |||
82 | :rtype: str |
||
83 | """ |
||
84 | return self._argument |
||
85 | |||
86 | # ------------------------------------------------------------------------------------------------------------------ |
||
87 | def print_info(self, level): |
||
88 | """ |
||
89 | Temp function for development. |
||
90 | |||
91 | :param int level: the level of block commands. |
||
92 | """ |
||
93 | print("{0!s}{1:4d} {2!s}".format(' ' * 4 * level, self.id, self.name)) |
||
94 | for node_id in self.child_nodes: |
||
95 | node = in_scope(node_id) |
||
96 | |||
97 | node.print_info(level + 1) |
||
98 | |||
99 | out_scope(node) |
||
100 | |||
101 | # ------------------------------------------------------------------------------------------------------------------ |
||
102 | def get_hierarchy_name(self): |
||
1 ignored issue
–
show
|
|||
103 | """ |
||
104 | Returns the hierarchy name if this node is a part of a hierarchy. Otherwise returns False. |
||
105 | |||
106 | :rtype: str|bool |
||
107 | """ |
||
108 | return False |
||
109 | |||
110 | # ------------------------------------------------------------------------------------------------------------------ |
||
111 | @abc.abstractmethod |
||
112 | def get_command(self): |
||
113 | """ |
||
114 | Returns command of this node. |
||
115 | |||
116 | :rtype: str |
||
117 | """ |
||
118 | raise NotImplementedError() |
||
119 | |||
120 | # ------------------------------------------------------------------------------------------------------------------ |
||
121 | def get_hierarchy_level(self, parent_hierarchy_level=-1): |
||
2 ignored issues
–
show
|
|||
122 | """ |
||
123 | Returns the hierarchy level if this node is a part of a hierarchy. |
||
124 | |||
125 | :param int parent_hierarchy_level: The hierarchy level of the parent node in the same hierarchy. |
||
126 | |||
127 | :rtype: int |
||
128 | """ |
||
129 | raise RuntimeError("This method MUST only be called when a node is a part of an hierarchy.") |
||
130 | |||
131 | # ------------------------------------------------------------------------------------------------------------------ |
||
132 | def get_option_value(self, option_name): |
||
133 | """ |
||
134 | Returns the value of an option. Returns None if the option is not set. |
||
135 | |||
136 | :param str option_name: The name of the option. |
||
137 | |||
138 | :rtype: str |
||
139 | """ |
||
140 | return self._options[option_name] if option_name in self._options else None |
||
141 | |||
142 | # ------------------------------------------------------------------------------------------------------------------ |
||
143 | @abc.abstractmethod |
||
144 | def is_block_command(self): |
||
145 | """ |
||
146 | Returns True if this node is created by a block command. Otherwise returns False. |
||
147 | |||
148 | :rtype: bool |
||
149 | """ |
||
150 | raise NotImplementedError() |
||
151 | |||
152 | # ------------------------------------------------------------------------------------------------------------------ |
||
153 | def is_document_root(self): |
||
1 ignored issue
–
show
|
|||
154 | """ |
||
155 | Returns True if this node is a document root node. Otherwise returns False. |
||
156 | |||
157 | :rtype: bool |
||
158 | """ |
||
159 | return False |
||
160 | |||
161 | # ------------------------------------------------------------------------------------------------------------------ |
||
162 | def is_hierarchy_root(self): |
||
1 ignored issue
–
show
|
|||
163 | """ |
||
164 | Returns True if this node can be the root of a hierarchy. Otherwise returns False. |
||
165 | |||
166 | :rtype: bool |
||
167 | """ |
||
168 | return False |
||
169 | |||
170 | # ------------------------------------------------------------------------------------------------------------------ |
||
171 | @abc.abstractmethod |
||
172 | def is_inline_command(self): |
||
173 | """ |
||
174 | Returns True if this node is created by a inline command. Otherwise returns False. |
||
175 | |||
176 | :rtype: bool |
||
177 | """ |
||
178 | raise NotImplementedError() |
||
179 | |||
180 | # ------------------------------------------------------------------------------------------------------------------ |
||
181 | def is_phrasing(self): |
||
1 ignored issue
–
show
|
|||
182 | """ |
||
183 | Returns True if this node is a phrasing node, i.e. is a part of a paragraph. Otherwise returns False. |
||
184 | |||
185 | :rtype: bool |
||
186 | """ |
||
187 | return False |
||
188 | |||
189 | # ------------------------------------------------------------------------------------------------------------------ |
||
190 | def is_list_element(self): |
||
1 ignored issue
–
show
|
|||
191 | """ |
||
192 | Returns True if this node is a list element, e.g. an item in itemize. Otherwise returns False. |
||
193 | |||
194 | :rtype: bool |
||
195 | """ |
||
196 | return False |
||
197 | |||
198 | # ------------------------------------------------------------------------------------------------------------------ |
||
199 | def append_child_node(self, child_node): |
||
200 | """ |
||
201 | Appends a child node to the list of child nodes of the node. |
||
202 | |||
203 | :param sdoc.sdoc2.node.Node.Node child_node: The new child node |
||
204 | """ |
||
205 | self.child_nodes.append(child_node.id) |
||
206 | |||
207 | # ------------------------------------------------------------------------------------------------------------------ |
||
208 | def prepare_content_tree(self): |
||
209 | """ |
||
210 | Prepares this node for further processing. |
||
211 | """ |
||
212 | for node_id in self.child_nodes: |
||
213 | node = in_scope(node_id) |
||
214 | |||
215 | node.prepare_content_tree() |
||
216 | |||
217 | out_scope(node) |
||
218 | |||
219 | # ------------------------------------------------------------------------------------------------------------------ |
||
220 | def number(self, numbers): |
||
221 | """ |
||
222 | Numbers all numerable nodes such as chapters, sections, figures, and, items. |
||
223 | |||
224 | :param numbers: The current numbers. |
||
225 | """ |
||
226 | for node_id in self.child_nodes: |
||
227 | node = in_scope(node_id) |
||
228 | |||
229 | node.number(numbers) |
||
230 | |||
231 | out_scope(node) |
||
232 | |||
233 | # ------------------------------------------------------------------------------------------------------------------ |
||
234 | def get_enumerated_items(self): |
||
235 | """ |
||
236 | Returns a list with a tuple with command and number of enumerated child nodes. |
||
237 | |||
238 | Thi method is intended for unit test only. |
||
239 | |||
240 | :rtype: list[(str,str)] |
||
241 | """ |
||
242 | items = list() |
||
243 | |||
244 | # First append the enumeration of this node (if any). |
||
245 | if 'number' in self._options: |
||
246 | items.append((self.get_command(), self._options['number'], self._argument)) |
||
247 | |||
248 | # Second append the enumeration of child nodes (if any). |
||
249 | for node_id in self.child_nodes: |
||
250 | node = in_scope(node_id) |
||
251 | |||
252 | tmp = node.get_enumerated_items() |
||
253 | if tmp: |
||
254 | items.append(tmp) |
||
255 | |||
256 | out_scope(node) |
||
257 | |||
258 | return items |
||
259 | |||
260 | # ------------------------------------------------------------------------------------------------------------------ |
||
261 | def parse_labels(self): |
||
262 | """ |
||
263 | Parses all labels and call methods to collect labels.and for |
||
264 | """ |
||
265 | self.modify_label_list() |
||
266 | |||
267 | if self.labels: |
||
268 | self.set_id_heading_node() |
||
269 | |||
270 | # ------------------------------------------------------------------------------------------------------------------ |
||
271 | def modify_label_list(self): |
||
272 | """ |
||
273 | Creates label list for each heading node, and for node_store. Removes label nodes from child list. |
||
274 | """ |
||
275 | for node_id in self.child_nodes: |
||
276 | node = in_scope(node_id) |
||
277 | |||
278 | if node.get_command() == 'label': |
||
279 | # Appending in Node labels list. |
||
280 | self.labels.append(node.id) |
||
281 | |||
282 | # Appending in NodeStore labels list. |
||
283 | if node._argument not in node_store.labels: |
||
284 | node_store.labels[node._argument] = self._options['number'] |
||
285 | else: |
||
286 | raise NameError('Duplicate label', node._argument) |
||
287 | |||
288 | # Removing node from child nodes. |
||
289 | self.child_nodes.remove(node.id) |
||
290 | |||
291 | node.parse_labels() |
||
292 | |||
293 | out_scope(node) |
||
294 | |||
295 | # ------------------------------------------------------------------------------------------------------------------ |
||
296 | def set_id_heading_node(self): |
||
297 | """ |
||
298 | Sets id to heading node. (Argument of first label) |
||
299 | """ |
||
300 | node = in_scope(self.labels[0]) |
||
301 | self._options['id'] = node._argument |
||
302 | out_scope(node) |
||
303 | |||
304 | # ------------------------------------------------------------------------------------------------------------------ |
||
305 | def change_ref_argument(self): |
||
306 | """ |
||
307 | Changes reference argument on number of depending heading node. |
||
308 | """ |
||
309 | for node_id in self.child_nodes: |
||
310 | node = in_scope(node_id) |
||
311 | |||
312 | if node._argument in node_store.labels and node.get_command() == 'ref': |
||
313 | node._options['href'] = node._argument |
||
314 | node._argument = node_store.labels[node._argument] |
||
315 | |||
316 | node.change_ref_argument() |
||
317 | |||
318 | out_scope(node) |
||
319 | |||
321 |
This check looks for invalid names for a range of different identifiers.
You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.
If your project includes a Pylint configuration file, the settings contained in that file take precedence.
To find out more about Pylint, please refer to their site.