underlines + cleanup

This commit is contained in:
NN Solex
2023-05-16 17:09:26 +03:00
parent e6d961a13c
commit 8b1bf326fc
2 changed files with 186 additions and 72 deletions

187
md2mu.py
View File

@@ -1,49 +1,146 @@
import mistune
from mistune import Markdown
from mistune.core import BlockState
from mistune.util import strip_end
from mistune.renderers._list import render_list
from mistune.renderers.markdown import MarkdownRenderer
from typing import Dict, Any
from textwrap import indent
import argparse
import re
class Markdown2Micron(mistune.HTMLRenderer):
def text(self, text) -> str:
return text
def emphasis(self, text: str) -> str:
return '`*' + text + '`*'
def strong(self, text: str) -> str:
return '`!' + text + '`!'
def codespan(self, text: str) -> str:
return '`=' + text + '`='
def heading(self, text, level, **attrs) -> str:
UNDERLINED = r'\b_{1,3}(?=[^\s_])'
UNDERLINED_END_RE = {
'_': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])_(?!_)\b'),
'__': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])__(?!_)\b'),
'___': re.compile(r'(?:(?<!\\)(?:\\\\)*\\_|[^\s_])___(?!_)\b'),
}
def parse_underlined(inline, m, state):
print(inline, m, state)
text = m.group(2)
print('rrr')
state.append_token({'type': 'underlined', 'raw': text})
return m.end()
def parse_underlined(self, m, state) -> int:
print(state)
pos = m.end()
marker = m.group(0)
mlen = len(marker)
_end_re = UNDERLINED_END_RE[marker]
m1 = _end_re.search(state.src, pos)
if not m1:
state.append_token({'type': 'text', 'raw': marker})
return pos
end_pos = m1.end()
text = state.src[pos:end_pos-mlen]
prec_pos = self.precedence_scan(m, state, end_pos)
if prec_pos:
return prec_pos
new_state = state.copy()
new_state.src = text
new_state.in_underlined = True
state.append_token({
'type': 'underlined',
'children': self.render(new_state),
})
return end_pos
def render_underlined(self, token, state) -> str:
return '`_' + self.render_children(token, state) + '`_'
class Markdown2Micron(MarkdownRenderer):
NAME = 'micron'
def __call__(self, tokens, state: BlockState):
out = self.render_tokens(tokens, state)
# special handle for line breaks
out += '\n\n'.join(self.render_referrences(state)) + '\n'
return strip_end(out)
def render_children(self, token, state: BlockState):
children = token['children']
return self.render_tokens(children, state)
def text(self, token: Dict[str, Any], state: BlockState) -> str:
return token['raw']
def emphasis(self, token: Dict[str, Any], state: BlockState) -> str:
return '`*' + self.render_children(token, state) + '`*'
def strong(self, token: Dict[str, Any], state: BlockState) -> str:
return '`!' + self.render_children(token, state) + '`!'
def link(self, token: Dict[str, Any], state: BlockState) -> str:
label = token.get('label')
text = self.render_children(token, state)
out = '`[' + text + '`'
if label:
return out + '`[' + label + '`'
attrs = token['attrs']
url = attrs['url']
if text == url:
return '`[' + text + '`'
elif 'mailto:' + text == url:
return '`[' + text + '`'
out += url
return out + ']'
def image(self, token: Dict[str, Any], state: BlockState) -> str:
return self.link(token, state)
def codespan(self, token: Dict[str, Any], state: BlockState) -> str:
return '`=' + token['raw'] + '`='
def linebreak(self, token: Dict[str, Any], state: BlockState) -> str:
return ' \n'
def softbreak(self, token: Dict[str, Any], state: BlockState) -> str:
return '\n'
def blank_line(self, token: Dict[str, Any], state: BlockState) -> str:
return ''
def inline_html(self, token: Dict[str, Any], state: BlockState) -> str:
return ''
def paragraph(self, token: Dict[str, Any], state: BlockState) -> str:
text = self.render_children(token, state)
return text + '\n\n'
def heading(self, token: Dict[str, Any], state: BlockState) -> str:
level = token['attrs']['level']
if level > 3:
level = 3
return '>' * level + text + '\n'
def link(self, text: str, url: str, title=None) -> str:
s = self.safe_url(url)
if text:
s = text + '`' + s
return f'`[{s}]'
def image(self, text: str, url: str, title=None) -> str:
s = self.safe_url(url)
if title:
s = title + '`' + s
return f'`[{s}]'
def blank_line(self) -> str:
return '' + '\n'
def linebreak(self) -> str:
return '\n'
def softbreak(self) -> str:
return '\n'
def inline_html(self, html: str) -> str:
return '`=\n' + html + '`=\n'
def thematic_break(self):
return '-' + '\n'
def paragraph(self, text):
return text + '\n'
def block_quote(self, text: str) -> str:
return '>>>>' + text
def list(self, text: str, ordered: bool, **attrs) -> str:
return text + '\n'
def list_item(self, text: str) -> str:
return '+ ' + text + '\n'
def block_code(self, code: str, info=None) -> str:
return '`=\n' + code + '`=\n'
marker = '>' * level
text = self.render_children(token, state)
return marker + ' ' + text + '\n\n'
def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str:
return '-\n\n'
def block_text(self, token: Dict[str, Any], state: BlockState) -> str:
return self.render_children(token, state) + '\n'
def block_code(self, token: Dict[str, Any], state: BlockState) -> str:
code = token['raw']
if code and code[-1] != '\n':
code += '\n'
marker = '`='
return marker + '\n' + code + marker + '\n\n'
def block_quote(self, token: Dict[str, Any], state: BlockState) -> str:
text = indent(self.render_children(token, state), '>>>>')
return text + '\n\n'
def block_html(self, token: Dict[str, Any], state: BlockState) -> str:
return ''
def block_error(self, token: Dict[str, Any], state: BlockState) -> str:
return ''
def list(self, token: Dict[str, Any], state: BlockState) -> str:
return render_list(self, token, state)
def main():
@@ -55,11 +152,13 @@ def main():
with open(args.md_file, 'r') as mdf:
md_str = mdf.read()
m2μ = Markdown2Micron()
md2micron = mistune.create_markdown(renderer=m2μ)
m2μr = Markdown2Micron()
m = Markdown(renderer=m2μr)
m2μ.inline.register('underlined', UNDERLINED, parse_underlined, before='emphasis')
m2μ.renderer.register('underlined', render_underlined)
with open(args.mu_file, 'w') as muf:
md_str = muf.write(md2micron(md_str))
md_str = muf.write(m(md_str))
if __name__ == "__main__":
main()

