Convert between Slack message formats (Mrkdwn, Rich Text) and GitHub Flavored Markdown with AST manipulation
Project description
slack-gfm
Convert between Slack message formats (Mrkdwn, Rich Text) and GitHub Flavored Markdown with AST manipulation.
TL;DR - Quick Start
from slack_gfm import rich_text_to_gfm, gfm_to_rich_text, mrkdwn_to_gfm
# Convert Slack Rich Text to GitHub Flavored Markdown
rich_text = {
"type": "rich_text",
"elements": [{
"type": "rich_text_section",
"elements": [
{"type": "text", "text": "Hello "},
{"type": "user", "user_id": "U123ABC"}
]
}]
}
gfm = rich_text_to_gfm(rich_text)
# Result: "Hello [@U123ABC](slack://user?id=U123ABC)"
# Convert back to Rich Text
rich_text = gfm_to_rich_text(gfm)
# Migrate legacy mrkdwn to GFM
mrkdwn = "*Hello* <@U123ABC|john>"
gfm = mrkdwn_to_gfm(mrkdwn)
# Result: "**Hello** [@john](slack://user?id=U123ABC&name=john)"
Installation
pip install --user slack-gfm
Or with uv:
uv add slack-gfm
Features
- Rich Text <-> GFM: Bidirectional conversion with full round-trip support
- Mrkdwn -> GFM: Migrate legacy Slack messages
- ID Mapping: Map Slack user/channel IDs to display names
- AST Manipulation: Transform messages for ML/MCP or custom processing
- Type Safe: Full type hints for Python 3.12+
Usage
Basic Conversions
from slack_gfm import rich_text_to_gfm, gfm_to_rich_text
# Rich Text -> GFM (most common use case)
gfm_text = rich_text_to_gfm(rich_text_data)
# GFM -> Rich Text (for creating Slack messages)
rich_text = gfm_to_rich_text(gfm_text)
ID Mapping
Map Slack IDs to human-readable names:
from slack_gfm import rich_text_to_gfm
gfm = rich_text_to_gfm(
rich_text_data,
user_map={"U123ABC": "john", "U456DEF": "jane"},
channel_map={"C789GHI": "general"}
)
# User mentions become: [@john](slack://user?id=U123ABC&name=john)
# Channel mentions become: [#general](slack://channel?id=C789GHI&name=general)
Advanced: AST Manipulation
For ML training, MCP context, or custom transformations:
from slack_gfm import parse_rich_text, render_gfm
from slack_gfm.ast import NodeVisitor, transform_ast, UserMention, CodeBlock
# Define custom visitor for ML feature extraction
class MLFeatureExtractor(NodeVisitor):
def __init__(self):
self.features = {"users": [], "code_blocks": []}
def visit_usermention(self, node: UserMention):
self.features["users"].append(node.user_id)
return node
def visit_codeblock(self, node: CodeBlock):
# Detect JSON in code blocks
if node.content.strip().startswith("{"):
self.features["code_blocks"].append({
"type": "json",
"content": node.content
})
return node
# Parse and extract features
ast = parse_rich_text(rich_text_data)
extractor = MLFeatureExtractor()
ast = transform_ast(ast, extractor)
# Use features for ML
print(extractor.features)
# {"users": ["U123", "U456"], "code_blocks": [{"type": "json", ...}]}
# Still render to GFM
gfm = render_gfm(ast)
See docs/user-guide.md for more examples and docs/api-reference.md for complete API documentation.
How It Works
slack-gfm uses a common Abstract Syntax Tree (AST) to represent formatted text:
Slack Rich Text -> Parser -> AST -> Renderer -> GFM
^ |
| v
+-------- Renderer <- AST <- Parser <- GFM
Slack Mrkdwn -> Parser -> AST -> Renderer -> GFM
Slack-specific features (user mentions, channel mentions, broadcasts) are preserved using custom slack:// URLs in GFM, enabling perfect round-trip conversion.
Development
# Clone the repository
git clone https://github.com/retcheverry/slack-gfm.git
cd slack-gfm
# Install dependencies
uv sync
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=slack_gfm --cov-report=html
Requirements
- Python 3.12+
- markdown-it-py >= 3.0.0
License
AGPL-3.0-or-later
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
Links
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 slack_gfm-0.1.0.tar.gz.
File metadata
- Download URL: slack_gfm-0.1.0.tar.gz
- Upload date:
- Size: 71.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e57d2d9e408b28c7bf55af1c7a8867c36f13f7b11d12bdd8cce445765574a134
|
|
| MD5 |
20492e203f478d0bdb8a0e569e0158b0
|
|
| BLAKE2b-256 |
9f217c75be91e4b01cea04d7619827b0c45c16d3aa3992b7263c43c0cfa642b0
|
File details
Details for the file slack_gfm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: slack_gfm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58a6c676a788426416eb87c96c4c7d89e6f8085cf34c766c66701e467b423a07
|
|
| MD5 |
2fd73feb7c03577d396ba09c44db6527
|
|
| BLAKE2b-256 |
b7248353fc785766d8df4078ae358d409583d856be6d17af66306af0c520c304
|