Completed
Push — master ( c0c100...b6926c )
by P.R.
02:23
created

HeadingNode   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Test Coverage

Coverage 86.44%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 21
c 3
b 0
f 0
dl 0
loc 150
ccs 51
cts 59
cp 0.8644
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A get_hierarchy_name() 0 7 1
A is_block_command() 0 7 1
A __init__() 0 10 1
A number() 0 16 2
A is_inline_command() 0 7 1
C create_paragraphs() 0 39 7
A set_toc_id() 0 11 3
A split_text_nodes() 0 20 4
A prepare_content_tree() 0 11 1
1
"""
2
SDoc
3
4
Copyright 2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8
# ----------------------------------------------------------------------------------------------------------------------
9 1
import sdoc
10 1
from sdoc.sdoc2 import in_scope, out_scope
11 1
from sdoc.sdoc2.helper.Enumerable import Enumerable
12 1
from sdoc.sdoc2.node.EndParagraphNode import EndParagraphNode
13 1
from sdoc.sdoc2.node.Node import Node
14 1
from sdoc.sdoc2.node.TextNode import TextNode
15
16
17 1
class HeadingNode(Node):
0 ignored issues
show
Bug introduced by
The method get_command which was declared abstract in the super-class Node
was not overridden.

Methods which raise NotImplementedError should be overridden in concrete child classes.

Loading history...
18
    """
19
    Abstract class for heading nodes.
20
    """
21
22
    # ------------------------------------------------------------------------------------------------------------------
23 1
    def __init__(self, io, name, options, argument):
24
        """
25
        Object constructor.
26
27
        :param None|cleo.styles.output_style.OutputStyle io: The IO object.
28
        :param str name: The (command) name of this heading.
29
        :param dict[str,str] options: The options of this heading.
30
        :param str argument: The title of this heading.
31
        """
32 1
        super().__init__(io, name, options, argument)
33
34
    # ------------------------------------------------------------------------------------------------------------------
35 1
    def get_hierarchy_name(self):
36
        """
37
        Returns 'sectioning'.
38
39
        :rtype: str
40
        """
41 1
        return 'sectioning'
42
43
    # ------------------------------------------------------------------------------------------------------------------
44 1
    def is_block_command(self):
45
        """
46
        Returns False.
47
48
        :rtype: bool
49
        """
50 1
        return False
51
52
    # ------------------------------------------------------------------------------------------------------------------
53 1
    def is_inline_command(self):
54
        """
55
        Returns True.
56
57
        :rtype: bool
58
        """
59
        return True
60
61
    # ------------------------------------------------------------------------------------------------------------------
62 1
    def number(self, enumerable_numbers):
63
        """
64
        Sets number of heading nodes.
65
66
        :param dict[str,sdoc.sdoc2.helper.Enumerable.Enumerable] enumerable_numbers:
67
        """
68 1
        if 'heading' not in enumerable_numbers:
69 1
            enumerable_numbers['heading'] = Enumerable()
70
71 1
        enumerable_numbers['heading'].generate_numeration(self.get_hierarchy_level())
72 1
        enumerable_numbers['heading'].increment_last_level()
73 1
        enumerable_numbers['heading'].remove_starting_zeros()
74
75 1
        self._options['number'] = enumerable_numbers['heading'].get_string()
76
77 1
        super().number(enumerable_numbers)
78
79
    # ------------------------------------------------------------------------------------------------------------------
80 1
    def set_toc_id(self):
81
        """
82
        Set ID for table of contents.
83
        """
84
        if 'id' not in self._options:
85
            if 'number' in self._options:
86
                heading_text = self._options['number']
87
            else:
88
                heading_text = self.argument
89
90
            self._options['id'] = '#{}:{}'.format(self.name, heading_text)
91
92
    # ------------------------------------------------------------------------------------------------------------------
93 1
    def prepare_content_tree(self):
94
        """
95
        Prepares the content tree. Create paragraph nodes.
96
        """
97 1
        super().prepare_content_tree()
98
99
        # Adding the id's of splitted text in 'new_child_nodes1' list.
100 1
        self.split_text_nodes()
101
102
        # Creating paragraphs and add all id's in 'new_child_nodes2' list.
103 1
        self.create_paragraphs()
104
105
    # ------------------------------------------------------------------------------------------------------------------
106 1
    def split_text_nodes(self):
107
        """
108
        Replaces single text nodes that contains a paragraph separator (i.e. a double new line) with multiple text nodes
109
        without paragraph separator.
110
        """
111 1
        new_child_nodes = []
112
113 1
        for node_id in self.child_nodes:
114 1
            node = in_scope(node_id)
115
116 1
            if isinstance(node, TextNode):
117 1
                list_ids = node.split_by_paragraph()
118 1
                for ids in list_ids:
119 1
                    new_child_nodes.append(ids)
120
            else:
121 1
                new_child_nodes.append(node.id)
122
123 1
            out_scope(node)
124
125 1
        self.child_nodes = new_child_nodes
126
127
    # ------------------------------------------------------------------------------------------------------------------
128 1
    def create_paragraphs(self):
129
        """
130
        Create paragraph nodes.
131
132
        A paragraph consists of phrasing nodes only. Each continuous slice of phrasing child nodes is move to a
133
        paragraph node.
134
        """
135 1
        new_child_nodes = []
136 1
        paragraph_node = None
137
138 1
        for node_id in self.child_nodes:
139 1
            node = in_scope(node_id)
140
141 1
            if node.is_phrasing():
142 1
                if not paragraph_node:
143 1
                    paragraph_node = sdoc.sdoc2.node_store.create_inline_node('paragraph')
144 1
                    new_child_nodes.append(paragraph_node.id)
145
146 1
                paragraph_node.append_child_node(node)
147
            else:
148 1
                if paragraph_node:
149 1
                    paragraph_node.prune_whitespace()
150 1
                    sdoc.sdoc2.node_store.store_node(paragraph_node)
151 1
                    paragraph_node = None
152
153
                # End paragraph nodes are created temporary to separate paragraphs in a flat list of (text) node. There
154
                # role ae replaced by the content hierarchy now. So, we must no store end paragraph nodes.
155 1
                if not isinstance(node, EndParagraphNode):
156 1
                    new_child_nodes.append(node.id)
157
158 1
            out_scope(node)
159
160 1
        if paragraph_node:
161
            paragraph_node.prune_whitespace()
162
            sdoc.sdoc2.node_store.store_node(paragraph_node)
163
            # paragraph_node = None
164
165
        # Setting child nodes.
166 1
        self.child_nodes = new_child_nodes
167
168
# ----------------------------------------------------------------------------------------------------------------------
169