View File

@@ -1,11 +1,16 @@
>h1 Heading 8-)
>>h2 Heading
>>>h3 Heading
>>>h4 Heading
>>>h5 Heading
>>>h6 Heading
> h1 Heading 8-)
>>Horizontal Rules
>> h2 Heading
>>> h3 Heading
>>> h4 Heading
>>> h5 Heading
>>> h6 Heading
>> Horizontal Rules
-
@@ -13,43 +18,51 @@
-
>>Emphasis
>> Emphasis
`!This is bold text`!
`!This is bold text`!
`*This is italic text`*
`_This is bold text`_
`*This is italic text`*
`_This is italic text`_
~~Strikethrough~~
>>Blockquotes
>> Blockquotes
>>>>Blockquotes can also be nested...
>>>>by using additional greater-than signs right next to each other...
>>>>or with spaces between arrows.
>>Lists
>>>>>>>>by using additional greater-than signs right next to each other...
>>>Unordered
>>>>>>>>>>>>or with spaces between arrows.
>> Lists
>>> Unordered
+ Create a list by starting a line with `=+`=, `=-`=, or `=*`=
+ Marker character change forces new list start:
- Marker character change forces new list start:
+ Ac tristique libero volutpat at
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
+ Nulla volutpat aliquam velit
- Nulla volutpat aliquam velit
+ Very easy
>>>Ordered
>>> Ordered
+ Lorem ipsum dolor sit amet
+ Consectetur adipiscing elit
+ Integer molestie lorem at massa
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
>>Code
>> Code
Inline `=code`=
@@ -59,7 +72,9 @@ Indented code
// Some comments
line 1 of code
line 2 of code
line 3 of code`=
line 3 of code
`=
Block code "fences"
`=
@@ -76,13 +91,13 @@ var foo = function (bar) {
console.log(foo(5));
`=
>>Links
>> Links
`[link text`http://dev.nodeca.com]
`[link with title`http://nodeca.github.io/pica/demo/]
>>Images
>> Images
`[https://octodex.github.com/images/minion.png]
`[The Stormtroopocat`https://octodex.github.com/images/stormtroopocat.jpg]
`[Minion`https://octodex.github.com/images/minion.png]
`[Stormtroopocat`https://octodex.github.com/images/stormtroopocat.jpg]