Advanced formatting add-ons for Telethon with predictable Markdown and HTML parsing
Project description
๐งฉ Delimiters
Advanced Markdown & HTML Formatting for Telethon
delimiters is a production-grade formatting engine for Telethon that provides lossless, round-trip safe conversion between:
- Markdown
- HTML
- Telegram message entities
It is designed for userbots, bots, editors, exporters, mirrors, and archives that need full control over Telegram formatting โ including custom emojis, spoilers, blockquotes, and mentions.
โจ Why Delimiters Exists
Telegram internally does not use Markdown or HTML.
It stores formatting as entities (MessageEntityBold, MessageEntitySpoiler, etc.).
Most libraries:
- Lose formatting on edit
- Break nested entities
- Mishandle emojis & Unicode
- Cannot round-trip safely
Delimiters solves this properly.
Markdown and HTML are treated as serialization formats.
Telegram entities are treated as the source of truth.
๐ฅ Key Features
โ Unified API
One API for everything:
parse(text, mode="md" | "html")
unparse(text, entities, mode="md" | "html")
โ Full Telegram Entity Support
-
Bold / Italic / Underline / Strike
-
Spoilers
-
Inline code & code blocks
-
Collapsed & expanded blockquotes
-
Mentions
(tg://user?id=...) -
Text URLs
-
Custom emojis
-
Email & URL entities
-
HTML
<tg-spoiler>and<tg-emoji>
โ Lossless Round-Trip
- Markdown โ Entities โ Markdown HTML โ Entities โ HTML
No formatting is lost. No corruption. No surprises.
โ Advanced Markdown Extensions
!!underline!!
||spoiler||
%%collapsed blockquote%%
^^expanded blockquote^^
Activated automatically on import.
โ Unicode & Emoji Safe
-
Fully surrogate-safe
-
Works with all Unicode text
-
Handles custom emojis correctly
๐ฆ Installation
From project root:
pip install delimiters
๐ Project Structure
delimiters/
โโโ __init__.py # Public API
โโโ api.py # Unified parse / unparse
โโโ custom_markdown.py # Markdown โ Telegram entities
โโโ markdown_ext.py # Extra markdown delimiters
โโโ html_ext.py # HTML โ Telegram entities
setup.py
๐ฅ Importing
โ Recommended (Unified API)
from delimiters import parse, unparse
๐ง Advanced Imports (Optional)
from delimiters import CustomMarkdown
from delimiters import CustomHtmlParser
from delimiters import markdown
Use these only if you need low-level control.
๐ง Core Concepts (Must Read)
Telegram messages consist of:
text: str
entities: List[MessageEntity]
โ Telegram does NOT store Markdown or HTML.
delimiters converts between:
Markdown / HTML โ (text + entities)
๐ Basic Usage
Sending a Formatted Message
text, entities = parse("**Hello** ||secret||")
await client.send_message(chat_id, text, entities=entities)
Editing a Message Safely
text, entities = parse("!!Edited!!")
await message.edit(text, entities=entities)
Round-Trip Editing (Lossless)
md = unparse(message.text, message.entities)
text, entities = parse(md)
await message.edit(text, entities=entities)
โ๏ธ Markdown Support
Inline Formatting
**bold** __italic__ !!underline!! ~~strike~~ ||spoiler|| inline code``
Blockquotes
^^Expanded quote^^
%%Collapsed quote%%
-
Per-entity collapsed state preserved
-
Nesting supported
Mentions (Safe Everywhere)
[User](tg://user?id=93602376)
- โ Works in Saved Messages
- โ Not stripped by Telegram
Custom Emojis


- โ Converts to
MessageEntityCustomEmoji - โ Fully round-trip safe
๐ HTML Support
Supported Tags
<b>Bold</b>
<i>Italic</i>
<u>Underline</u>
<del>Strike</del>
<tg-spoiler>Spoiler</tg-spoiler>
<blockquote collapsed>Collapsed</blockquote>
<blockquote>Expanded</blockquote>
<tg-emoji emoji-id="5210952531676504517"></tg-emoji>
<a href="tg://user?id=93602376">Mention</a>
HTML โ Telegram
text, entities = parse(html, mode="html")
Telegram โ HTML
html = unparse(text, entities, mode="html")
๐งฉ Public API Reference
parse(text, mode="md")
Convert Markdown or HTML into Telegram-ready text & entities.
Parameters
text: str
mode: "md" | "html"
Returns
Tuple[str, List[MessageEntity]]
unparse(text, entities, mode="md")
Convert Telegram entities back to Markdown or HTML.
Parameters
text: str
entities: Iterable[MessageEntity]
mode: "md" | "html"
Returns
str
๐งช Advanced Usage
Accessing Low-Level Parsers
text, entities = CustomMarkdown.parse(md)
md = CustomMarkdown.unparse(text, entities)
text, entities = CustomHtmlParser.parse(html)
html = CustomHtmlParser.unparse(text, entities)
Using Extra Markdown Delimiters Directly
from delimiters import markdown
This activates:
!! โ underline
|| โ spoiler
%% โ collapsed quote
^^ โ expanded quote
๐ก๏ธ Safety Guarantees
- No entity overlap corruption
- Emoji & Unicode safe
- Nested entities preserved
- Telethon โฅ 1.34 compatible
- No monkey-patching core logic
๐ง Design Philosophy
-
Telegram entities are the source of truth
-
Markdown & HTML are serialization layers
-
Explicit > magic
-
Predictable > clever
This library is built for developers who understand Telegram deeply.
๐ When You Should Use This
- โ Advanced userbots
- โ Message editors
- โ Telegram โ HTML exporters
- โ Telegram mirrors
- โ Archival tools
- โ Emoji-heavy chats
๐ค Final Words
This project is intentionally:
-
Minimal
-
Explicit
-
Lossless
-
Production-ready
If you maintain a serious Telethon project, this is the formatting layer you want.
๐ License
This project is licensed under the MIT License.
See the full license or text here: https://opensource.org/licenses/MIT
ยฉ 2026 Ankit Chaubey. All rights reserved.
This project was initially developed for personal use and is now released publicly.
๐ฌ Contact
- Email: m.ankitchaubey@gmail.com
- Telegram: @ankify
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file delimiters-0.1.0.tar.gz.
File metadata
- Download URL: delimiters-0.1.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf3f2ed4870605b36287b81d9f262058293552bd4a70cc7c6529719ba6f082b6
|
|
| MD5 |
242f2bd9fafaef479e28ef56d557e4e5
|
|
| BLAKE2b-256 |
7ce13aa787e6c8588224bcee2ecb2f520f9b451855fcdf8035cf9abd4de41773
|
Provenance
The following attestation bundles were made for delimiters-0.1.0.tar.gz:
Publisher:
publish.yml on ankit-chaubey/delimiters
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
delimiters-0.1.0.tar.gz -
Subject digest:
bf3f2ed4870605b36287b81d9f262058293552bd4a70cc7c6529719ba6f082b6 - Sigstore transparency entry: 804814725
- Sigstore integration time:
-
Permalink:
ankit-chaubey/delimiters@35d271f5ec81399c4481da5fb8d1fc9f42a46377 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ankit-chaubey
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@35d271f5ec81399c4481da5fb8d1fc9f42a46377 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file delimiters-0.1.0-py3-none-any.whl.
File metadata
- Download URL: delimiters-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf1d6fcd43d7edba60c16772326f07c5dddf71a925e369cf4f7a08dcddee38e6
|
|
| MD5 |
daf5e02faf44eea5e88c2641c58516b1
|
|
| BLAKE2b-256 |
e8a6b29a7c24c1dadbf767ece10622eee4da21049d02afb77e30fecbe632d3b9
|
Provenance
The following attestation bundles were made for delimiters-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on ankit-chaubey/delimiters
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
delimiters-0.1.0-py3-none-any.whl -
Subject digest:
cf1d6fcd43d7edba60c16772326f07c5dddf71a925e369cf4f7a08dcddee38e6 - Sigstore transparency entry: 804814747
- Sigstore integration time:
-
Permalink:
ankit-chaubey/delimiters@35d271f5ec81399c4481da5fb8d1fc9f42a46377 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ankit-chaubey
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@35d271f5ec81399c4481da5fb8d1fc9f42a46377 -
Trigger Event:
workflow_dispatch
-
Statement type: