Completed
Push — master ( 32cfa8...ec62d3 )
by Dongxin
48s
created

DefListProcessor.run()   F

Complexity

Conditions 17

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 17
c 1
b 0
f 0
dl 0
loc 52
rs 3.0491

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 DefListProcessor.run() 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
"""
2
Definition List Extension for Python-Markdown
3
=============================================
4
5
Adds parsing of Definition Lists to Python-Markdown.
6
7
See <https://pythonhosted.org/Markdown/extensions/definition_lists.html>
8
for documentation.
9
10
Original code Copyright 2008 [Waylan Limberg](http://achinghead.com)
11
12
All changes Copyright 2008-2014 The Python Markdown Project
13
14
License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
15
16
"""
17
18
from __future__ import absolute_import
19
from __future__ import unicode_literals
20
from . import Extension
21
from ..blockprocessors import BlockProcessor, ListIndentProcessor
22
from ..util import etree
23
import re
24
25
26
class DefListProcessor(BlockProcessor):
27
    """ Process Definition Lists. """
28
29
    RE = re.compile(r'(^|\n)[ ]{0,3}:[ ]{1,3}(.*?)(\n|$)')
30
    NO_INDENT_RE = re.compile(r'^[ ]{0,3}[^ :]')
31
32
    def test(self, parent, block):
33
        return bool(self.RE.search(block))
34
35
    def run(self, parent, blocks):
36
37
        raw_block = blocks.pop(0)
38
        m = self.RE.search(raw_block)
39
        terms = [l.strip() for l in
40
                 raw_block[:m.start()].split('\n') if l.strip()]
41
        block = raw_block[m.end():]
42
        no_indent = self.NO_INDENT_RE.match(block)
43
        if no_indent:
44
            d, theRest = (block, None)
45
        else:
46
            d, theRest = self.detab(block)
47
        if d:
48
            d = '%s\n%s' % (m.group(2), d)
49
        else:
50
            d = m.group(2)
51
        sibling = self.lastChild(parent)
52
        if not terms and sibling is None:
53
            # This is not a definition item. Most likely a paragraph that
54
            # starts with a colon at the begining of a document or list.
55
            blocks.insert(0, raw_block)
56
            return False
57
        if not terms and sibling.tag == 'p':
58
            # The previous paragraph contains the terms
59
            state = 'looselist'
60
            terms = sibling.text.split('\n')
61
            parent.remove(sibling)
62
            # Aquire new sibling
63
            sibling = self.lastChild(parent)
64
        else:
65
            state = 'list'
66
67
        if sibling is not None and sibling.tag == 'dl':
68
            # This is another item on an existing list
69
            dl = sibling
70
            if not terms and len(dl) and dl[-1].tag == 'dd' and len(dl[-1]):
71
                state = 'looselist'
72
        else:
73
            # This is a new list
74
            dl = etree.SubElement(parent, 'dl')
75
        # Add terms
76
        for term in terms:
77
            dt = etree.SubElement(dl, 'dt')
78
            dt.text = term
79
        # Add definition
80
        self.parser.state.set(state)
81
        dd = etree.SubElement(dl, 'dd')
82
        self.parser.parseBlocks(dd, [d])
83
        self.parser.state.reset()
84
85
        if theRest:
86
            blocks.insert(0, theRest)
87
88
89
class DefListIndentProcessor(ListIndentProcessor):
90
    """ Process indented children of definition list items. """
91
92
    ITEM_TYPES = ['dd']
93
    LIST_TYPES = ['dl']
94
95
    def create_item(self, parent, block):
96
        """ Create a new dd and parse the block with it as the parent. """
97
        dd = etree.SubElement(parent, 'dd')
98
        self.parser.parseBlocks(dd, [block])
99
100
101
class DefListExtension(Extension):
102
    """ Add definition lists to Markdown. """
103
104
    def extendMarkdown(self, md, md_globals):
105
        """ Add an instance of DefListProcessor to BlockParser. """
106
        md.parser.blockprocessors.add('defindent',
107
                                      DefListIndentProcessor(md.parser),
108
                                      '>indent')
109
        md.parser.blockprocessors.add('deflist',
110
                                      DefListProcessor(md.parser),
111
                                      '>ulist')
112
113
114
def makeExtension(*args, **kwargs):
115
    return DefListExtension(*args, **kwargs)
116