Update text decorations.

This commit is contained in:
Alex Root Junior 2019-12-31 17:56:12 +02:00
parent cf4e39993b
commit dae96590c3
4 changed files with 97 additions and 77 deletions

View file

@ -1,4 +1,4 @@
from .text_decorations import html, markdown from .text_decorations import html_decoration, markdown_decoration
LIST_MD_SYMBOLS = "*_`[" LIST_MD_SYMBOLS = "*_`["
@ -41,7 +41,7 @@ def bold(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return markdown.bold.format(value=html.quote(_join(*content, sep=sep))) return markdown_decoration.bold.format(value=html_decoration.quote(_join(*content, sep=sep)))
def hbold(*content, sep=" "): def hbold(*content, sep=" "):
@ -52,7 +52,7 @@ def hbold(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return html.bold.format(value=html.quote(_join(*content, sep=sep))) return html_decoration.bold.format(value=html_decoration.quote(_join(*content, sep=sep)))
def italic(*content, sep=" "): def italic(*content, sep=" "):
@ -63,7 +63,7 @@ def italic(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return markdown.italic.format(value=html.quote(_join(*content, sep=sep))) return markdown_decoration.italic.format(value=html_decoration.quote(_join(*content, sep=sep)))
def hitalic(*content, sep=" "): def hitalic(*content, sep=" "):
@ -74,7 +74,7 @@ def hitalic(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return html.italic.format(value=html.quote(_join(*content, sep=sep))) return html_decoration.italic.format(value=html_decoration.quote(_join(*content, sep=sep)))
def code(*content, sep=" "): def code(*content, sep=" "):
@ -85,7 +85,7 @@ def code(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return markdown.code.format(value=html.quote(_join(*content, sep=sep))) return markdown_decoration.code.format(value=html_decoration.quote(_join(*content, sep=sep)))
def hcode(*content, sep=" "): def hcode(*content, sep=" "):
@ -96,7 +96,7 @@ def hcode(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return html.code.format(value=html.quote(_join(*content, sep=sep))) return html_decoration.code.format(value=html_decoration.quote(_join(*content, sep=sep)))
def pre(*content, sep="\n"): def pre(*content, sep="\n"):
@ -107,7 +107,7 @@ def pre(*content, sep="\n"):
:param sep: :param sep:
:return: :return:
""" """
return markdown.pre.format(value=html.quote(_join(*content, sep=sep))) return markdown_decoration.pre.format(value=html_decoration.quote(_join(*content, sep=sep)))
def hpre(*content, sep="\n"): def hpre(*content, sep="\n"):
@ -118,7 +118,7 @@ def hpre(*content, sep="\n"):
:param sep: :param sep:
:return: :return:
""" """
return html.pre.format(value=html.quote(_join(*content, sep=sep))) return html_decoration.pre.format(value=html_decoration.quote(_join(*content, sep=sep)))
def underline(*content, sep=" "): def underline(*content, sep=" "):
@ -129,7 +129,9 @@ def underline(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return markdown.underline.format(value=markdown.quote(_join(*content, sep=sep))) return markdown_decoration.underline.format(
value=markdown_decoration.quote(_join(*content, sep=sep))
)
def hunderline(*content, sep=" "): def hunderline(*content, sep=" "):
@ -140,7 +142,7 @@ def hunderline(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return html.underline.format(value=html.quote(_join(*content, sep=sep))) return html_decoration.underline.format(value=html_decoration.quote(_join(*content, sep=sep)))
def strikethrough(*content, sep=" "): def strikethrough(*content, sep=" "):
@ -151,7 +153,9 @@ def strikethrough(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return markdown.strikethrough.format(value=markdown.quote(_join(*content, sep=sep))) return markdown_decoration.strikethrough.format(
value=markdown_decoration.quote(_join(*content, sep=sep))
)
def hstrikethrough(*content, sep=" "): def hstrikethrough(*content, sep=" "):
@ -162,7 +166,9 @@ def hstrikethrough(*content, sep=" "):
:param sep: :param sep:
:return: :return:
""" """
return html.strikethrough.format(value=html.quote(_join(*content, sep=sep))) return html_decoration.strikethrough.format(
value=html_decoration.quote(_join(*content, sep=sep))
)
def link(title: str, url: str) -> str: def link(title: str, url: str) -> str:
@ -173,7 +179,7 @@ def link(title: str, url: str) -> str:
:param url: :param url:
:return: :return:
""" """
return markdown.link.format(value=html.quote(title), link=url) return markdown_decoration.link.format(value=html_decoration.quote(title), link=url)
def hlink(title: str, url: str) -> str: def hlink(title: str, url: str) -> str:
@ -184,7 +190,7 @@ def hlink(title: str, url: str) -> str:
:param url: :param url:
:return: :return:
""" """
return html.link.format(value=html.quote(title), link=url) return html_decoration.link.format(value=html_decoration.quote(title), link=url)
def hide_link(url: str) -> str: def hide_link(url: str) -> str:

View file

@ -6,7 +6,13 @@ from typing import AnyStr, Callable, Generator, Iterable, List, Optional
from aiogram.api.types import MessageEntity from aiogram.api.types import MessageEntity
__all__ = ("TextDecoration", "html", "markdown", "add_surrogate", "remove_surrogate") __all__ = (
"TextDecoration",
"html_decoration",
"markdown_decoration",
"add_surrogate",
"remove_surrogate",
)
@dataclass @dataclass
@ -82,7 +88,7 @@ class TextDecoration:
yield self.quote(text[offset:length]) yield self.quote(text[offset:length])
html = TextDecoration( html_decoration = TextDecoration(
link='<a href="{link}">{value}</a>', link='<a href="{link}">{value}</a>',
bold="<b>{value}</b>", bold="<b>{value}</b>",
italic="<i>{value}</i>", italic="<i>{value}</i>",
@ -93,18 +99,18 @@ html = TextDecoration(
quote=html.escape, quote=html.escape,
) )
markdown = TextDecoration( MARKDOWN_QUOTE_PATTERN = re.compile(r"([_*\[\]()~`>#+\-|{}.!])")
markdown_decoration = TextDecoration(
link="[{value}]({link})", link="[{value}]({link})",
bold="*{value}*", bold="*{value}*",
italic="_{value}_", italic="_{value}_\r",
code="`{value}`", code="`{value}`",
pre="```{value}```", pre="```{value}```",
underline="--{value}--", # Is not supported underline="__{value}__",
strikethrough="~~{value}~~", # Is not supported strikethrough="~{value}~",
quote=lambda text: re.sub( quote=lambda text: re.sub(pattern=MARKDOWN_QUOTE_PATTERN, repl=r"\\\1", string=text),
pattern=r"([*_`\[])", repl=r"\\\1", string=text )
), # Is not always helpful
) # Markdown is not recommended for usage. Use HTML instead
def add_surrogate(text: str) -> str: def add_surrogate(text: str) -> str:

View file

@ -14,15 +14,15 @@ class TestMarkdown:
[markdown.text, ("test", "test"), None, "test test"], [markdown.text, ("test", "test"), None, "test test"],
[markdown.bold, ("test", "test"), " ", "*test test*"], [markdown.bold, ("test", "test"), " ", "*test test*"],
[markdown.hbold, ("test", "test"), " ", "<b>test test</b>"], [markdown.hbold, ("test", "test"), " ", "<b>test test</b>"],
[markdown.italic, ("test", "test"), " ", "_test test_"], [markdown.italic, ("test", "test"), " ", "_test test_\r"],
[markdown.hitalic, ("test", "test"), " ", "<i>test test</i>"], [markdown.hitalic, ("test", "test"), " ", "<i>test test</i>"],
[markdown.code, ("test", "test"), " ", "`test test`"], [markdown.code, ("test", "test"), " ", "`test test`"],
[markdown.hcode, ("test", "test"), " ", "<code>test test</code>"], [markdown.hcode, ("test", "test"), " ", "<code>test test</code>"],
[markdown.pre, ("test", "test"), " ", "```test test```"], [markdown.pre, ("test", "test"), " ", "```test test```"],
[markdown.hpre, ("test", "test"), " ", "<pre>test test</pre>"], [markdown.hpre, ("test", "test"), " ", "<pre>test test</pre>"],
[markdown.underline, ("test", "test"), " ", "--test test--"], [markdown.underline, ("test", "test"), " ", "__test test__"],
[markdown.hunderline, ("test", "test"), " ", "<u>test test</u>"], [markdown.hunderline, ("test", "test"), " ", "<u>test test</u>"],
[markdown.strikethrough, ("test", "test"), " ", "~~test test~~"], [markdown.strikethrough, ("test", "test"), " ", "~test test~"],
[markdown.hstrikethrough, ("test", "test"), " ", "<s>test test</s>"], [markdown.hstrikethrough, ("test", "test"), " ", "<s>test test</s>"],
[markdown.link, ("test", "https://aiogram.dev"), None, "[test](https://aiogram.dev)"], [markdown.link, ("test", "https://aiogram.dev"), None, "[test](https://aiogram.dev)"],
[ [

View file

@ -3,32 +3,36 @@ from typing import List, Optional
import pytest import pytest
from aiogram.api.types import MessageEntity, User from aiogram.api.types import MessageEntity, User
from aiogram.utils.text_decorations import TextDecoration, html, markdown from aiogram.utils.text_decorations import TextDecoration, html_decoration, markdown_decoration
class TestTextDecoration: class TestTextDecoration:
@pytest.mark.parametrize( @pytest.mark.parametrize(
"decorator,entity,result", "decorator,entity,result",
[ [
[html, MessageEntity(type="url", offset=0, length=5), "test"], [html_decoration, MessageEntity(type="url", offset=0, length=5), "test"],
[ [
html, html_decoration,
MessageEntity(type="text_link", offset=0, length=5, url="https://aiogram.dev"), MessageEntity(type="text_link", offset=0, length=5, url="https://aiogram.dev"),
'<a href="https://aiogram.dev">test</a>', '<a href="https://aiogram.dev">test</a>',
], ],
[html, MessageEntity(type="bold", offset=0, length=5), "<b>test</b>"], [html_decoration, MessageEntity(type="bold", offset=0, length=5), "<b>test</b>"],
[html, MessageEntity(type="italic", offset=0, length=5), "<i>test</i>"], [html_decoration, MessageEntity(type="italic", offset=0, length=5), "<i>test</i>"],
[html, MessageEntity(type="code", offset=0, length=5), "<code>test</code>"], [html_decoration, MessageEntity(type="code", offset=0, length=5), "<code>test</code>"],
[html, MessageEntity(type="pre", offset=0, length=5), "<pre>test</pre>"], [html_decoration, MessageEntity(type="pre", offset=0, length=5), "<pre>test</pre>"],
[html, MessageEntity(type="underline", offset=0, length=5), "<u>test</u>"], [html_decoration, MessageEntity(type="underline", offset=0, length=5), "<u>test</u>"],
[html, MessageEntity(type="strikethrough", offset=0, length=5), "<s>test</s>"],
[html, MessageEntity(type="hashtag", offset=0, length=5), "test"],
[html, MessageEntity(type="cashtag", offset=0, length=5), "test"],
[html, MessageEntity(type="bot_command", offset=0, length=5), "test"],
[html, MessageEntity(type="email", offset=0, length=5), "test"],
[html, MessageEntity(type="phone_number", offset=0, length=5), "test"],
[ [
html, html_decoration,
MessageEntity(type="strikethrough", offset=0, length=5),
"<s>test</s>",
],
[html_decoration, MessageEntity(type="hashtag", offset=0, length=5), "test"],
[html_decoration, MessageEntity(type="cashtag", offset=0, length=5), "test"],
[html_decoration, MessageEntity(type="bot_command", offset=0, length=5), "test"],
[html_decoration, MessageEntity(type="email", offset=0, length=5), "test"],
[html_decoration, MessageEntity(type="phone_number", offset=0, length=5), "test"],
[
html_decoration,
MessageEntity( MessageEntity(
type="text_mention", type="text_mention",
offset=0, offset=0,
@ -37,25 +41,29 @@ class TestTextDecoration:
), ),
'<a href="tg://user?id=42">test</a>', '<a href="tg://user?id=42">test</a>',
], ],
[html, MessageEntity(type="url", offset=0, length=5), "test"], [html_decoration, MessageEntity(type="url", offset=0, length=5), "test"],
[ [
html, html_decoration,
MessageEntity(type="text_link", offset=0, length=5, url="https://aiogram.dev"), MessageEntity(type="text_link", offset=0, length=5, url="https://aiogram.dev"),
'<a href="https://aiogram.dev">test</a>', '<a href="https://aiogram.dev">test</a>',
], ],
[markdown, MessageEntity(type="bold", offset=0, length=5), "*test*"], [markdown_decoration, MessageEntity(type="bold", offset=0, length=5), "*test*"],
[markdown, MessageEntity(type="italic", offset=0, length=5), "_test_"], [markdown_decoration, MessageEntity(type="italic", offset=0, length=5), "_test_\r"],
[markdown, MessageEntity(type="code", offset=0, length=5), "`test`"], [markdown_decoration, MessageEntity(type="code", offset=0, length=5), "`test`"],
[markdown, MessageEntity(type="pre", offset=0, length=5), "```test```"], [markdown_decoration, MessageEntity(type="pre", offset=0, length=5), "```test```"],
[markdown, MessageEntity(type="underline", offset=0, length=5), "--test--"], [markdown_decoration, MessageEntity(type="underline", offset=0, length=5), "__test__"],
[markdown, MessageEntity(type="strikethrough", offset=0, length=5), "~~test~~"],
[markdown, MessageEntity(type="hashtag", offset=0, length=5), "test"],
[markdown, MessageEntity(type="cashtag", offset=0, length=5), "test"],
[markdown, MessageEntity(type="bot_command", offset=0, length=5), "test"],
[markdown, MessageEntity(type="email", offset=0, length=5), "test"],
[markdown, MessageEntity(type="phone_number", offset=0, length=5), "test"],
[ [
markdown, markdown_decoration,
MessageEntity(type="strikethrough", offset=0, length=5),
"~test~",
],
[markdown_decoration, MessageEntity(type="hashtag", offset=0, length=5), "test"],
[markdown_decoration, MessageEntity(type="cashtag", offset=0, length=5), "test"],
[markdown_decoration, MessageEntity(type="bot_command", offset=0, length=5), "test"],
[markdown_decoration, MessageEntity(type="email", offset=0, length=5), "test"],
[markdown_decoration, MessageEntity(type="phone_number", offset=0, length=5), "test"],
[
markdown_decoration,
MessageEntity( MessageEntity(
type="text_mention", type="text_mention",
offset=0, offset=0,
@ -74,16 +82,16 @@ class TestTextDecoration:
@pytest.mark.parametrize( @pytest.mark.parametrize(
"decorator,before,after", "decorator,before,after",
[ [
[html, "test", "test"], [html_decoration, "test", "test"],
[html, "test < test", "test &lt; test"], [html_decoration, "test < test", "test &lt; test"],
[html, "test > test", "test &gt; test"], [html_decoration, "test > test", "test &gt; test"],
[html, "test & test", "test &amp; test"], [html_decoration, "test & test", "test &amp; test"],
[html, "test @ test", "test @ test"], [html_decoration, "test @ test", "test @ test"],
[markdown, "test", "test"], [markdown_decoration, "test", "test"],
[markdown, "[test]", "\\[test]"], [markdown_decoration, "[test]", "\\[test\\]"],
[markdown, "test ` test", "test \\` test"], [markdown_decoration, "test ` test", "test \\` test"],
[markdown, "test * test", "test \\* test"], [markdown_decoration, "test * test", "test \\* test"],
[markdown, "test _ test", "test \\_ test"], [markdown_decoration, "test _ test", "test \\_ test"],
], ],
) )
def test_quote(self, decorator: TextDecoration, before: str, after: str): def test_quote(self, decorator: TextDecoration, before: str, after: str):
@ -92,10 +100,10 @@ class TestTextDecoration:
@pytest.mark.parametrize( @pytest.mark.parametrize(
"decorator,text,entities,result", "decorator,text,entities,result",
[ [
[html, "test", None, "test"], [html_decoration, "test", None, "test"],
[html, "test", [], "test"], [html_decoration, "test", [], "test"],
[ [
html, html_decoration,
"test1 test2 test3 test4 test5 test6 test7", "test1 test2 test3 test4 test5 test6 test7",
[ [
MessageEntity(type="bold", offset=6, length=29), MessageEntity(type="bold", offset=6, length=29),
@ -105,7 +113,7 @@ class TestTextDecoration:
"test1 <b>test2 <u>test3</u> test4 <i>test5</i> test6</b> test7", "test1 <b>test2 <u>test3</u> test4 <i>test5</i> test6</b> test7",
], ],
[ [
html, html_decoration,
"test1 test2 test3 test4 test5", "test1 test2 test3 test4 test5",
[ [
MessageEntity(type="bold", offset=6, length=17), MessageEntity(type="bold", offset=6, length=17),
@ -114,7 +122,7 @@ class TestTextDecoration:
"test1 <b>test2 <u>test3</u> test4</b> test5", "test1 <b>test2 <u>test3</u> test4</b> test5",
], ],
[ [
html, html_decoration,
"test1 test2 test3 test4", "test1 test2 test3 test4",
[ [
MessageEntity(type="bold", offset=6, length=11), MessageEntity(type="bold", offset=6, length=11),
@ -123,19 +131,19 @@ class TestTextDecoration:
"test1 <b>test2 <u>test3</u></b> test4", "test1 <b>test2 <u>test3</u></b> test4",
], ],
[ [
html, html_decoration,
"test1 test2 test3", "test1 test2 test3",
[MessageEntity(type="bold", offset=6, length=5)], [MessageEntity(type="bold", offset=6, length=5)],
"test1 <b>test2</b> test3", "test1 <b>test2</b> test3",
], ],
[ [
html, html_decoration,
"test1 test2", "test1 test2",
[MessageEntity(type="bold", offset=0, length=5)], [MessageEntity(type="bold", offset=0, length=5)],
"<b>test1</b> test2", "<b>test1</b> test2",
], ],
[ [
html, html_decoration,
"strike bold", "strike bold",
[ [
MessageEntity(type="strikethrough", offset=0, length=6), MessageEntity(type="strikethrough", offset=0, length=6),
@ -144,7 +152,7 @@ class TestTextDecoration:
"<s>strike</s> <b>bold</b>", "<s>strike</s> <b>bold</b>",
], ],
[ [
html, html_decoration,
"test", "test",
[ [
MessageEntity(type="strikethrough", offset=0, length=5), MessageEntity(type="strikethrough", offset=0, length=5),
@ -153,7 +161,7 @@ class TestTextDecoration:
"<s><b>test</b></s>", "<s><b>test</b></s>",
], ],
[ [
html, html_decoration,
"strikeboldunder", "strikeboldunder",
[ [
MessageEntity(type="strikethrough", offset=0, length=15), MessageEntity(type="strikethrough", offset=0, length=15),