Skip to content

Commit baf662b

Browse files
committed
outsourced mistune stuff
1 parent 836a1c7 commit baf662b

File tree

4 files changed

+161
-147
lines changed

4 files changed

+161
-147
lines changed

__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .md2mu import *

md2mu.py

+7-147
Original file line numberDiff line numberDiff line change
@@ -1,151 +1,8 @@
1-
import mistune
21
from mistune import Markdown
3-
from mistune.core import BlockState
4-
from mistune.util import strip_end
5-
from mistune.renderers._list import render_list
6-
from mistune.renderers.markdown import MarkdownRenderer
7-
from typing import Dict, Any
8-
from textwrap import indent
92
import argparse
103
import re
11-
12-
UNDERLINED = r'\b_{1,3}(?=[^\s_])'
13-
UNDERLINED_END_RE = {
14-
'_': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])_(?!_)\b'),
15-
'__': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])__(?!_)\b'),
16-
'___': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])___(?!_)\b'),
17-
}
18-
19-
def parse_underlined(inline, m, state):
20-
text = m.group(2)
21-
print('rrr')
22-
state.append_token({'type': 'underlined', 'raw': text})
23-
return m.end()
24-
25-
def parse_underlined(self, m, state) -> int:
26-
pos = m.end()
27-
marker = m.group(0)
28-
mlen = len(marker)
29-
_end_re = UNDERLINED_END_RE[marker]
30-
m1 = _end_re.search(state.src, pos)
31-
if not m1:
32-
state.append_token({'type': 'text', 'raw': marker})
33-
return pos
34-
end_pos = m1.end()
35-
text = state.src[pos:end_pos-mlen]
36-
prec_pos = self.precedence_scan(m, state, end_pos)
37-
if prec_pos:
38-
return prec_pos
39-
new_state = state.copy()
40-
new_state.src = text
41-
new_state.in_underlined = True
42-
state.append_token({
43-
'type': 'underlined',
44-
'children': self.render(new_state),
45-
})
46-
return end_pos
47-
48-
def render_underlined(self, token, state) -> str:
49-
return '`_' + self.render_children(token, state) + '`_'
50-
51-
class Markdown2Micron(MarkdownRenderer):
52-
NAME = 'micron'
53-
54-
def __call__(self, tokens, state: BlockState):
55-
out = self.render_tokens(tokens, state)
56-
# special handle for line breaks
57-
out += '\n\n'.join(self.render_referrences(state)) + '\n'
58-
return strip_end(out)
59-
60-
def render_children(self, token, state: BlockState):
61-
children = token['children']
62-
return self.render_tokens(children, state)
63-
64-
def text(self, token: Dict[str, Any], state: BlockState) -> str:
65-
return token['raw']
66-
67-
def emphasis(self, token: Dict[str, Any], state: BlockState) -> str:
68-
return '`*' + self.render_children(token, state) + '`*'
69-
70-
def strong(self, token: Dict[str, Any], state: BlockState) -> str:
71-
return '`!' + self.render_children(token, state) + '`!'
72-
73-
def link(self, token: Dict[str, Any], state: BlockState) -> str:
74-
label = token.get('label')
75-
text = self.render_children(token, state)
76-
out = '`[' + text + '`'
77-
if label:
78-
return out + '`[' + label + '`'
79-
attrs = token['attrs']
80-
url = attrs['url']
81-
if text == url:
82-
return '`[' + text + '`'
83-
elif 'mailto:' + text == url:
84-
return '`[' + text + '`'
85-
out += url
86-
return out + ']'
87-
88-
def image(self, token: Dict[str, Any], state: BlockState) -> str:
89-
return self.link(token, state)
90-
91-
def codespan(self, token: Dict[str, Any], state: BlockState) -> str:
92-
return '`=' + token['raw'] + '`='
93-
94-
def linebreak(self, token: Dict[str, Any], state: BlockState) -> str:
95-
return ' \n'
96-
97-
def softbreak(self, token: Dict[str, Any], state: BlockState) -> str:
98-
return '\n'
99-
100-
def blank_line(self, token: Dict[str, Any], state: BlockState) -> str:
101-
return ''
102-
103-
def inline_html(self, token: Dict[str, Any], state: BlockState) -> str:
104-
return ''
105-
106-
def paragraph(self, token: Dict[str, Any], state: BlockState) -> str:
107-
text = self.render_children(token, state)
108-
return text + '\n\n'
109-
110-
def heading(self, token: Dict[str, Any], state: BlockState) -> str:
111-
level = token['attrs']['level']
112-
if level > 3:
113-
level = 3
114-
marker = '>' * level
115-
text = self.render_children(token, state)
116-
return marker + ' ' + text + '\n\n'
117-
def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str:
118-
return '-\n\n'
119-
120-
def block_text(self, token: Dict[str, Any], state: BlockState) -> str:
121-
return self.render_children(token, state) + '\n'
122-
123-
def block_code(self, token: Dict[str, Any], state: BlockState) -> str:
124-
code = token['raw']
125-
if code and code[-1] != '\n':
126-
code += '\n'
127-
marker = '`='
128-
return marker + '\n' + code + marker + '\n\n'
129-
130-
def block_quote(self, token: Dict[str, Any], state: BlockState) -> str:
131-
text = indent(self.render_children(token, state), '>>>>')
132-
return text + '\n\n'
133-
134-
def block_html(self, token: Dict[str, Any], state: BlockState) -> str:
135-
return ''
136-
137-
def block_error(self, token: Dict[str, Any], state: BlockState) -> str:
138-
return ''
139-
140-
def list(self, token: Dict[str, Any], state: BlockState) -> str:
141-
return render_list(self, token, state)
142-
143-
def m2μ():
144-
m2μr = Markdown2Micron()
145-
m2μ = Markdown(renderer=m2μr)
146-
m2μ.inline.register('underlined', UNDERLINED, parse_underlined, before='emphasis')
147-
m2μ.renderer.register('underlined', render_underlined)
148-
return m2μ
4+
from underlined import underlined
5+
from micron import MicronRenderer
1496

