sdoc.helper.Html.Html.generate_attribute()   F
last analyzed

Complexity

Conditions 14

Size

Total Lines 57
Code Lines 42

Duplication

Lines 57
Ratio 100 %

Code Coverage

Tests 14
CRAP Score 48.8837

Importance

Changes 0
Metric Value
eloc 42
dl 57
loc 57
ccs 14
cts 32
cp 0.4375
rs 3.6
c 0
b 0
f 0
cc 14
nop 2
crap 48.8837

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like sdoc.helper.Html.Html.generate_attribute() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 1
from typing import Dict, Optional
2
3
4 1 View Code Duplication
class Html:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5
    """
6
    Utility class with functions for generating HTML code.
7
    """
8
9
    # ------------------------------------------------------------------------------------------------------------------
10 1
    @staticmethod
11 1
    def escape(text: str, quote: bool = True) -> str:
12
        """
13
        Returns a string with special characters converted to HTML entities.
14
15
        :param str text: The string with optionally special characters.
16
        :param bool quote: If true the quotation mark characters, both double quote (") and single quote (')
17
                           characters are also translated.
18
        """
19 1
        text = text.replace("&", "&")  # Must be done first!
20 1
        text = text.replace("<", "&lt;")
21 1
        text = text.replace(">", "&gt;")
22 1
        if quote:
23 1
            text = text.replace('"', "&quot;")
24 1
            text = text.replace('\'', "&#x27;")
25
26 1
        return text
27
28
    # ------------------------------------------------------------------------------------------------------------------
29 1
    @staticmethod
30 1
    def generate_attribute(name: str, value: str) -> str:
31
        """
32
        Returns a string proper conversion of special characters to HTML entities of an attribute of a HTML tag.
33
34
        :param str name: The name of the attribute.
35
        :param str value: The value of the attribute.
36
        """
37 1
        html = ''
38
39
        # Boolean attributes.
40 1
        if name in ('autofocus',
41
                    'checked',
42
                    'disabled',
43
                    'hidden',
44
                    'ismap',
45
                    'multiple',
46
                    'novalidate',
47
                    'readonly',
48
                    'required',
49
                    'selected',
50
                    'spellcheck'):
51
            if value:
52
                html += ' '
53
                html += name
54
                html += '="'
55
                html += name
56
                html += '"'
57
58
        # Annoying boolean attribute exceptions.
59 1
        elif name in ('draggable', 'contenteditable'):
60
            if value is not None:
61
                html += ' '
62
                html += name
63
                html += '="true"' if value else '="false"'
64
65 1
        elif name == 'autocomplete':
66
            if value is not None:
67
                html += ' '
68
                html += name
69
                html += '="on"' if value else '="off"'
70
71 1
        elif name == 'translate':
72
            if value is not None:
73
                html += ' '
74
                html += name
75
                html += '="yes"' if value else '="no"'
76
77
        else:
78 1
            if value is not None and value != '':
79 1
                html += ' '
80 1
                html += Html.escape(name)
81 1
                html += '="'
82 1
                html += Html.escape(value)
83 1
                html += '"'
84
85 1
        return html
86
87
    # ------------------------------------------------------------------------------------------------------------------
88 1
    @staticmethod
89 1
    def generate_element(tag_name: str,
90
                         attributes: Optional[Dict[str, str]] = None,
91
                         inner_text: str = '',
92
                         is_html: bool = False) -> str:
93
        """
94
        Generates HTML code for an element.
95
96
        Note: tags for void elements such as '<br/>' are not supported.
97
98
        :param str tag_name: The name of the tag, e.g. a, form.
99
        :param dict[str,str]|None attributes: The attributes of the tag. Special characters in the attributes will be
100
                                              replaced with HTML entities.
101
        :param str inner_text: The inner text of the tag.
102
        :param bool is_html: If set the inner text is a HTML snippet, otherwise special characters in the inner text
103
                             will be replaced with HTML entities.
104
        """
105 1
        html = Html.generate_tag(tag_name, attributes)
106 1
        html += inner_text if is_html else Html.escape(inner_text)
107 1
        html += '</'
108 1
        html += tag_name
109 1
        html += '>'
110
111 1
        return html
112
113
    # ------------------------------------------------------------------------------------------------------------------
114 1
    @staticmethod
115 1
    def generate_tag(tag_name: str, attributes: Optional[Dict[str, str]] = None) -> str:
116
        """
117
        Generates HTML code for a start tag of an element.
118
119
        :param str tag_name: The name of the tag, e.g. a, form.
120
        :param dict[str,str]|None attributes: The attributes of the tag. Special characters in the attributes will be
121
                                              replaced with HTML entities.
122
        """
123 1
        html = '<'
124 1
        html += tag_name
125 1
        for key in sorted(attributes):
126 1
            html += Html.generate_attribute(key, attributes[key])
127 1
        html += '>'
128
129 1
        return html
130
131
    # ------------------------------------------------------------------------------------------------------------------
132 1
    @staticmethod
133 1
    def generate_void_element(tag_name: str, attributes: Optional[Dict[str, str]] = None) -> str:
134
        """
135
        Generates HTML code for an element.
136
137
        Note: tags for void elements such as '<br/>' are not supported.
138
139
        :param str tag_name: The name of the tag, e.g. a, form.
140
        :param dict[str,str]|None attributes: The attributes of the tag. Special characters in the attributes will be
141
                                              replaced with HTML entities.
142
        """
143
        html = '<'
144
        html += tag_name
145
        for key in sorted(attributes):
146
            html += Html.generate_attribute(key, attributes[key])
147
        html += '/>'
148
149
        return html
150
151
# ----------------------------------------------------------------------------------------------------------------------
152