Text FormattingΒΆ
wzgram uses a custom Markdown dialect for text formatting which adds some unique features that make writing styled texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a variety of decorations that can also be nested in order to combine multiple styles together.
The official BOT API style HTML formatting is also supported
Tip
The default parse mode, DEFAULT, understands both
syntaxes in one message, so **bold** and <blockquote> can sit side by side.
MARKDOWN and HTML are
the strict modes: each escapes the otherβs syntax, so a tag inside strict Markdown is
sent as literal text. DISABLED sends everything as
written.
Basic StylesΒΆ
When formatting your messages, you can choose between Markdown-style, HTML-style or both (default). The following is a list of the basic styles currently supported by wzgram.
bold
italic
underline
strike
blockquote
inline fixed-width codepre-formatted fixed-width code blockspoiler
HTML StyleΒΆ
To strictly use this mode, pass HTML to the parse_mode parameter when using
send_message(). The following tags are currently supported:
<b>bold</b>, <strong>bold</strong>
<i>italic</i>, <em>italic</em>
<u>underline</u>, <ins>underline</ins>
<s>strike</s>, <del>strike</del>, <strike>strike</strike>
<tg-spoiler>spoiler</tg-spoiler>, <span class="tg-spoiler">spoiler</span>
<blockquote>block quotation</blockquote>
<blockquote expandable>expandable block quotation</blockquote>
<a href="https://rjriajul.github.io/wzgram/">text URL</a>
<a href="tg://user?id=123456789">inline mention</a>
<code>inline fixed-width code</code>
<tg-emoji emoji-id="5469770542288478598">π</tg-emoji>
<tg-time unix="1735689600" format="d">formatted date and time</tg-time>
<pre>
<code class="language-python">
pre-formatted fixed-width code block written in the Python programming language
</code>
</pre>
Example:
from pyrogram.enums import ParseMode
await app.send_message(
chat_id="me",
text=(
"<b>bold</b>, <strong>bold</strong>"
"<i>italic</i>, <em>italic</em>"
"<u>underline</u>, <ins>underline</ins>"
"<s>strike</s>, <strike>strike</strike>, <del>strike</del>"
"<tg-spoiler>spoiler</tg-spoiler>\n\n"
"<b>bold <i>italic bold <s>italic bold strike <tg-spoiler>italic bold strike spoiler</tg-spoiler></s> <u>underline italic bold</u></i> bold</b>\n\n"
"<a href=\"https://rjriajul.github.io/wzgram/\">inline URL</a> "
"<a href=\"tg://user?id=23122162\">inline mention of a user</a>\n"
"<tg-emoji emoji-id=5469770542288478598>π</tg-emoji> "
"<code>inline fixed-width code</code> "
"<pre>pre-formatted fixed-width code block</pre>\n\n"
"<pre><code class='language-python'>"
"for i in range(10):\n"
" print(i)"
"</code></pre>\n\n"
"<tg-time unix=\"1735689600\" format=\"d\">today</tg-time>\n\n"
"<blockquote>Block quotation started"
"Block quotation continued"
"The last line of the block quotation</blockquote>"
"<blockquote expandable>Expandable block quotation started"
"Expandable block quotation continued"
"Expandable block quotation continued"
"Hidden by default part of the block quotation started"
"Expandable block quotation continued"
"The last line of the block quotation</blockquote>"
),
parse_mode=ParseMode.HTML
)
Note
All <, > and & symbols that are not a part of a tag or an HTML entity must be replaced with the
corresponding HTML entities (< with <, > with > and & with &). You can use this
snippet to quickly escape those characters:
text = "<my & text>"
text = text.replace("<", "<").replace("&", "&")
print(text)
<my & text>
Markdown StyleΒΆ
To strictly use this mode, pass MARKDOWN to the parse_mode parameter when using
send_message(). Use the following syntax in your message:
Note
There is no Markdown syntax for blockquotes or custom emoji. A leading > is
sent as a literal >, and  parses as a text link. Use
<blockquote> and <tg-emoji> instead β in HTML mode, or mixed into the default
combined mode.
**bold**
__italic__
--underline--
~~strike~~
`inline fixed-width code`
```
pre-formatted
fixed-width
code block
```
||spoiler||
[text URL](https://rjriajul.github.io/wzgram/)
[text user mention](tg://user?id=123456789)
Example:
from pyrogram.enums import ParseMode
await app.send_message(
chat_id="me",
text=(
"**bold**, "
"__italic__, "
"--underline--, "
"~~strike~~, "
"||spoiler||, "
"[URL](https://rjriajul.github.io/wzgram/), "
"`code`, "
"```py"
"for i in range(10):\n"
" print(i)"
"```\n"
),
parse_mode=ParseMode.MARKDOWN
)
Different StylesΒΆ
By default, when ignoring the parse_mode parameter, both Markdown and HTML styles are enabled together. This means you can combine together both syntaxes in the same text:
await app.send_message(chat_id="me", text="**bold**, <i>italic</i>")
Result:
bold, italic
If you donβt like this behaviour you can always choose to only enable either Markdown or HTML in strict mode by passing
MARKDOWN or HTML as argument to the parse_mode parameter.
from pyrogram.enums import ParseMode
await app.send_message(chat_id="me", text="**bold**, <i>italic</i>", parse_mode=ParseMode.MARKDOWN)
await app.send_message(chat_id="me", text="**bold**, <i>italic</i>", parse_mode=ParseMode.HTML)
Result:
bold, <i>italic</i>
**bold**, italic
In case you want to completely turn off the style parser, simply pass DISABLED to parse_mode.
The text will be sent as-is.
from pyrogram.enums import ParseMode
await app.send_message(chat_id="me", text="**bold**, <i>italic</i>", parse_mode=ParseMode.DISABLED)
Result:
**bold**, <i>italic</i>
Nested and Overlapping EntitiesΒΆ
Warning
The Markdown style is not recommended for complex text formatting.
If you want to use complex text formatting such as nested entities, overlapping entities use the HTML style instead.
You can also style texts with more than one decoration at once by nesting entities together. For example, you can send a text message with both bold and underline styles, or a text that has both italic and strike styles, and you can still combine both Markdown and HTML together.
Here there are some example texts you can try sending:
Markdown:
**bold, --underline--****bold __italic --underline ~~strike~~--__****bold __and** italic__
HTML:
<b>bold, <u>underline</u></b><b>bold <i>italic <u>underline <s>strike</s></u></i></b><b>bold <i>and</b> italic</i>
Combined:
--you can combine <i>HTML</i> with **Markdown**--**and also <i>overlap** --entities</i> this way--
RichText (Rich Media Text Formatting)ΒΆ
RichText is used for page blocks, article rendering and inline rich media formatting. It is a different wire format from MessageEntity-based text formatting and supports additional decorations.
The following RichText types are available for reading (parsing) from Telegram page blocks:
RichTextPlain β plain text string
RichTextBold β bold text
RichTextItalic β italic text
RichTextUnderline β underlined text
RichTextStrikethrough β strikethrough text
RichTextSpoiler β spoiler text
RichTextCode β monospace / inline code
RichTextSubscript β subscript text
RichTextSuperscript β superscript text
RichTextMarked β highlighted / marked text
RichTextDateTime β formatted date and time
RichTextCustomEmoji β custom emoji
RichTextMathematicalExpression β LaTeX math expression
RichTextUrl β text with URL
RichTextEmailAddress β email address
RichTextPhoneNumber β phone number
RichTextBankCardNumber β bank card number
RichTextMention β username mention
RichTextHashtag β hashtag
RichTextCashtag β cashtag
RichTextBotCommand β bot command
RichTextTextMention β user mention by ID
RichTextAnchor β named anchor
RichTextAnchorLink β link to an anchor
RichTextReference β reference to an anchor
RichTextReferenceLink β link to a reference
RichTextImage β inline image
To construct rich messages for sending, use InputRichMessage
with raw HTML or Markdown text, which is parsed server-side:
from pyrogram.types import InputRichMessage
rich = InputRichMessage(
html="<b>bold</b> <tg-emoji emoji-id=5469770542288478598>π</tg-emoji>"
)
# Pass to methods that accept InputRichMessage (e.g. answer_web_app)