1507
def main():
1518

@@ -157,10 +14,13 @@ def main():
15714

15815
with open(args.md_file, 'r') as mdf:
15916
md_str = mdf.read()
160-
md2mu = m2μ()
17+
18+
m2μr = MicronRenderer()
19+
m2μ = Markdown(renderer=m2μr)
20+
underlined(m2μ)
16121

16222
with open(args.mu_file, 'w') as muf:
163-
md_str = muf.write(md2mu(md_str))
23+
md_str = muf.write(m2μ(md_str))
16424

16525
if __name__ == "__main__":
16626
main()

micron.py

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from mistune.core import BlockState
2+
from mistune.util import strip_end
3+
from mistune.renderers._list import render_list
4+
from mistune.renderers.markdown import MarkdownRenderer
5+
from typing import Dict, Any
6+
from textwrap import indent
7+
8+
class MicronRenderer(MarkdownRenderer):
9+
"""A renderer to format Micron text."""
10+
NAME = 'micron'
11+
12+
def __call__(self, tokens, state: BlockState):
13+
out = self.render_tokens(tokens, state)
14+
# special handle for line breaks
15+
out += '\n\n'.join(self.render_referrences(state)) + '\n'
16+
return strip_end(out)
17+
18+
def render_children(self, token, state: BlockState):
19+
children = token['children']
20+
return self.render_tokens(children, state)
21+
22+
def text(self, token: Dict[str, Any], state: BlockState) -> str:
23+
return token['raw']
24+
25+
def emphasis(self, token: Dict[str, Any], state: BlockState) -> str:
26+
return '`*' + self.render_children(token, state) + '`*'
27+
28+
def strong(self, token: Dict[str, Any], state: BlockState) -> str:
29+
return '`!' + self.render_children(token, state) + '`!'
30+
31+
def link(self, token: Dict[str, Any], state: BlockState) -> str:
32+
label = token.get('label')
33+
text = self.render_children(token, state)
34+
out = '`[' + text + '`'
35+
if label:
36+
return out + '`[' + label + '`'
37+
attrs = token['attrs']
38+
url = attrs['url']
39+
if text == url:
40+
return '`[' + text + '`'
41+
elif 'mailto:' + text == url:
42+
return '`[' + text + '`'
43+
out += url
44+
return out + ']'
45+
46+
def image(self, token: Dict[str, Any], state: BlockState) -> str:
47+
return self.link(token, state)
48+
49+
def codespan(self, token: Dict[str, Any], state: BlockState) -> str:
50+
return '`=' + token['raw'] + '`='
51+
52+
def linebreak(self, token: Dict[str, Any], state: BlockState) -> str:
53+
return ' \n'
54+
55+
def softbreak(self, token: Dict[str, Any], state: BlockState) -> str:
56+
return '\n'
57+
58+
def blank_line(self, token: Dict[str, Any], state: BlockState) -> str:
59+
return ''
60+
61+
def inline_html(self, token: Dict[str, Any], state: BlockState) -> str:
62+
return ''
63+
64+
def paragraph(self, token: Dict[str, Any], state: BlockState) -> str:
65+
text = self.render_children(token, state)
66+
return text + '\n\n'
67+
68+
def heading(self, token: Dict[str, Any], state: BlockState) -> str:
69+
level = token['attrs']['level']
70+
if level > 3:
71+
level = 3
72+
marker = '>' * level
73+
text = self.render_children(token, state)
74+
return marker + ' ' + text + '\n\n'
75+
def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str:
76+
return '-\n\n'
77+
78+
def block_text(self, token: Dict[str, Any], state: BlockState) -> str:
79+
return self.render_children(token, state) + '\n'
80+
81+
def block_code(self, token: Dict[str, Any], state: BlockState) -> str:
82+
code = token['raw']
83+
if code and code[-1] != '\n':
84+
code += '\n'
85+
marker = '`='
86+
return marker + '\n' + code + marker + '\n\n'
87+
88+
def block_quote(self, token: Dict[str, Any], state: BlockState) -> str:
89+
text = indent(self.render_children(token, state), '>>>>')
90+
return text + '\n\n'
91+
92+
def block_html(self, token: Dict[str, Any], state: BlockState) -> str:
93+
return ''
94+
95+
def block_error(self, token: Dict[str, Any], state: BlockState) -> str:
96+
return ''
97+
98+
def list(self, token: Dict[str, Any], state: BlockState) -> str:
99+
return render_list(self, token, state)

