Completed
Pull Request — master (#17)
by
unknown
01:20
created

sdoc.sdoc2.node.Node.is_block_command()   A

Complexity

Conditions 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 8
rs 9.4285
1
"""
2
SDoc
3
4
Copyright 2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8
# ----------------------------------------------------------------------------------------------------------------------
9
import abc
10
from sdoc.sdoc2 import in_scope, out_scope, node_store
11
12
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
0 ignored issues
show
Coding Style Naming introduced by
The name id does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

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.

Loading history...
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
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
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
Unused Code introduced by
The argument parent_hierarchy_level seems to be unused.
Loading history...
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
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
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
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
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
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
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
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
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
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:
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
284
                    node_store.labels[node._argument] = self._options['number']
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
285
                else:
286
                    raise NameError('Duplicate label', node._argument)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
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
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
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':
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
313
                node._options['href'] = node._argument
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _options was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
314
                node._argument = node_store.labels[node._argument]
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _argument was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
315
316
            node.change_ref_argument()
317
318
            out_scope(node)
319
320
# ----------------------------------------------------------------------------------------------------------------------
321