GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

QLinearGradientConformer._conform_stops_to_scss()   B
last analyzed

Complexity

Conditions 8

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 24
rs 7.3333
c 0
b 0
f 0
cc 8
nop 2
1
# -*- coding: utf-8 -*-
2
# -----------------------------------------------------------------------------
3
# Copyright (c) 2015 Yann Lanthony
4
# Copyright (c) 2017-2018 Spyder Project Contributors
5
#
6
# Licensed under the terms of the MIT License
7
# (See LICENSE.txt for details)
8
# -----------------------------------------------------------------------------
9
"""Conform qss to compliant scss and css to valid qss."""
10
11
# yapf: disable
12
13
from __future__ import absolute_import, print_function
14
15
# Standard library imports
16
import re
17
18
19
# yapf: enable
20
21
_DEFAULT_COORDS = ('x1', 'y1', 'x2', 'y2')
22
23
24
class Conformer(object):
25
    """Base class for all text transformations."""
26
27
    def to_scss(self, qss):
28
        """Transform some qss to valid scss."""
29
        return NotImplemented
30
31
    def to_qss(self, css):
32
        """Transform some css to valid qss."""
33
        return NotImplemented
34
35
36
class NotConformer(Conformer):
37
    """Conform QSS "!" in selectors."""
38
39
    def to_scss(self, qss):
40
        """Replace "!" in selectors with "_qnot_"."""
41
        return qss.replace(':!', ':_qnot_')
42
43
    def to_qss(self, css):
44
        """Replace "_qnot_" in selectors with "!"."""
45
        return css.replace(':_qnot_', ':!')
46
47
48
class QLinearGradientConformer(Conformer):
49
    """Conform QSS qlineargradient function."""
50
51
    qss_pattern = re.compile(
52
        r'qlineargradient\('
53
        r'((?:(?:\s+)?(?:x1|y1|x2|y2):(?:\s+)?[0-9A-Za-z$_\.-]+,?)+)'  # coords
54
        r'((?:(?:\s+)?stop:.*,?)+(?:\s+)?)?'  # stops
55
        r'\)',
56
        re.MULTILINE,
57
    )
58
59
    def _conform_coords_to_scss(self, group):
60
        """
61
        Take a qss str with xy coords and returns the values.
62
63
          'x1: 0, y1: 0, x2: 0, y2: 0' => '0, 0, 0, 0'
64
          'y1: 1' => '0, 1, 0, 0'
65
        """
66
        values = ['0', '0', '0', '0']
67
        for key_values in [part.split(':', 1) for part in group.split(',')]:
68
            try:
69
                key, value = key_values
70
                key = key.strip()
71
                if key in _DEFAULT_COORDS:
72
                    pos = _DEFAULT_COORDS.index(key)
73
                    if pos >= 0 and pos <= 3:
74
                        values[pos] = value.strip()
75
            except ValueError:
76
                pass
77
        return ', '.join(values)
78
79
    def _conform_stops_to_scss(self, group):
80
        """
81
        Take a qss str with stops and returns the values.
82
83
          'stop: 0 red, stop: 1 blue' => '0 red, 1 blue'
84
        """
85
        new_group = []
86
        split = [""]
87
        bracket_level = 0
88
        for char in group:
89
            if not bracket_level and char == ",":
90
                split.append("")
91
                continue
92
            elif char == "(":
93
                bracket_level += 1
94
            elif char == ")":
95
                bracket_level -= 1
96
            split[-1] += char
97
98
        for part in split:
99
            if part:
100
                _, value = part.split(':', 1)
101
                new_group.append(value.strip())
102
        return ', '.join(new_group)
103
104
    def to_scss(self, qss):
105
        """
106
        Conform qss qlineargradient to scss qlineargradient form.
107
108
        Normalize all whitespace including the removal of newline chars.
109
110
        qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0, stop: 0 red, stop: 1 blue)
111
        =>
112
        qlineargradient(0, 0, 0, 0, (0 red, 1 blue))
113
        """
114
        conformed = qss
115
116
        for coords, stops in self.qss_pattern.findall(qss):
117
            new_coords = self._conform_coords_to_scss(coords)
118
            conformed = conformed.replace(coords, new_coords, 1)
119
120
            if not stops:
121
                continue
122
123
            new_stops = ', ({})'.format(self._conform_stops_to_scss(stops))
124
            conformed = conformed.replace(stops, new_stops, 1)
125
126
        return conformed
127
128
    def to_qss(self, css):
129
        """Transform to qss from css."""
130
        return css
131
132
133
conformers = [c() for c in Conformer.__subclasses__() if c is not Conformer]
134
135
136
def scss_conform(input_str):
137
    """
138
    Conform qss to valid scss.
139
140
    Runs the to_scss method of all Conformer subclasses on the input_str.
141
    Conformers are run in order of definition.
142
143
    :param input_str: QSS string
144
    :returns: Valid SCSS string
145
    """
146
    conformed = input_str
147
    for conformer in conformers:
148
        conformed = conformer.to_scss(conformed)
149
150
    return conformed
151
152
153
def qt_conform(input_str):
154
    """
155
    Conform css to valid qss.
156
157
    Runs the to_qss method of all Conformer subclasses on the input_str.
158
    Conformers are run in reverse order.
159
160
    :param input_str: CSS string
161
    :returns: Valid QSS string
162
    """
163
    conformed = input_str
164
    for conformer in conformers[::-1]:
165
        conformed = conformer.to_qss(conformed)
166
167
    return conformed
168