85 lines
2.2 KiB
Python
85 lines
2.2 KiB
Python
from .block_parser import BlockParser, expand_leading_tab, cleanup_lines
|
|
from .inline_parser import InlineParser
|
|
|
|
|
|
class Markdown(object):
|
|
def __init__(self, renderer, block=None, inline=None, plugins=None):
|
|
if block is None:
|
|
block = BlockParser()
|
|
|
|
if inline is None:
|
|
inline = InlineParser(renderer)
|
|
|
|
self.block = block
|
|
self.inline = inline
|
|
self.renderer = inline.renderer
|
|
self.before_parse_hooks = []
|
|
self.before_render_hooks = []
|
|
self.after_render_hooks = []
|
|
|
|
if plugins:
|
|
for plugin in plugins:
|
|
plugin(self)
|
|
|
|
def use(self, plugin):
|
|
plugin(self)
|
|
|
|
def before_parse(self, s, state):
|
|
s, state = preprocess(s, state)
|
|
for hook in self.before_parse_hooks:
|
|
s, state = hook(self, s, state)
|
|
return s, state
|
|
|
|
def before_render(self, tokens, state):
|
|
for hook in self.before_render_hooks:
|
|
tokens = hook(self, tokens, state)
|
|
return tokens
|
|
|
|
def after_render(self, result, state):
|
|
for hook in self.after_render_hooks:
|
|
result = hook(self, result, state)
|
|
return result
|
|
|
|
def parse(self, s, state=None):
|
|
if state is None:
|
|
state = {}
|
|
|
|
s, state = self.before_parse(s, state)
|
|
tokens = self.block.parse(s, state)
|
|
tokens = self.before_render(tokens, state)
|
|
result = self.block.render(tokens, self.inline, state)
|
|
result = self.after_render(result, state)
|
|
return result
|
|
|
|
def read(self, filepath, state=None):
|
|
if state is None:
|
|
state = {}
|
|
|
|
state['__file__'] = filepath
|
|
with open(filepath, 'rb') as f:
|
|
s = f.read()
|
|
|
|
return self.parse(s.decode('utf-8'), state)
|
|
|
|
def __call__(self, s):
|
|
return self.parse(s)
|
|
|
|
|
|
def preprocess(s, state):
|
|
state.update({
|
|
'def_links': {},
|
|
'def_footnotes': {},
|
|
'footnotes': [],
|
|
})
|
|
|
|
if s is None:
|
|
s = '\n'
|
|
else:
|
|
s = s.replace('\u2424', '\n')
|
|
s = cleanup_lines(s)
|
|
s = expand_leading_tab(s)
|
|
if not s.endswith('\n'):
|
|
s += '\n'
|
|
|
|
return s, state
|