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

1import re 

2from ..util import strip_end 

3 

4__all__ = ['def_list'] 

5 

6# https://michelf.ca/projects/php-markdown/extra/#def-list 

7 

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$') 

21 

22 

23def parse_def_list(block, m, state): 

24 pos = m.end() 

25 children = list(_parse_def_item(block, m)) 

26 

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) 

32 

33 state.append_token({ 

34 'type': 'def_list', 

35 'children': children, 

36 }) 

37 return pos 

38 

39 

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 } 

47 

48 src = m.group(0) 

49 end = len(head) 

50 

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 

58 

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 

68 

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 } 

75 

76 

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 

87 

88 

89def render_def_list(renderer, text): 

90 return '<dl>\n' + text + '</dl>\n' 

91 

92 

93def render_def_list_head(renderer, text): 

94 return '<dt>' + text + '</dt>\n' 

95 

96 

97def render_def_list_item(renderer, text): 

98 return '<dd>' + text + '</dd>\n' 

99 

100 

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 

104 

105 Here is an example: 

106 

107 .. code-block:: text 

108 

109 Apple 

110 : Pomaceous fruit of plants of the genus Malus in 

111 the family Rosaceae. 

112 

113 Orange 

114 : The fruit of an evergreen tree of the genus Citrus. 

115 

116 It will be converted into HTML: 

117 

118 .. code-block:: html 

119 

120 <dl> 

121 <dt>Apple</dt> 

122 <dd>Pomaceous fruit of plants of the genus Malus in 

123 the family Rosaceae.</dd> 

124 

125 <dt>Orange</dt> 

126 <dd>The fruit of an evergreen tree of the genus Citrus.</dd> 

127 </dl> 

128 

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)