underlined.py

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
__all__ = ['underlined']
2+
3+
import re
4+
5+
UNDERLINED = r'\b_{1,3}(?=[^\s_])'
6+
UNDERLINED_END_RE = {
7+
'_': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])_(?!_)\b'),
8+
'__': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])__(?!_)\b'),
9+
'___': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])___(?!_)\b'),
10+
}
11+
12+
def parse_underlined(self, m, state) -> int:
13+
pos = m.end()
14+
marker = m.group(0)
15+
mlen = len(marker)
16+
_end_re = UNDERLINED_END_RE[marker]
17+
m1 = _end_re.search(state.src, pos)
18+
if not m1:
19+
state.append_token({'type': 'text', 'raw': marker})
20+
return pos
21+
end_pos = m1.end()
22+
text = state.src[pos:end_pos-mlen]
23+
prec_pos = self.precedence_scan(m, state, end_pos)
24+
if prec_pos:
25+
return prec_pos
26+
new_state = state.copy()
27+
new_state.src = text
28+
new_state.in_underlined = True
29+
state.append_token({
30+
'type': 'underlined',
31+
'children': self.render(new_state),
32+
})
33+
return end_pos
34+
35+
def render_underlined_mu(self, token, state) -> str:
36+
return '`_' + self.render_children(token, state) + '`_'
37+
38+
def render_underlined_html(self, token, state) -> str:
39+
return '<u>' + self.render_children(token, state) + '</u>'
40+
41+
def underlined(md):
42+
"""A mistune plugin to render underlined tags.
43+
Most Markdown parsers render it as emphasis tag.
44+
45+
Underlined text is surrounded by `_`, `__`, or `___`
46+
47+
:param md: Markdown instance
48+
"""
49+
md.inline.register('underlined', UNDERLINED, parse_underlined, before='emphasis')
50+
if md.renderer:
51+
if md.renderer.NAME == 'html':
52+
md.renderer.register('underlined', render_underlined_html)
53+
elif md.renderer.NAME == 'micron':
54+
md.renderer.register('underlined', render_underlined_mu)

0 commit comments

Comments
 (0)