p2dmd is a Markdown to Telegram-specific-markdown converter.
Project description
p2dmd
p2dmd is a Python library by addy that converts standard Markdown to Telegram MarkdownV2, so you can send richly formatted messages through the Telegram Bot API without manually escaping every special character.
Why p2dmd?
Telegram's MarkdownV2 format requires that almost every special character (_ * [ ] ( ) ~ \ > # + - = | { } . !`) be escaped with a backslash. Doing this by hand is tedious and error-prone. p2dmd handles all of that automatically, while also converting LaTeX math to readable Unicode and splitting oversized code blocks.
Installation
pip install p2dmd
Quick Start
from p2dmd import escape
text = """
# My Heading
This is **bold**, _italic_, __underlined__, and ~~strikethrough~~.
Hide a secret with ||spoiler text||.
Inline code: `print("hello")`
```python
def greet(name):
return f"Hello, {name}!"
A blockquote
- Item A
- Item B
- Nested item
- First step
- Second step
Math: ( \varphi(35) = 35 \left(1 - \frac{1}{5}\right) \left(1 - \frac{1}{7}\right) ) """
result = escape(text)
Now send it with your bot
import requests requests.post( "https://api.telegram.org/bot<YOUR_TOKEN>/sendMessage", json={ "chat_id": "<CHAT_ID>", "text": result, "parse_mode": "MarkdownV2" } )
---
## Supported Syntax
| Input (Markdown) | Output (Telegram MarkdownV2) | Notes |
|---|---|---|
| `**bold**` | `*bold*` | Bold text |
| `_italic_` | `_italic_` | Italic text |
| `__underline__` | `__underline__` | Underlined text |
| `~~strike~~` | `~strike~` | Strikethrough |
| `\|\|spoiler\|\|` | `\|\|spoiler\|\|` | Hidden/spoiler text |
| `` `code` `` | `` `code` `` | Inline code |
| ` ```lang ... ``` ` | ` ```lang ... ``` ` | Code block (with language) |
| `[text](url)` | `[text](url)` | Clickable link |
| `` | `[alt](url)` | Image as link (Telegram doesn't embed images in text) |
| `> quote` | `> quote` | Blockquote |
| `# Heading` | `▎*Heading*` | Section heading |
| `- item` / `* item` | `• item` | Bullet list |
| `1. item` | `1\. item` | Numbered list |
| `\( expr \)` | Unicode math | Inline LaTeX |
| `\[ expr \]` | Unicode math (block) | Display LaTeX |
---
## API Reference
### `escape(text, flag=0, italic=True)`
The main function. Takes a Markdown string and returns a Telegram MarkdownV2-safe string.
```python
from p2dmd import escape
result = escape(text)
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
text |
str |
required | Markdown text to convert |
flag |
int |
0 |
Set to 1 to preserve literal \\ double backslashes in output |
italic |
bool |
True |
Set to False to skip _italic_ conversion (useful if your text uses underscores in variable names) |
Returns: str — the escaped, Telegram-ready string.
Sending Long Messages
Telegram has a 4096 character limit per message. p2dmd automatically splits code blocks longer than 2300 characters. After calling escape(), check for the split marker \n@|@|@|@\n\n and send each part as a separate message:
from p2dmd import escape
result = escape(my_long_text)
parts = result.split("\n@|@|@|@\n\n")
for part in parts:
requests.post(
"https://api.telegram.org/bot<TOKEN>/sendMessage",
json={"chat_id": chat_id, "text": part, "parse_mode": "MarkdownV2"}
)
LaTeX / Math Support
p2dmd converts LaTeX expressions to Unicode characters, making math readable even in plain text:
| LaTeX | Unicode |
|---|---|
\varphi(35) = 35(1 - \frac{1}{5})(1 - \frac{1}{7}) |
ϕ(35) = 35(1 - ⅕)(1 - 1/7) |
\alpha + \beta = \gamma |
α + β = γ |
\sum_{i=1}^{n} i = \frac{n(n+1)}{2} |
∑ᵢ₌₁ⁿ i = n(n+1)/2 |
\sqrt{2} |
√2̄ |
a^2 + b^2 = c^2 |
a² + b² = c² |
Supported: Greek letters, operators, arrows, fractions, subscripts, superscripts, and over 300 symbols. See src/latex2unicode.py for the full symbol table.
Publishing to PyPI (Trusted Publishing)
This repo uses OIDC Trusted Publishing — no PyPI API token needed.
One-time setup on PyPI:
- Go to your project on pypi.org → Publishing → Add a new publisher
- Fill in:
- GitHub owner:
pooraddyy - Repository name:
p2dmd - Workflow filename:
main.yml - Environment name:
pypi
- GitHub owner:
- On GitHub, create a Repository Environment named
pypi(Settings → Environments)
To publish a release:
git tag v1.0.0
git push origin v1.0.0
The workflow triggers automatically on version tags and publishes to PyPI.
Reference
- Telegram MarkdownV2 spec: https://core.telegram.org/bots/api#markdownv2-style
- Inspired by: https://github.com/skoropadas/telegramify-markdown
License
GPLv3 — free to use, modify, and distribute under the same license.
Project details
Release history Release notifications | RSS feed
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 p2dmd-0.3.10.tar.gz.
File metadata
- Download URL: p2dmd-0.3.10.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c2e9aaab0bd78a9d1f68d96fea8d348f6a7a6f80891b59a51612b8de9bbc92b
|
|
| MD5 |
fa2f5ae0d0697f4ace4ee3c0f7c52853
|
|
| BLAKE2b-256 |
d5b63bc129e30dce0147bad6fac96993b5bd8830d7ea740c3dc090c6d585662a
|
Provenance
The following attestation bundles were made for p2dmd-0.3.10.tar.gz:
Publisher:
main.yml on pooraddyy/p2dmd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
p2dmd-0.3.10.tar.gz -
Subject digest:
5c2e9aaab0bd78a9d1f68d96fea8d348f6a7a6f80891b59a51612b8de9bbc92b - Sigstore transparency entry: 1468252585
- Sigstore integration time:
-
Permalink:
pooraddyy/p2dmd@c4417fcc967c47eff65c8305c68af646991acae9 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/pooraddyy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
main.yml@c4417fcc967c47eff65c8305c68af646991acae9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file p2dmd-0.3.10-py3-none-any.whl.
File metadata
- Download URL: p2dmd-0.3.10-py3-none-any.whl
- Upload date:
- Size: 25.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2be5ceaa2f197605bd519dc17c608533e4630831f3d9ab15b1ca1916eda7bfab
|
|
| MD5 |
e3a087fe5562d7020a8382471e5bfc0a
|
|
| BLAKE2b-256 |
be9d770a134de38259b1743986488e62c90fd570abcd4dc1404887df706bfa13
|
Provenance
The following attestation bundles were made for p2dmd-0.3.10-py3-none-any.whl:
Publisher:
main.yml on pooraddyy/p2dmd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
p2dmd-0.3.10-py3-none-any.whl -
Subject digest:
2be5ceaa2f197605bd519dc17c608533e4630831f3d9ab15b1ca1916eda7bfab - Sigstore transparency entry: 1468253014
- Sigstore integration time:
-
Permalink:
pooraddyy/p2dmd@c4417fcc967c47eff65c8305c68af646991acae9 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/pooraddyy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
main.yml@c4417fcc967c47eff65c8305c68af646991acae9 -
Trigger Event:
push
-
Statement type: