diff --git a/pyrogram/client/style/__init__.py b/pyrogram/client/parser/__init__.py
similarity index 93%
rename from pyrogram/client/style/__init__.py
rename to pyrogram/client/parser/__init__.py
index 768cee7b..4769038d 100644
--- a/pyrogram/client/style/__init__.py
+++ b/pyrogram/client/parser/__init__.py
@@ -16,5 +16,4 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see .
-from .html import HTML
-from .markdown import Markdown
+from .parser import Parser
\ No newline at end of file
diff --git a/pyrogram/client/parser/parser.py b/pyrogram/client/parser/parser.py
new file mode 100644
index 00000000..afb7ecaa
--- /dev/null
+++ b/pyrogram/client/parser/parser.py
@@ -0,0 +1,56 @@
+# Pyrogram - Telegram MTProto API Client Library for Python
+# Copyright (C) 2017-2019 Dan Tès
+#
+# This file is part of Pyrogram.
+#
+# Pyrogram is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrogram is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrogram. If not, see .
+
+from collections import OrderedDict
+from typing import Union
+
+
+import pyrogram
+from .html import HTML
+from .markdown import Markdown
+
+
+class Parser:
+ def __init__(self, client: Union["pyrogram.BaseClient", None]):
+ self.html = HTML(client)
+ self.markdown = Markdown(client)
+
+ def parse(self, text: str, mode: str = ""):
+ if mode is None:
+ return OrderedDict([
+ ("message", text),
+ ("entities", [])
+ ])
+
+ mode = mode.lower()
+
+ if mode == "":
+ return self.markdown.parse(text)
+
+ if mode in ["markdown", "md"]:
+ return self.markdown.parse(text, True)
+
+ if mode == "html":
+ return self.html.parse(text)
+
+ @staticmethod
+ def unparse(text: str, entities: list, is_html: bool):
+ if is_html:
+ return HTML.unparse(text, entities)
+ else:
+ return Markdown.unparse(text, entities)
diff --git a/pyrogram/client/style/utils.py b/pyrogram/client/parser/utils.py
similarity index 91%
rename from pyrogram/client/style/utils.py
rename to pyrogram/client/parser/utils.py
index b001f1cf..1fce419f 100644
--- a/pyrogram/client/style/utils.py
+++ b/pyrogram/client/parser/utils.py
@@ -35,3 +35,7 @@ def add_surrogates(text):
def remove_surrogates(text):
# Replace each surrogate pair with a SMP code point
return text.encode("utf-16", "surrogatepass").decode("utf-16")
+
+
+def replace_once(source: str, old: str, new: str, start: int):
+ return source[:start] + source[start:].replace(old, new, 1)