Completed
Push — dev-4.1-unstable ( 5aa386...906e19 )
by Felipe A.
01:22
created

test()   A

Complexity

Conditions 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
c 1
b 0
f 1
dl 0
loc 20
rs 9.4285
1
import re
2
3
import jinja2
4
import jinja2.ext
5
import jinja2.lexer
6
7
8
class HTMLCompressFeed(object):
9
    re_whitespace = re.compile('(\"[^\"\\n]*\"|\'[^\'\\n]*\')|([ \\t\\r\\n]+)')
10
    token_class = jinja2.lexer.Token
11
    block_tokens = {
12
        'variable_begin': 'variable_end',
13
        'block_begin': 'block_end'
14
        }
15
16
    def __init__(self):
17
        self.intag = False
18
        self.pending = ''
19
        self.lineno = 0
20
        self.skip_until = None
21
22
    def finalize(self, strip=False):
23
        if self.intag:
24
            data = self._collapse(self.pending)
25
        else:
26
            data = self.pending.rstrip() if strip else self.pending
27
        if data.strip():
28
            yield self.token_class(self.lineno, 'data', data)
29
        self.pending = ''
30
31
    def _collapse(self, data):
32
        return self.re_whitespace.sub(
33
            lambda m: ' ' if m.groups()[-1] else m.group(0),
34
            data
35
            )
36
37
    def feed(self, token):
38
        if self.skip_until:
39
            yield token
40
            if token.type == self.skip_until:
41
                self.skip_until = None
42
            return
43
44
        if token.type in self.block_tokens:
45
            print(token.type)
46
            for data in self.finalize(token.type == 'block_begin'):
47
                yield data
48
            yield token
49
            self.skip_until = self.block_tokens[token.type]
50
            return
51
52
        lineno = self.lineno
53
        size = len(token.value)
54
        value = self.pending + token.value
55
        while value:
56
            lineno = self.lineno if len(value) > size else token.lineno
57
            s, p, value = value.partition('>' if self.intag else '<')
58
            if self.intag:
59
                s = self._collapse(s)
60
                if p:
61
                    self.intag = False
62
                    s = s.rstrip() + p
63
                yield self.token_class(lineno, 'data', s)
64
            elif p:
65
                self.intag = True
66
                s = s + p if s.strip() else p
67
                yield self.token_class(lineno, 'data', s)
68
            else:
69
                value = s
70
                break
71
        self.lineno = lineno
72
        self.pending = value
73
74
75
class HTMLCompress(jinja2.ext.Extension):
76
    def filter_stream(self, stream):
77
        feed = HTMLCompressFeed()
78
        for token in stream:
79
            for data in feed.feed(token):
80
                yield data
81
        for data in feed.finalize():
82
            yield data
83