mirror of https://gitlab.com/bashrc2/epicyon
Improve markdown support
parent
bc083f4bbe
commit
d3b1b5acda
126
markdown.py
126
markdown.py
|
@ -32,7 +32,13 @@ def _markdown_emphasis_html(markdown: str) -> str:
|
|||
'_:': '</ul>:',
|
||||
'_;': '</ul>;',
|
||||
'_,': '</ul>,',
|
||||
'_\n': '</ul>\n'
|
||||
'_\n': '</ul>\n',
|
||||
' `': '<em>',
|
||||
'`.': '</em>',
|
||||
'`:': '</em>',
|
||||
'`;': '</em>',
|
||||
'`\n': '</em>',
|
||||
'` ': '</em>'
|
||||
}
|
||||
for md_str, html in replacements.items():
|
||||
markdown = markdown.replace(md_str, html)
|
||||
|
@ -61,7 +67,19 @@ def _markdown_replace_quotes(markdown: str) -> str:
|
|||
lines = markdown.split('\n')
|
||||
result = ''
|
||||
prev_quote_line = None
|
||||
code_section = False
|
||||
for line in lines:
|
||||
# avoid code sections
|
||||
if not code_section:
|
||||
if '<code>' in line:
|
||||
code_section = True
|
||||
else:
|
||||
if '</code>' in line:
|
||||
code_section = False
|
||||
if code_section:
|
||||
result += line + '\n'
|
||||
continue
|
||||
|
||||
if '> ' not in line:
|
||||
result += line + '\n'
|
||||
prev_quote_line = None
|
||||
|
@ -128,9 +146,101 @@ def _markdown_replace_links(markdown: str, images: bool = False) -> str:
|
|||
return markdown
|
||||
|
||||
|
||||
def _markdown_replace_bullet_points(markdown: str) -> str:
|
||||
"""Replaces bullet points
|
||||
"""
|
||||
lines = markdown.split('\n')
|
||||
bullet_style = ('* ', ' * ', '- ', ' - ')
|
||||
bullet_matched = ''
|
||||
start_line = -1
|
||||
line_ctr = 0
|
||||
changed = False
|
||||
code_section = False
|
||||
for line in lines:
|
||||
if not line.strip():
|
||||
# skip blank lines
|
||||
line_ctr += 1
|
||||
continue
|
||||
|
||||
# skip over code sections
|
||||
if not code_section:
|
||||
if '<code>' in line:
|
||||
code_section = True
|
||||
else:
|
||||
if '</code>' in line:
|
||||
code_section = False
|
||||
if code_section:
|
||||
line_ctr += 1
|
||||
continue
|
||||
|
||||
if not bullet_matched:
|
||||
for test_str in bullet_style:
|
||||
if line.startswith(test_str):
|
||||
bullet_matched = test_str
|
||||
start_line = line_ctr
|
||||
break
|
||||
else:
|
||||
if not line.startswith(bullet_matched):
|
||||
for index in range(start_line, line_ctr):
|
||||
line_text = lines[index].replace(bullet_matched, '', 1)
|
||||
if index == start_line:
|
||||
lines[index] = '<ul>\n<li>' + line_text + '</li>'
|
||||
elif index == line_ctr - 1:
|
||||
lines[index] = '<li>' + line_text + '</li>\n</ul>'
|
||||
else:
|
||||
lines[index] = '<li>' + line_text + '</li>'
|
||||
changed = True
|
||||
start_line = -1
|
||||
bullet_matched = ''
|
||||
line_ctr += 1
|
||||
|
||||
if not changed:
|
||||
return markdown
|
||||
|
||||
markdown = ''
|
||||
for line in lines:
|
||||
markdown += line + '\n'
|
||||
return markdown
|
||||
|
||||
|
||||
def _markdown_replace_code(markdown: str) -> str:
|
||||
"""Replaces code sections within markdown
|
||||
"""
|
||||
lines = markdown.split('\n')
|
||||
start_line = -1
|
||||
line_ctr = 0
|
||||
changed = False
|
||||
section_active = False
|
||||
for line in lines:
|
||||
if not line.strip():
|
||||
# skip blank lines
|
||||
line_ctr += 1
|
||||
continue
|
||||
if line.startswith('```'):
|
||||
if not section_active:
|
||||
start_line = line_ctr
|
||||
section_active = True
|
||||
else:
|
||||
lines[start_line] = '<code>'
|
||||
lines[line_ctr] = '</code>'
|
||||
section_active = False
|
||||
changed = True
|
||||
line_ctr += 1
|
||||
|
||||
if not changed:
|
||||
return markdown
|
||||
|
||||
markdown = ''
|
||||
for line in lines:
|
||||
markdown += line + '\n'
|
||||
return markdown
|
||||
|
||||
|
||||
def markdown_to_html(markdown: str) -> str:
|
||||
"""Converts markdown formatted text to html
|
||||
"""
|
||||
markdown = _markdown_replace_code(markdown)
|
||||
markdown = _markdown_replace_bullet_points(markdown)
|
||||
markdown = _markdown_replace_quotes(markdown)
|
||||
markdown = _markdown_emphasis_html(markdown)
|
||||
markdown = _markdown_replace_links(markdown, True)
|
||||
|
@ -140,6 +250,7 @@ def markdown_to_html(markdown: str) -> str:
|
|||
lines_list = markdown.split('\n')
|
||||
html_str = ''
|
||||
ctr = 0
|
||||
code_section = False
|
||||
titles = {
|
||||
"h5": '#####',
|
||||
"h4": '####',
|
||||
|
@ -150,6 +261,19 @@ def markdown_to_html(markdown: str) -> str:
|
|||
for line in lines_list:
|
||||
if ctr > 0:
|
||||
html_str += '<br>'
|
||||
|
||||
# avoid code sections
|
||||
if not code_section:
|
||||
if '<code>' in line:
|
||||
code_section = True
|
||||
else:
|
||||
if '</code>' in line:
|
||||
code_section = False
|
||||
if code_section:
|
||||
html_str += line
|
||||
ctr += 1
|
||||
continue
|
||||
|
||||
for hsh, hashes in titles.items():
|
||||
if line.startswith(hashes):
|
||||
line = line.replace(hashes, '').strip()
|
||||
|
|
|
@ -6,7 +6,7 @@ The ActivityPub protocol is a decentralized social networking protocol based upo
|
|||
|
||||
## Status of This Document
|
||||
|
||||
*This document is based upon the 2018 version of the []W3C ActivityPub specification](https://www.w3.org/TR/activitypub). Any alterations are for the purposes of more accurately reflecting the actual use of the protocol, with the aim of creating less confusion for new implementors.*
|
||||
*This document is based upon the 2018 version of the [W3C ActivityPub specification](https://www.w3.org/TR/activitypub). Any alterations are for the purposes of more accurately reflecting the actual use of the protocol, with the aim of creating less confusion for new implementors.*
|
||||
|
||||
# 1. Overview
|
||||
|
||||
|
@ -19,8 +19,8 @@ ActivityPub implementations can implement just one of these things or both of th
|
|||
|
||||
In ActivityPub, a user is represented by "actors" via the user's accounts on servers. User's accounts on different servers correspond to different actors. Every Actor has:
|
||||
|
||||
- **An `inbox`:** How they get messages from the world
|
||||
- **An `outbox`:** How they send messages to others
|
||||
* **An `inbox`:** How they get messages from the world
|
||||
* **An `outbox`:** How they send messages to others
|
||||
|
||||
![An Actor with inbox and outbox](activitypub-tutorial-1.png)
|
||||
|
||||
|
|
26
tests.py
26
tests.py
|
@ -5725,6 +5725,32 @@ def _test_markdown_to_html():
|
|||
'This is a multi-line quotation:<br>' + \
|
||||
'<blockquote><i>The first line The second line</i></blockquote>'
|
||||
|
||||
markdown = 'This is a list of points:\n' + \
|
||||
' * Point 1\n' + \
|
||||
' * Point 2\n\n' + \
|
||||
'And some other text.'
|
||||
result = markdown_to_html(markdown)
|
||||
expected = \
|
||||
'This is a list of points:<br><ul><br><li>Point 1</li><br>' + \
|
||||
'<li>Point 2</li><br><li></li><br></ul><br>And some other text.<br>'
|
||||
if result != expected:
|
||||
print(result)
|
||||
assert result == expected
|
||||
|
||||
markdown = 'This is a code section:\n' + \
|
||||
'``` json\n' + \
|
||||
'10 PRINT "YOLO"\n' + \
|
||||
'20 GOTO 10\n' + \
|
||||
'```\n\n' + \
|
||||
'And some other text.'
|
||||
result = markdown_to_html(markdown)
|
||||
expected = \
|
||||
'This is a code section:<br><code><br>10 PRINT "YOLO"<br>' + \
|
||||
'20 GOTO 10<br></code><br><br>And some other text.<br>'
|
||||
if result != expected:
|
||||
print(result)
|
||||
assert result == expected
|
||||
|
||||
markdown = 'This is **bold**'
|
||||
assert markdown_to_html(markdown) == 'This is <b>bold</b>'
|
||||
|
||||
|
|
Loading…
Reference in New Issue