Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/mistune/markdown.py: 80%

64 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-01 06:54 +0000

1from typing import Optional 

2from .core import BlockState 

3from .block_parser import BlockParser 

4from .inline_parser import InlineParser 

5 

6 

7class Markdown: 

8 """Markdown instance to convert markdown text into HTML or other formats. 

9 Here is an example with the HTMLRenderer:: 

10 

11 from mistune import HTMLRenderer 

12 

13 md = Markdown(renderer=HTMLRenderer(escape=False)) 

14 md('hello **world**') 

15 

16 :param renderer: a renderer to convert parsed tokens 

17 :param block: block level syntax parser 

18 :param inline: inline level syntax parser 

19 :param plugins: mistune plugins to use 

20 """ 

21 def __init__(self, renderer=None, 

22 block: Optional[BlockParser]=None, 

23 inline: Optional[InlineParser]=None, 

24 plugins=None): 

25 if block is None: 

26 block = BlockParser() 

27 

28 if inline is None: 

29 inline = InlineParser() 

30 

31 self.renderer = renderer 

32 self.block: BlockParser = block 

33 self.inline: InlineParser = inline 

34 self.before_parse_hooks = [] 

35 self.before_render_hooks = [] 

36 self.after_render_hooks = [] 

37 

38 if plugins: 

39 for plugin in plugins: 

40 plugin(self) 

41 

42 def use(self, plugin): 

43 plugin(self) 

44 

45 def render_state(self, state: BlockState): 

46 data = self._iter_render(state.tokens, state) 

47 if self.renderer: 

48 return self.renderer(data, state) 

49 return list(data) 

50 

51 def _iter_render(self, tokens, state): 

52 for tok in tokens: 

53 if 'children' in tok: 

54 children = self._iter_render(tok['children'], state) 

55 tok['children'] = list(children) 

56 elif 'text' in tok: 

57 text = tok.pop('text') 

58 # process inline text 

59 # avoid striping emsp or other unicode spaces 

60 tok['children'] = self.inline(text.strip(' \r\n\t\f'), state.env) 

61 yield tok 

62 

63 def parse(self, s: str, state: Optional[BlockState]=None): 

64 """Parse and convert the given markdown string. If renderer is None, 

65 the returned **result** will be parsed markdown tokens. 

66 

67 :param s: markdown string 

68 :param state: instance of BlockState 

69 :returns: result, state 

70 """ 

71 if state is None: 

72 state = self.block.state_cls() 

73 

74 # normalize line separator 

75 s = s.replace('\r\n', '\n') 

76 s = s.replace('\r', '\n') 

77 if not s.endswith('\n'): 

78 s += '\n' 

79 

80 state.process(s) 

81 

82 for hook in self.before_parse_hooks: 

83 hook(self, state) 

84 

85 self.block.parse(state) 

86 

87 for hook in self.before_render_hooks: 

88 hook(self, state) 

89 

90 result = self.render_state(state) 

91 

92 for hook in self.after_render_hooks: 

93 result = hook(self, result, state) 

94 return result, state 

95 

96 def read(self, filepath, encoding='utf-8', state=None): 

97 if state is None: 

98 state = self.block.state_cls() 

99 

100 state.env['__file__'] = filepath 

101 with open(filepath, 'rb') as f: 

102 s = f.read() 

103 

104 s = s.decode(encoding) 

105 return self.parse(s, state) 

106 

107 def __call__(self, s: str): 

108 if s is None: 

109 s = '\n' 

110 return self.parse(s)[0]