Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/mistune/plugins/def_list.py: 98%
61 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
1import re
2from ..util import strip_end
4__all__ = ['def_list']
6# https://michelf.ca/projects/php-markdown/extra/#def-list
8DEF_PATTERN = (
9 r'^(?P<def_list_head>(?:[^\n]+\n)+?)'
10 r'\n?(?:'
11 r'\:[ \t]+.*\n'
12 r'(?:[^\n]+\n)*' # lazy continue line
13 r'(?:(?:[ \t]*\n)*[ \t]+[^\n]+\n)*'
14 r'(?:[ \t]*\n)*'
15 r')+'
16)
17DEF_RE = re.compile(DEF_PATTERN, re.M)
18DD_START_RE = re.compile(r'^:[ \t]+', re.M)
19TRIM_RE = re.compile(r'^ {0,4}', re.M)
20HAS_BLANK_LINE_RE = re.compile(r'\n[ \t]*\n$')
23def parse_def_list(block, m, state):
24 pos = m.end()
25 children = list(_parse_def_item(block, m))
27 m = DEF_RE.match(state.src, pos)
28 while m:
29 children.extend(list(_parse_def_item(block, m)))
30 pos = m.end()
31 m = DEF_RE.match(state.src, pos)
33 state.append_token({
34 'type': 'def_list',
35 'children': children,
36 })
37 return pos
40def _parse_def_item(block, m):
41 head = m.group('def_list_head')
42 for line in head.splitlines():
43 yield {
44 'type': 'def_list_head',
45 'text': line,
46 }
48 src = m.group(0)
49 end = len(head)
51 m = DD_START_RE.search(src, end)
52 start = m.start()
53 prev_blank_line = src[end:start] == '\n'
54 while m:
55 m = DD_START_RE.search(src, start + 1)
56 if not m:
57 break
59 end = m.start()
60 text = src[start:end].replace(':', ' ', 1)
61 children = _process_text(block, text, prev_blank_line)
62 prev_blank_line = bool(HAS_BLANK_LINE_RE.search(text))
63 yield {
64 'type': 'def_list_item',
65 'children': children,
66 }
67 start = end
69 text = src[start:].replace(':', ' ', 1)
70 children = _process_text(block, text, prev_blank_line)
71 yield {
72 'type': 'def_list_item',
73 'children': children,
74 }
77def _process_text(block, text, loose):
78 text = TRIM_RE.sub('', text)
79 state = block.state_cls()
80 state.process(strip_end(text))
81 # use default list rules
82 block.parse(state, block.list_rules)
83 tokens = state.tokens
84 if not loose and len(tokens) == 1 and tokens[0]['type'] == 'paragraph':
85 tokens[0]['type'] = 'block_text'
86 return tokens
89def render_def_list(renderer, text):
90 return '<dl>\n' + text + '</dl>\n'
93def render_def_list_head(renderer, text):
94 return '<dt>' + text + '</dt>\n'
97def render_def_list_item(renderer, text):
98 return '<dd>' + text + '</dd>\n'
101def def_list(md):
102 """A mistune plugin to support def list, spec defined at
103 https://michelf.ca/projects/php-markdown/extra/#def-list
105 Here is an example:
107 .. code-block:: text
109 Apple
110 : Pomaceous fruit of plants of the genus Malus in
111 the family Rosaceae.
113 Orange
114 : The fruit of an evergreen tree of the genus Citrus.
116 It will be converted into HTML:
118 .. code-block:: html
120 <dl>
121 <dt>Apple</dt>
122 <dd>Pomaceous fruit of plants of the genus Malus in
123 the family Rosaceae.</dd>
125 <dt>Orange</dt>
126 <dd>The fruit of an evergreen tree of the genus Citrus.</dd>
127 </dl>
129 :param md: Markdown instance
130 """
131 md.block.register('def_list', DEF_PATTERN, parse_def_list, before='paragraph')
132 if md.renderer and md.renderer.NAME == 'html':
133 md.renderer.register('def_list', render_def_list)
134 md.renderer.register('def_list_head', render_def_list_head)
135 md.renderer.register('def_list_item', render_def_list_item)