English | 简体中文
Convert Markdown to plain text + MessageEntity format required by Telegram Bot API.
- ✅ Full Markdown Support: Headings, lists, tables, code blocks, quotes, and more
- ✅ LaTeX to Unicode: Automatically converts LaTeX math formulas to Unicode symbols
- ✅ Smart Message Splitting: Intelligently splits long messages by UTF-16 length
- ✅ Code Block Extraction: Automatically extracts code blocks as files
- ✅ Mermaid Rendering: Supports rendering Mermaid diagrams as images
- ✅ Zero Dependencies Core: Core conversion has no external dependencies (except Mermaid rendering)
go get github.com/riverfjs/telegramify-gopackage main
import (
"fmt"
tg "github.com/riverfjs/telegramify-go"
)
func main() {
markdown := `# Hello World
This is **bold** and *italic* text.
\`\`\`python
print("Hello, Telegram!")
\`\`\`
`
// Convert to plain text + entities
text, entities := tg.Convert(markdown, true, nil)
fmt.Println("Text:", text)
fmt.Println("Entities:", len(entities))
}package main
import (
"context"
"fmt"
tg "github.com/riverfjs/telegramify-go"
)
func main() {
markdown := `# Long Document Example
This is a very long document...
\`\`\`go
func main() {
fmt.Println("Code will be extracted as files")
}
\`\`\`
`
ctx := context.Background()
contents, err := tg.Telegramify(ctx, markdown, 4096, true, nil)
if err != nil {
panic(err)
}
for _, content := range contents {
switch c := content.(type) {
case *tg.Text:
fmt.Printf("Text message: %d characters\n", len(c.Text))
case *tg.File:
fmt.Printf("File: %s (%d bytes)\n", c.FileName, len(c.FileData))
case *tg.Photo:
fmt.Printf("Photo: %s\n", c.FileName)
}
}
}func Convert(markdown string, latexEscape bool, config *RenderConfig) (string, []MessageEntity)Converts Markdown to (plain text, entities).
Parameters:
markdown: Raw Markdown textlatexEscape: Whether to convert LaTeX to Unicodeconfig: Render configuration, nil uses default config
Returns:
string: Plain text[]MessageEntity: Entity list
func Telegramify(ctx context.Context, content string, maxMessageLength int, latexEscape bool, config *RenderConfig) ([]Content, error)Full processing pipeline: conversion, splitting, file extraction, Mermaid rendering.
Parameters:
ctx: Contextcontent: Raw Markdown textmaxMessageLength: Maximum UTF-16 length per message (Telegram limit is 4096)latexEscape: Whether to convert LaTeX to Unicodeconfig: Render configuration
Returns:
[]Content: List of Text, File, or Photo objects
type RenderConfig struct {
MarkdownSymbol *Symbol
CiteExpandable bool
}
type Symbol struct {
HeadingLevel1 string // Default: 📌
HeadingLevel2 string // Default: 📝
HeadingLevel3 string // Default: 📋
HeadingLevel4 string // Default: 📄
HeadingLevel5 string // Default: 📃
HeadingLevel6 string // Default: 🔖
Quote string // Default: 💬
Image string // Default: 🖼
TaskCompleted string // Default: ✅
TaskUncompleted string // Default: ☑️
}- Headings: H1-H6, with custom prefix symbols
- Emphasis: bold, italic,
strikethrough - Lists: Ordered lists, unordered lists, task lists
- Code: Inline code, code blocks (with language identifiers)
- Quotes: Single-line and multi-line quotes
- Links: text
- Images:
- Tables: GitHub-flavored tables
- Math: LaTeX to Unicode conversion
- Custom Emoji:
tg://emoji?id=... - Spoilers: ||hidden text||
Telegram requires entity offsets and lengths to be calculated in UTF-16 code units. This library handles it automatically:
text := "Hello 世界 🌍"
length := tg.UTF16Len(text) // 10 (not 9 runes)telegramify-go/
├── entity.go # MessageEntity and UTF-16 utilities
├── content.go # Output type definitions
├── config.go # Configuration system
├── converter.go # Converter public API
├── pipeline.go # Processing pipeline
├── telegramify.go # Main entry point
├── internal/
│ ├── types/ # Shared type definitions
│ ├── buffer/ # Text buffer
│ ├── converter/ # Core converter
│ │ ├── walker.go # AST walker
│ │ ├── preprocess.go # Preprocessing
│ │ └── segment.go # Segment definitions
│ ├── parser/ # Markdown parser
│ ├── latex/ # LaTeX to Unicode
│ │ ├── symbols.go # Symbol table
│ │ ├── parser.go # Recursive descent parser
│ │ └── latex.go # Public interface
│ ├── mermaid/ # Mermaid rendering
│ └── util/ # Utility functions
└── go.mod
- Core: goldmark - Markdown parser
- Optional: None (Mermaid rendering uses standard library HTTP client)
- Type System: Go's strong type system provides better type safety
- Concurrency: Go's goroutines support more efficient concurrent processing
- Performance: Compiled language, better performance
- Dependencies: Core functionality has zero external dependencies (Python version depends on pyromark)
# Clone repository
git clone https://github.com/riverfjs/telegramify-go.git
cd telegramify-go
# Build
go build ./...
# Test
go test ./...
# Run examples
go run examples/basic/main.go- Validation gates passed:
go test ./...,go test ./... -race,go vet ./... - Current coverage snapshot: overall
84.3% - Core package coverage:
internal/converter91.6%,internal/latex88.2%,internal/mermaid84.4%,internal/parser100%,internal/util100% examples/*are demo programs and are not a test coverage target
MIT License
This library is inspired by npm:telegramify-markdown.