Skip to content

Commit

Permalink
Merge pull request #30 from sudoskys/dev
Browse files Browse the repository at this point in the history
feat(latex helper): readable latex
  • Loading branch information
sudoskys authored Oct 21, 2024
2 parents 92293af + d777051 commit 0229382
Show file tree
Hide file tree
Showing 13 changed files with 1,143 additions and 62 deletions.
Binary file added .github/result-7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/result-8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
161 changes: 118 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@
[![PyPI version](https://badge.fury.io/py/telegramify-markdown.svg)](https://badge.fury.io/py/telegramify-markdown)
[![Downloads](https://pepy.tech/badge/telegramify-markdown)](https://pepy.tech/project/telegramify-markdown)

> 🪄 Python Telegram Markdown Converter | No more formatting headaches.
**Effortlessly Convert Raw Markdown to Telegram's [MarkdownV2](https://core.telegram.org/bots/api#markdownv2-style)
Style**

**Convert Raw Markdown to Telegram's MarkdownV2 Style**
Say goodbye to formatting issues! You no longer need to write parsers to convert raw Markdown text into Telegram's
MarkdownV2 format.

Introducing a robust Python library that enhances Markdown formatting support in Telegram. This library automatically
processes various Markdown inputs, preserving the original formatting without requiring manual escaping. It simplifies
your Markdown interactions on Telegram with seamless auto-processing.
This library is designed to make reading and sending Markdown content on Telegram easier and more efficient. It is ideal
for LLM responses, GitHub README files, and more.

Before this library, sending and rendering unknown Markdown content (like GitHub's README files) required complex
parsing and reconstruction. Now, you can easily handle this and customize it for better results!
Forget about formatting errors from the API. Our custom renderer has been tested in a real server environment to ensure
its effectiveness.

Utilizing a custom renderer, the library has been tested in a real server environment to ensure its efficacy.
We also support Latex Visualization(escape) and Expanded Citation.

> For those interested, there is also a Node.js version of the library with the same
> name: [npm:telegramify-markdown](https://www.npmjs.com/package/telegramify-markdown)
> [!NOTE]
> If you're interested, there's also a Node.js version of the library
> available: [npm:telegramify-markdown](https://www.npmjs.com/package/telegramify-markdown).
## Installation

Expand All @@ -33,45 +35,56 @@ or, if you use `pdm`:
pdm add telegramify-markdown
```

## Supported Input

- [x] Headings (Levels 1-6)
- [x] `Links [text](url)`
- [x] `Images ![alt](url)`
- [x] Lists (Ordered and Unordered)
- [x] Tables `|-|-|`
- [x] Horizontal Rules `----`
- [x] Text Styles `*Italic*` and `**Bold**`
- [x] Underline `__Underline__` (if `customize.strict_markdown` is False)
- [x] Code Blocks
- [x] Inline Code
- [x] Block Quotes `>`
- [x] Strikethrough `~~Strikethrough~~`
- [x] Spoilers `||Spoiler||`
- [x] Task Lists
- [x] Expanded Citation
- [ ] Strikethrough `~Strikethrough~`
- [ ] Telegram Emojis
- [ ] Telegram User Mentions

> [!NOTE]
> Despite `~Strikethrough~` being mentioned in Telegram's official documentation, it can't be parsed as strikethrough.
## Use case

| Exp 1 | Exp 2 |
|---------------------------------|---------------------------------|
| ![result](.github/result-7.png) | ![result](.github/result-8.png) |

````python3
import telegramify_markdown
from telegramify_markdown import customize

customize.markdown_symbol.head_level_1 = "📌" # If you want, Customizing the head level 1 symbol
customize.markdown_symbol.link = "🔗" # If you want, Customizing the link symbol
customize.strict_markdown = True # If you want to use __underline__ as underline, set it to False, or it will be converted to bold.
customize.strict_markdown = True # If you want to use __underline__ as underline, set it to False, or it will be converted to bold as telegram does.
customize.cite_expandable = True # If you want to enable expandable citation, set it to True.
markdown_text = """
customize.latex_escape = True # If you want to escape LaTeX symbols, set it to True.

# Use `r` to avoid escaping the backslash.
markdown_text = r"""
# Title
## Subtitle
### Subsubtitle
#### Subsubsubtitle
\(TEST
\\(TEST
\\\(TEST
\\\\(TEST
\\\\\(TEST
**Latex Math**
Function Change:
\(\Delta y = f(x_2) - f(x_1)\) can represent the change in the value of a function.
Average Rate of Change:
\(\frac{\Delta y}{\Delta x} = \frac{f(x_2) - f(x_1)}{x_2 - x_1}\) is used to denote the average rate of change of a function over the interval \([x_1, x_2]\).
- Slope:
\[
F = G\frac{{m_1m_2}}{{r^2}}
\]
- Inline: \(F = G\frac{{m_1m_2}}{{r^4}}\)
There \frac{1}{2} not in the latex block.
**Table**
| Tables | Are | Cool |
| ------------- |:-------------:| -----:|
| | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
'\_', '\*', '\[', '\]', '\(', '\)', '\~', '\`', '\>', '\#', '\+', '\-', '\=', '\|', '\{', '\}', '\.', '\!'
_ , * , [ , ] , ( , ) , ~ , ` , > , # , + , - , = , | , { , } , . , !
We will remove the \ symbol from the original text.
Expand All @@ -89,13 +102,18 @@ __underline italic bold__
- [x] Completed task list item
> Quote
> Multiline Quote In Markdown it's not possible to send multiline quote in telegram without using code block or html tag but telegramify_markdown can do it.
>Multiline Quote In Markdown it's not possible to send multiline quote in telegram without using code block or html tag but telegramify_markdown can do it.
---
Text
Text
Text
> If you quote is too long, it will be automatically set in expandable citation.
> This is the second line of the quote.
> This is the third line of the quote.
> `This is the third line of the quote.`
> This is the fourth line of the quote.
> This is the fifth line of the quote.
> `This is the fifth line of the quote.`
```python
print("Hello, World!")
Expand All @@ -116,9 +134,66 @@ print(converted)
# export Markdown to Telegram MarkdownV2 style.
````

output as follows:
## Supported Input

- [x] Headings (Levels 1-6)
- [x] `Links [text](url)`
- [x] `Images ![alt](url)`
- [x] Lists (Ordered and Unordered)
- [x] Tables `|-|-|`
- [x] Horizontal Rules `----`
- [x] Text Styles `*Italic*` and `**Bold**`
- [x] Underline `__Underline__` (if `customize.strict_markdown` is False)
- [x] Code Blocks
- [x] Inline Code
- [x] Block Quotes `>`
- [x] Strikethrough `~~Strikethrough~~`
- [x] Spoilers `||Spoiler||`
- [x] Task Lists
- [x] Expanded Citation
- [ ] Strikethrough `~Strikethrough~`
- [ ] Telegram Emojis
- [ ] Telegram User Mentions

> [!NOTE]
> Despite `~Strikethrough~` being mentioned in Telegram's official documentation, it can't be parsed as strikethrough.
## Proper Usage

```python
import textwrap

from telebot import TeleBot

import telegramify_markdown
import telegramify_markdown.customize as customize

customize.strict_markdown = False
value1 = 52222
markdown_text = textwrap.dedent(
f"""
# Title
## Subtitle
value1: {value1}
||spoiler||
"""
)
can_be_sent = telegramify_markdown.markdownify(markdown_text)
TeleBot("TOKEN").send_message(
"CHAT_ID",
can_be_sent,
parse_mode="MarkdownV2"
)
```

## Acknowledgement

This library is inspired by [npm:telegramify-markdown](https://www.npmjs.com/package/telegramify-markdown).

latex escape is inspired by [latex2unicode](https://github.com/tomtung/latex2unicode) and @yym68686.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

| Exp 1 | Exp 2 |
|---------------------------------|---------------------------------|
| ![result](.github/result-5.png) | ![result](.github/result-6.png) |

22 changes: 22 additions & 0 deletions playground/re_t.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import re

sp_p = re.compile(r"(?<!\\)(?:\\\\)*\|\|(.+?)\|\|", re.DOTALL)
todo_p = re.compile(r"^- \[([ xX])\] (.*)", re.DOTALL | re.MULTILINE)
math_p = re.compile(r'(?:\$\$(.*?)\$\$|\\\[(.*?)\\\])', re.DOTALL | re.MULTILINE)
inline_math_p = re.compile(r'(?<!\\)(?:\\\\)*\$(.+?)\$', re.DOTALL)
math = r"""
\[
\begin{aligned}
\text{Let } f(x) &= \frac{1}{x} \\
\text{Then } f'(x) &= -\frac{1}{x^2} \\
\text{And } f''(x) &= \frac{2}{x^3}
\end{aligned}
\]
inline $f(x) = \frac{1}{x}$
"""

print(inline_math_p.findall(math))
print("====")
print(math_p.findall(math))
35 changes: 31 additions & 4 deletions playground/show_send.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import telegramify_markdown

telegramify_markdown.customize.strict_markdown = False # we need send underline text
telegramify_markdown.customize.latex_escape = True # we need to escape latex
run_1 = telegramify_markdown.markdownify(
"Hello, World! HTML: &lt;strong&gt;Hello, World!&lt;/strong&gt;"
)
print(run_1)
md = """
md = r"""
# Title
## Subtitle
### Subsubtitle
Expand All @@ -22,6 +23,27 @@
\\\\(TEST
\\\\\(TEST
**Latex Math**
Function Change:
\(\Delta y = f(x_2) - f(x_1)\) can represent the change in the value of a function.
Average Rate of Change:
\(\frac{\Delta y}{\Delta x} = \frac{f(x_2) - f(x_1)}{x_2 - x_1}\) is used to denote the average rate of change of a function over the interval \([x_1, x_2]\).
- Slope:
\[
F = G\frac{{m_1m_2}}{{r^2}}
\]
- Inline: \(F = G\frac{{m_1m_2}}{{r^4}}\)
There \frac{1}{2} not in the latex block.
**Table**
| Tables | Are | Cool |
| ------------- |:-------------:| -----:|
| | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
'\_', '\*', '\[', '\]', '\(', '\)', '\~', '\`', '\>', '\#', '\+', '\-', '\=', '\|', '\{', '\}', '\.', '\!'
_ , * , [ , ] , ( , ) , ~ , ` , > , # , + , - , = , | , { , } , . , !
We will remove the \ symbol from the original text.
Expand All @@ -39,13 +61,18 @@
- [x] Completed task list item
> Quote
> Multiline Quote In Markdown it's not possible to send multiline quote in telegram without using code block or html tag but telegramify_markdown can do it.
>Multiline Quote In Markdown it's not possible to send multiline quote in telegram without using code block or html tag but telegramify_markdown can do it.
---
Text
Text
Text
> If you quote is too long, it will be automatically set in expandable citation.
> This is the second line of the quote.
> This is the third line of the quote.
> `This is the third line of the quote.`
> This is the fourth line of the quote.
> This is the fifth line of the quote.
> `This is the fifth line of the quote.`
```python
print("Hello, World!")
Expand Down
19 changes: 14 additions & 5 deletions playground/use_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,19 @@
**bold text**
||spoiler||
"""
converted = telegramify_markdown.convert(task)
math = r"""
\[
\begin{aligned}
\text{Let } f(x) &= \frac{1}{x} \\
\text{Then } f'(x) &= -\frac{1}{x^2} \\
\text{And } f''(x) &= \frac{2}{x^3}
\end{aligned}
\]
$ f(x) = \frac{1}{x} $
"""

converted = telegramify_markdown.convert(math)
print(converted)

rule = re.compile(r"(?<!\\)(?:\\\\)*\|\|(.+?)\|\|", re.DOTALL)
pattern = re.compile(r"^- \[([ xX])\] (.*)", re.DOTALL | re.MULTILINE)
print(rule.findall(test_md))
print(pattern.findall(task))

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "telegramify-markdown"
version = "0.1.13"
version = "0.1.14"
description = "Convert Markdown to a format usable by Telegram."
authors = [
{ name = "sudoskys", email = "coldlando@hotmail.com" },
Expand Down
Loading

0 comments on commit 0229382

Please sign in to comment.