slack-markdown-parser 2.2.5__tar.gz → 2.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/CHANGELOG.md +21 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/MANIFEST.in +5 -4
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/PKG-INFO +64 -34
- slack_markdown_parser-2.3.1/README-ja.md +200 -0
- slack_markdown_parser-2.3.1/README.md +231 -0
- slack_markdown_parser-2.3.1/docs/spec-ja.md +232 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/docs/spec.md +72 -43
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/pyproject.toml +1 -1
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser/__init__.py +1 -1
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser/converter.py +159 -16
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/PKG-INFO +64 -34
- slack_markdown_parser-2.3.1/slack_markdown_parser.egg-info/SOURCES.txt +16 -0
- slack_markdown_parser-2.2.5/CONTRIBUTING.md +0 -53
- slack_markdown_parser-2.2.5/README-ja.md +0 -189
- slack_markdown_parser-2.2.5/README.md +0 -201
- slack_markdown_parser-2.2.5/docs/slack-client-manual-checklist.md +0 -53
- slack_markdown_parser-2.2.5/docs/slack-nested-modifier-findings.md +0 -59
- slack_markdown_parser-2.2.5/docs/slack-render-test-workflow.md +0 -117
- slack_markdown_parser-2.2.5/docs/spec-ja.md +0 -206
- slack_markdown_parser-2.2.5/slack_markdown_parser.egg-info/SOURCES.txt +0 -28
- slack_markdown_parser-2.2.5/tests/fixtures/llm_markdown_p0_corpus.md +0 -121
- slack_markdown_parser-2.2.5/tests/fixtures/slack_cjk_inner_code_matrix.md +0 -275
- slack_markdown_parser-2.2.5/tests/fixtures/slack_nested_modifier_matrix.md +0 -365
- slack_markdown_parser-2.2.5/tests/fixtures/slack_nested_modifier_matrix_parens.md +0 -365
- slack_markdown_parser-2.2.5/tests/fixtures/slack_nested_modifier_matrix_quotes.md +0 -365
- slack_markdown_parser-2.2.5/tests/test_converter.py +0 -632
- slack_markdown_parser-2.2.5/tests/test_llm_markdown_p0_corpus.py +0 -49
- slack_markdown_parser-2.2.5/tests/test_nested_modifier_matrix.py +0 -86
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/LICENSE +0 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/setup.cfg +0 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser/py.typed +0 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/dependency_links.txt +0 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/requires.txt +0 -0
- {slack_markdown_parser-2.2.5 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/top_level.txt +0 -0
|
@@ -6,6 +6,27 @@ The format is based on Keep a Changelog, and the project follows Semantic Versio
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.3.1] - 2026-04-10
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Stopped `preserve_visual_blank_lines` from inserting visual-only blank-line placeholders inside fenced code blocks.
|
|
14
|
+
- Kept fallback plain text stable when visual blank-line placeholders are enabled alongside parser-added spacing markers around emphasis or inline code.
|
|
15
|
+
|
|
16
|
+
## [2.3.0] - 2026-04-10
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Documented Slack's March 6, 2026 richer `markdown` block rollout as rollout-dependent in the README and behavior specs, so headers and raw Markdown tables are no longer described as universally stable.
|
|
21
|
+
- Updated maintainer docs with the April 8, 2026 Slack Web rollout observations, including native headers/dividers/task lists/raw Markdown tables and the current blank-line spacing limitation.
|
|
22
|
+
- Extended `scripts/post_slack_render_test.py` with `--transport raw_http|slack_sdk` to compare Web API posting paths while keeping the same markdown payload generation.
|
|
23
|
+
- Split public docs from maintainer QA docs in README / CONTRIBUTING and labeled render-check workflow notes as maintainer-facing rather than end-user package docs.
|
|
24
|
+
- Further reduced README-to-QA coupling by moving maintainer QA doc links behind CONTRIBUTING so the main README stays focused on the public package surface.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Added an opt-in `preserve_visual_blank_lines` argument to the main conversion APIs so parser callers can compensate for Slack's currently tight paragraph spacing inside `markdown` blocks without changing fallback plain text.
|
|
29
|
+
|
|
9
30
|
## [2.2.5] - 2026-03-14
|
|
10
31
|
|
|
11
32
|
### Fixed
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
include LICENSE
|
|
2
2
|
include README.md
|
|
3
3
|
include README-ja.md
|
|
4
|
-
include CONTRIBUTING.md
|
|
5
4
|
include CHANGELOG.md
|
|
6
|
-
|
|
5
|
+
include docs/spec.md
|
|
6
|
+
include docs/spec-ja.md
|
|
7
|
+
exclude CONTRIBUTING.md
|
|
7
8
|
prune docs/_internal
|
|
8
|
-
|
|
9
|
+
prune tests
|
|
9
10
|
recursive-include slack_markdown_parser py.typed
|
|
10
|
-
global-exclude __pycache__ *.py[cod]
|
|
11
|
+
global-exclude __pycache__ *.py[cod] .DS_Store
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: slack-markdown-parser
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.1
|
|
4
4
|
Summary: Convert LLM Markdown into Slack Block Kit markdown/table messages
|
|
5
5
|
Author: darkgaldragon
|
|
6
6
|
License-Expression: MIT
|
|
@@ -31,67 +31,84 @@ Dynamic: license-file
|
|
|
31
31
|
|
|
32
32
|
# slack-markdown-parser
|
|
33
33
|
|
|
34
|
-
`slack-markdown-parser` is a Python library that converts
|
|
34
|
+
`slack-markdown-parser` is a Python library that converts ordinary Markdown generated by LLMs into Slack Block Kit messages built from `markdown` and `table` blocks.
|
|
35
35
|
|
|
36
36
|
## Why this library exists
|
|
37
37
|
|
|
38
38
|
Many Slack AI bots have traditionally converted model output into Slack-specific `mrkdwn`, but that approach creates a few recurring problems:
|
|
39
39
|
|
|
40
|
-
-
|
|
41
|
-
- Unstable formatting in languages without
|
|
42
|
-
- No table syntax in `mrkdwn`:
|
|
40
|
+
- Extra conversion work: LLMs naturally generate ordinary Markdown, so `mrkdwn` usually needs extra conversion logic or stricter prompts.
|
|
41
|
+
- Unstable formatting in languages without spaces between words: in Japanese, Chinese, Korean, and similar writing systems, Slack can fail to interpret `*`, `~`, and related markers correctly, exposing the raw punctuation.
|
|
42
|
+
- No table syntax in `mrkdwn`: if you stay in the old format, Markdown tables need custom table rendering.
|
|
43
43
|
|
|
44
44
|
## Design approach
|
|
45
45
|
|
|
46
|
-
This library
|
|
46
|
+
This library uses Slack Block Kit `markdown` blocks for regular Markdown and `table` blocks for tables.
|
|
47
47
|
|
|
48
48
|
| Problem | Approach |
|
|
49
49
|
|---|---|
|
|
50
|
-
|
|
|
51
|
-
| Formatting instability | Prefer zero-width spaces (
|
|
50
|
+
| Extra conversion work | Send ordinary Markdown through Slack `markdown` blocks without rewriting it into `mrkdwn`. |
|
|
51
|
+
| Formatting instability | Prefer zero-width spaces (`U+200B`) around formatting markers, and only add visible spaces in a few language-specific cases where Slack still renders Japanese, Chinese, or Korean text incorrectly. |
|
|
52
52
|
| No table syntax in `mrkdwn` | Detect Markdown tables and convert them into Slack `table` blocks, including repair of common LLM-generated table inconsistencies. |
|
|
53
53
|
|
|
54
|
-
The
|
|
54
|
+
The goal is natural rendering on Slack, not full CommonMark or HTML fidelity.
|
|
55
55
|
If Slack itself does not support a construct in `markdown` blocks, this library prefers safe plain-text rendering or explicit `table` blocks over aggressive rewrites into old `mrkdwn`.
|
|
56
56
|
|
|
57
57
|
## Features
|
|
58
58
|
|
|
59
|
-
- Convert
|
|
59
|
+
- Convert ordinary Markdown into Slack `markdown` blocks
|
|
60
60
|
- Convert Markdown tables into Slack `table` blocks
|
|
61
61
|
- Repair common LLM table issues such as missing outer pipes, missing separator rows, mismatched column counts, and empty cells
|
|
62
62
|
- Split output into multiple Slack messages when needed to satisfy Slack's "one table per message" constraint
|
|
63
|
-
-
|
|
64
|
-
- Add
|
|
65
|
-
-
|
|
66
|
-
- Support Markdown and Slack-style links inside table cells
|
|
67
|
-
-
|
|
63
|
+
- Remove ANSI/control characters and neutralize invalid Slack angle-bracket tokens before block generation
|
|
64
|
+
- Add zero-width spaces around inline formatting markers to reduce rendering issues outside fenced code blocks, while preserving English-like punctuation-only boundaries that Slack already renders reliably
|
|
65
|
+
- Add visible spaces for a small set of nested inline-code cases in dense Japanese, Chinese, and Korean text when zero-width spaces alone are not enough
|
|
66
|
+
- Support Markdown links and Slack-style links inside table cells
|
|
67
|
+
- Optionally keep blank lines visible inside Slack `markdown` blocks by inserting placeholder lines, while keeping preview text unchanged
|
|
68
|
+
- Build preview text for `chat.postMessage.text` from generated blocks, removing the invisible or temporary spacing that was added only to stabilize Slack rendering
|
|
68
69
|
- Accept raw LLM Markdown without tightly constraining the model prompt, using best-effort sanitize and table repair before Slack delivery
|
|
69
70
|
|
|
70
|
-
##
|
|
71
|
+
## How Slack behaved in testing
|
|
71
72
|
|
|
72
73
|
The library is built around how Slack actually renders `markdown` and `table` blocks in practice.
|
|
73
74
|
|
|
75
|
+
Slack updated its [`markdown` block docs](https://docs.slack.dev/reference/block-kit/blocks/markdown-block/)
|
|
76
|
+
and [changelog entry](https://docs.slack.dev/changelog/2026/03/06/block-kit-rich-text)
|
|
77
|
+
on March 6, 2026 to describe broader support for headings, dividers, task lists,
|
|
78
|
+
native Markdown tables, and syntax-highlighted code blocks. In the Slack Web
|
|
79
|
+
workspace used for this project's April 8, 2026 validation, raw `markdown`
|
|
80
|
+
blocks rendered those constructs natively, including distinct heading levels
|
|
81
|
+
for `#`, `##`, `###`, and setext headings.
|
|
82
|
+
|
|
83
|
+
Slack still controls the exact release timing and visual style of those newer
|
|
84
|
+
features. Treat newer raw Markdown rendering as behavior controlled by Slack,
|
|
85
|
+
not by this library, and verify it in your own workspace, client, and posting
|
|
86
|
+
path.
|
|
87
|
+
|
|
74
88
|
Reliable in current Slack rendering:
|
|
75
89
|
|
|
76
90
|
- `**bold**`, `*italic*`, `~~strike~~`, inline code, and fenced code blocks
|
|
77
|
-
- Bare URLs,
|
|
91
|
+
- Bare URLs, `<https://...>` style links, Markdown links, reference-style links, and mailto links
|
|
78
92
|
- Bullet lists, ordered lists, task lists, and simple blockquotes
|
|
79
93
|
- Explicit Slack `table` blocks generated from Markdown tables
|
|
94
|
+
- In environments where Slack has enabled the newer renderer, raw Markdown headings, dividers, and tables inside `markdown` blocks
|
|
80
95
|
|
|
81
96
|
Known Slack-side limitations:
|
|
82
97
|
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
98
|
+
- Exact heading sizes and some newer raw Markdown features still depend on the Slack app, workspace, and release state
|
|
99
|
+
- Paragraph breaks inside `markdown` blocks currently get little or no extra vertical spacing in tested Slack Web clients, so blank lines can look visually collapsed
|
|
100
|
+
- Nested blockquotes are weaker than in full Markdown renderers
|
|
101
|
+
- Raw Markdown tables inside `markdown` blocks now render in some newer Slack environments, but explicit Slack `table` blocks remain the reliable option across workspaces and delivery paths
|
|
86
102
|
- Markdown image syntax does not become an embedded image in `markdown` blocks
|
|
87
103
|
- Math, raw HTML, HTML comments, `<details>`, admonition syntax, and Mermaid are rendered as plain text or code, not as rich features
|
|
88
104
|
|
|
89
105
|
What this library compensates for:
|
|
90
106
|
|
|
91
107
|
- Normalizes underscore emphasis (`_..._`, `__...__`) into Slack-friendly asterisk emphasis
|
|
92
|
-
- Wraps bare URLs into Slack-friendly
|
|
108
|
+
- Wraps bare URLs into Slack-friendly `<https://...>` link form before sending `markdown` blocks
|
|
93
109
|
- Repairs malformed LLM-generated tables before converting them into Slack `table` blocks
|
|
94
110
|
- Keeps table-like rows inside fenced code blocks out of table normalization
|
|
111
|
+
- Optionally turns internal blank lines into placeholder lines that keep paragraphs visibly separated in Slack `markdown` blocks
|
|
95
112
|
- Neutralizes invalid Slack angle-bracket tokens such as raw HTML-like tags
|
|
96
113
|
|
|
97
114
|
## Requirements
|
|
@@ -121,11 +138,19 @@ markdown = """
|
|
|
121
138
|
| UI | *In progress* |
|
|
122
139
|
"""
|
|
123
140
|
|
|
124
|
-
for payload in convert_markdown_to_slack_payloads(
|
|
141
|
+
for payload in convert_markdown_to_slack_payloads(
|
|
142
|
+
markdown,
|
|
143
|
+
preserve_visual_blank_lines=True,
|
|
144
|
+
):
|
|
125
145
|
print(payload)
|
|
126
146
|
```
|
|
127
147
|
|
|
128
148
|
`convert_markdown_to_slack_messages` automatically splits output into multiple messages when the input contains multiple tables.
|
|
149
|
+
Set `preserve_visual_blank_lines=True` when you want the parser to compensate
|
|
150
|
+
for Slack's currently tight paragraph spacing inside `markdown` blocks.
|
|
151
|
+
The blank-line workaround is intentionally narrow: it skips table segments and
|
|
152
|
+
avoids inserting placeholder lines right before setext heading underlines or
|
|
153
|
+
reference-link definitions.
|
|
129
154
|
|
|
130
155
|
## Rendering example
|
|
131
156
|
|
|
@@ -150,7 +175,7 @@ API | **In progress** | Team A
|
|
|
150
175
|
UI | *Under review* | Team B
|
|
151
176
|
QA | ~~On hold~~ | Team C
|
|
152
177
|
|
|
153
|
-
> Note: production
|
|
178
|
+
> Note: production release is scheduled for 2026-03-08 10:00 JST
|
|
154
179
|
|
|
155
180
|
1. Finalize release notes
|
|
156
181
|
1. Unify change labels
|
|
@@ -174,25 +199,33 @@ Example Slack bot rendering (`markdown` + `table` blocks):
|
|
|
174
199
|
|
|
175
200
|
| Function | Description |
|
|
176
201
|
|---|---|
|
|
177
|
-
| `convert_markdown_to_slack_messages(markdown_text) -> list[list[dict]]` | Convert Markdown into Slack messages already split around table blocks. |
|
|
178
|
-
| `convert_markdown_to_slack_payloads(markdown_text) -> list[dict]` | Convert Markdown into Slack-ready
|
|
179
|
-
| `convert_markdown_to_slack_blocks(markdown_text) -> list[dict]` | Convert Markdown into a flat Block Kit block list. |
|
|
180
|
-
| `build_fallback_text_from_blocks(blocks) -> str` | Build
|
|
202
|
+
| `convert_markdown_to_slack_messages(markdown_text, *, preserve_visual_blank_lines=False) -> list[list[dict]]` | Convert Markdown into Slack messages already split around table blocks. |
|
|
203
|
+
| `convert_markdown_to_slack_payloads(markdown_text, *, preserve_visual_blank_lines=False) -> list[dict]` | Convert Markdown into Slack-ready request data with both `blocks` and preview `text`. |
|
|
204
|
+
| `convert_markdown_to_slack_blocks(markdown_text, *, preserve_visual_blank_lines=False) -> list[dict]` | Convert Markdown into a flat Block Kit block list. |
|
|
205
|
+
| `build_fallback_text_from_blocks(blocks) -> str` | Build preview text suitable for `chat.postMessage.text`. |
|
|
181
206
|
| `blocks_to_plain_text(blocks) -> str` | Convert blocks into plain text. |
|
|
182
207
|
|
|
208
|
+
`preserve_visual_blank_lines=True` replaces internal blank lines in non-table
|
|
209
|
+
Markdown segments with lines that contain only a non-breaking space. Those
|
|
210
|
+
placeholder lines are removed again when generating preview plain text, so Slack
|
|
211
|
+
notifications and logs stay close to the original Markdown source.
|
|
212
|
+
The current implementation deliberately skips blank runs that sit immediately
|
|
213
|
+
before setext-heading underlines or reference-link definitions, because those
|
|
214
|
+
boundaries can change Markdown meaning in newer Slack Markdown rendering.
|
|
215
|
+
|
|
183
216
|
### Utility functions
|
|
184
217
|
|
|
185
218
|
| Function | Description |
|
|
186
219
|
|---|---|
|
|
187
220
|
| `normalize_markdown_tables(markdown_text) -> str` | Normalize Markdown table syntax before conversion. |
|
|
188
|
-
| `add_zero_width_spaces_to_markdown(text) -> str` | Insert
|
|
221
|
+
| `add_zero_width_spaces_to_markdown(text) -> str` | Insert zero-width spaces around formatting tokens where Slack needs stronger boundaries. |
|
|
189
222
|
| `decode_html_entities(text) -> str` | Decode HTML entities before parsing. |
|
|
190
223
|
| `sanitize_slack_text(text) -> str` | Remove ANSI/control noise and neutralize invalid Slack angle-bracket tokens. |
|
|
191
|
-
| `strip_zero_width_spaces(text) -> str` | Remove
|
|
224
|
+
| `strip_zero_width_spaces(text) -> str` | Remove zero-width spaces (`U+200B`) and BOM (`U+FEFF`) while preserving join-control characters such as ZWJ. |
|
|
192
225
|
|
|
193
226
|
### Lower-level exported helpers
|
|
194
227
|
|
|
195
|
-
These are also part of the public package
|
|
228
|
+
These are also part of the public package API:
|
|
196
229
|
|
|
197
230
|
- `add_zero_width_spaces`
|
|
198
231
|
- `convert_markdown_text_to_blocks`
|
|
@@ -206,9 +239,6 @@ These are also part of the public package surface:
|
|
|
206
239
|
|
|
207
240
|
- Behavior spec: [docs/spec.md](docs/spec.md)
|
|
208
241
|
- Japanese behavior spec: [docs/spec-ja.md](docs/spec-ja.md)
|
|
209
|
-
- Slack render-test workflow: [docs/slack-render-test-workflow.md](docs/slack-render-test-workflow.md)
|
|
210
|
-
- Nested-modifier findings: [docs/slack-nested-modifier-findings.md](docs/slack-nested-modifier-findings.md)
|
|
211
|
-
- Desktop/mobile manual checklist: [docs/slack-client-manual-checklist.md](docs/slack-client-manual-checklist.md)
|
|
212
242
|
- Non-goals:
|
|
213
243
|
- Generating Slack `mrkdwn` strings
|
|
214
244
|
- Supporting clients or MCP tools that can only send `mrkdwn`
|
|
@@ -216,7 +246,7 @@ These are also part of the public package surface:
|
|
|
216
246
|
## Contributing
|
|
217
247
|
|
|
218
248
|
Contributions, bug reports, and documentation improvements are welcome.
|
|
219
|
-
Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening an issue or pull request.
|
|
249
|
+
Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening an issue or pull request. Maintainer-facing Slack renderer QA notes are linked from there rather than treated as part of the end-user package docs.
|
|
220
250
|
|
|
221
251
|
## Changelog
|
|
222
252
|
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# slack-markdown-parser
|
|
2
|
+
|
|
3
|
+
LLM が生成するふつうの Markdown を、Slack Block Kit(`markdown` + `table` ブロック)に変換する Python ライブラリです。
|
|
4
|
+
|
|
5
|
+
## 背景
|
|
6
|
+
|
|
7
|
+
Slack で AI BOT を動かすとき、従来は Slack 独自の `mrkdwn` 形式に変換することが多かったのですが、次の課題がありました。
|
|
8
|
+
|
|
9
|
+
- 変換の手間: LLM はふつうの Markdown を出力するため、`mrkdwn` に合わせた変換ロジックや厳しいプロンプト制御が必要になりやすい
|
|
10
|
+
- 装飾の崩れ: 日本語・中国語・韓国語のように単語間に空白を入れない文では、`*` や `~` などの装飾記号がうまく解釈されず、そのまま見えてしまうことがある
|
|
11
|
+
- テーブル非対応: `mrkdwn` には表の構文がないため、表をリストなどへ作り替える必要がある
|
|
12
|
+
|
|
13
|
+
## 設計方針
|
|
14
|
+
|
|
15
|
+
Slack Block Kit の `markdown` ブロックと `table` ブロックを使って、上の課題に対応します。
|
|
16
|
+
|
|
17
|
+
| 課題 | 解決手段 |
|
|
18
|
+
|---|---|
|
|
19
|
+
| 変換の手間 | `markdown` ブロックがふつうの Markdown を受け取れるので、LLM 出力を `mrkdwn` に書き換えずに使う |
|
|
20
|
+
| 装飾の崩れ | 基本はゼロ幅スペース(`U+200B`)で装飾記号の境界を補い、それでも崩れる一部の日本語・中国語・韓国語のケースだけ可視スペースを使う |
|
|
21
|
+
| テーブル非対応 | Markdown テーブルを見つけて `table` ブロックに変換し、LLM が作りがちな表の崩れも自動で補う |
|
|
22
|
+
|
|
23
|
+
このライブラリの目標は、CommonMark や HTML を完全再現することではなく、Slack 上で自然に読める表示を作ることです。
|
|
24
|
+
Slack の `markdown` ブロック自体が対応していない構文は、古い `mrkdwn` へ無理に書き換えるより、安全なプレーンテキスト表示や `table` ブロック化を優先します。
|
|
25
|
+
|
|
26
|
+
## 主な機能
|
|
27
|
+
|
|
28
|
+
- ふつうの Markdown テキストを `markdown` ブロックに変換
|
|
29
|
+
- Markdown テーブルを `table` ブロックに変換
|
|
30
|
+
- LLM が生成する表で起こりやすい崩れ(外枠パイプ不足、区切り行不足、列数不一致、空セル)を補正
|
|
31
|
+
- テーブルごとにメッセージを自動分割し、Slack の「1メッセージ1テーブル」制約に対応
|
|
32
|
+
- ANSI escape / 制御文字を除去し、不正な Slack 角括弧トークンを無害化
|
|
33
|
+
- フェンスドコードブロック外では、装飾記号の前後にゼロ幅スペースを入れて表示崩れを減らす
|
|
34
|
+
- 日本語・中国語・韓国語の詰まった文で、インラインコードを含む装飾が崩れる一部のケースでは可視スペースを補って安定化
|
|
35
|
+
- テーブルセル内の Markdown リンク / Slack 形式リンクを認識
|
|
36
|
+
- `markdown` ブロック内の空行が見えにくい環境向けに、内部空行だけを補助用の行へ置き換える `preserve_visual_blank_lines` オプションを用意
|
|
37
|
+
- `chat.postMessage.text` 用のプレビュー文字列を生成し、Slack 表示を安定させるために入れた補助文字はそこで自然な形に戻す
|
|
38
|
+
- モデル側で Markdown を厳密に制御しなくてもよいよう、Slack 送信前にできる範囲でサニタイズと表補正を行う
|
|
39
|
+
|
|
40
|
+
## 実測ベースの Slack の挙動
|
|
41
|
+
|
|
42
|
+
本ライブラリは、Slack の `markdown` / `table` ブロックが実際にどう見えるかを前提に設計しています。
|
|
43
|
+
|
|
44
|
+
Slack は 2026-03-06 に `markdown` ブロックの公式ドキュメントを更新し、見出し、水平線、タスクリスト、表、言語付きコードブロックなど、これまでより多くの Markdown 記法を案内し始めました。ただし、これらの機能は環境ごとに順番に有効化されるとも書かれています。つまり、ワークスペースやクライアントによって見え方が違う可能性があります。
|
|
45
|
+
|
|
46
|
+
現在の Slack で比較的安定して表示されるもの:
|
|
47
|
+
|
|
48
|
+
- `**bold**`, `*italic*`, `~~strike~~`, インラインコード, フェンスドコード
|
|
49
|
+
- bare URL, `<https://...>` 形式リンク, Markdown リンク, 参照リンク, mailto リンク
|
|
50
|
+
- 箇条書き, 番号付きリスト, タスクリスト, 単純な引用
|
|
51
|
+
- Markdown テーブルを変換した明示的な Slack `table` ブロック
|
|
52
|
+
- Slack 側で新しい Markdown 表示が有効な環境では、`markdown` ブロック内の見出し・水平線・表
|
|
53
|
+
|
|
54
|
+
Slack 側の制約として残るもの:
|
|
55
|
+
|
|
56
|
+
- 見出しサイズや一部の新しい Markdown 表示は、Slack アプリ・ワークスペース・有効化状況に依存する
|
|
57
|
+
- `markdown` ブロック内の段落区切りは、実測した Slack Web では上下の余白がほとんどなく、空行がつぶれて見えやすい
|
|
58
|
+
- 多段引用はフル Markdown レンダラほどきれいに出ない
|
|
59
|
+
- `markdown` ブロック内の生 Markdown テーブルは一部環境では表示されるが、安定性では明示的な Slack `table` ブロックの方が上
|
|
60
|
+
- Markdown 画像記法は `markdown` ブロック内では埋め込み画像にならない
|
|
61
|
+
- 数式, 生 HTML, HTML comment, `<details>`, admonition 記法, Mermaid は特別な表示にならず、テキストまたはコードとして出る
|
|
62
|
+
|
|
63
|
+
このライブラリが吸収するもの:
|
|
64
|
+
|
|
65
|
+
- underscore 装飾 (`_..._`, `__...__`) を Slack 互換の asterisk 装飾へ正規化
|
|
66
|
+
- bare URL を Slack の `<https://...>` 形式にそろえる
|
|
67
|
+
- 崩れた Markdown テーブルを補って Slack `table` ブロックへ変換
|
|
68
|
+
- フェンスドコード内の table 風行をテーブル処理から除外
|
|
69
|
+
- 必要に応じて、内部空行を補助用の行に置き換えて段落の区切りを見えやすくする
|
|
70
|
+
- 生 HTML 風タグなど、Slack の特殊記法としては無効な `<...>` 形式を無害化
|
|
71
|
+
|
|
72
|
+
## 利用前提
|
|
73
|
+
|
|
74
|
+
- Slack Block Kit の `blocks` で `markdown` / `table` ブロックを送信できる実装が必要です。
|
|
75
|
+
- `text` / `mrkdwn` のみ送信できる経路では利用できません。
|
|
76
|
+
|
|
77
|
+
## インストール
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install slack-markdown-parser
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 最小利用例
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from slack_markdown_parser import (
|
|
87
|
+
convert_markdown_to_slack_payloads,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
markdown = """
|
|
91
|
+
# Weekly Report
|
|
92
|
+
|
|
93
|
+
| Team | Status |
|
|
94
|
+
|---|---|
|
|
95
|
+
| API | **On track** |
|
|
96
|
+
| UI | *In progress* |
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
for payload in convert_markdown_to_slack_payloads(
|
|
100
|
+
markdown,
|
|
101
|
+
preserve_visual_blank_lines=True,
|
|
102
|
+
):
|
|
103
|
+
print(payload)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`convert_markdown_to_slack_messages` は、複数テーブルを含む入力を Slack 制約に合わせて複数メッセージへ分割します。
|
|
107
|
+
Slack Web の新しい `markdown` 表示で段落間の余白が極端に小さい場合は、`preserve_visual_blank_lines=True` を使うと内部空行だけを見えやすく補えます。
|
|
108
|
+
|
|
109
|
+
## 入出力イメージ
|
|
110
|
+
|
|
111
|
+
検証テキスト:
|
|
112
|
+
|
|
113
|
+
````markdown
|
|
114
|
+
# 週次プロダクト更新
|
|
115
|
+
|
|
116
|
+
今週は**検索速度改善**と*UI調整*を進めました。旧仕様は~~廃止予定~~です。
|
|
117
|
+
詳細ログIDは`run-20260305-02`です。
|
|
118
|
+
参考: https://example.com/changelog
|
|
119
|
+
|
|
120
|
+
- APIの**レスポンス改善**
|
|
121
|
+
- *キャッシュヒット率*を改善
|
|
122
|
+
- タイムアウト設定を調整
|
|
123
|
+
- バッチ処理の安定化
|
|
124
|
+
- リトライ回数を統一
|
|
125
|
+
- ドキュメント更新
|
|
126
|
+
|
|
127
|
+
カテゴリ | 状況 | 担当
|
|
128
|
+
API | **進行中** | Team A
|
|
129
|
+
UI | *確認中* | Team B
|
|
130
|
+
QA | ~~保留~~ | Team C
|
|
131
|
+
|
|
132
|
+
> 注意: 本番反映は 3/8 10:00 JST を予定
|
|
133
|
+
|
|
134
|
+
1. リリースノート最終確認
|
|
135
|
+
1. 変更点の表記統一
|
|
136
|
+
2. 影響範囲の追記
|
|
137
|
+
2. 監視アラートしきい値調整
|
|
138
|
+
1. `warning`閾値の更新
|
|
139
|
+
3. QA再確認
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
./deploy.sh production
|
|
143
|
+
```
|
|
144
|
+
````
|
|
145
|
+
|
|
146
|
+
実際のSlack BOTでの表示例(`markdown` + `table` ブロック):
|
|
147
|
+
|
|
148
|
+

|
|
149
|
+
|
|
150
|
+
## ライブラリの公開インターフェース
|
|
151
|
+
|
|
152
|
+
### メイン関数(公開関数)
|
|
153
|
+
|
|
154
|
+
| 関数 | 説明 |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `convert_markdown_to_slack_messages(markdown_text, *, preserve_visual_blank_lines=False) → list[list[dict]]` | Markdown をテーブル分割済みのメッセージ群に変換 |
|
|
157
|
+
| `convert_markdown_to_slack_payloads(markdown_text, *, preserve_visual_blank_lines=False) → list[dict]` | `blocks` とプレビュー用 `text` を含む Slack 送信用データへ変換 |
|
|
158
|
+
| `convert_markdown_to_slack_blocks(markdown_text, *, preserve_visual_blank_lines=False) → list[dict]` | Markdown を Block Kit ブロックのリストに変換 |
|
|
159
|
+
| `build_fallback_text_from_blocks(blocks) → str` | `chat.postMessage.text` 用のプレビュー文字列を生成 |
|
|
160
|
+
| `blocks_to_plain_text(blocks) → str` | ブロックからプレーンテキストを生成 |
|
|
161
|
+
|
|
162
|
+
`preserve_visual_blank_lines=True` は、非テーブル領域の内部空行を「改行を見えやすくするための補助行」に置き換えるオプションです。
|
|
163
|
+
この補助行はプレビュー文字列を作るときに取り除かれるので、通知文やログは元の Markdown に近い形を保てます。
|
|
164
|
+
また、setext 見出しの下線直前や参照リンク定義直前には補助行を入れず、Markdown の意味が変わらないようにしています。
|
|
165
|
+
|
|
166
|
+
### ユーティリティ関数(公開関数)
|
|
167
|
+
|
|
168
|
+
| 関数 | 説明 |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `normalize_markdown_tables(markdown_text) → str` | テーブル記法を正規化(パイプ補完、区切り行生成、列数調整) |
|
|
171
|
+
| `add_zero_width_spaces_to_markdown(text) → str` | 装飾記号の前後にゼロ幅スペースを挿入(フェンスドコードブロック内は除外) |
|
|
172
|
+
| `decode_html_entities(text) → str` | HTML エンティティをデコード |
|
|
173
|
+
| `sanitize_slack_text(text) → str` | ANSI / 制御文字を除去し、不正な Slack 角括弧トークンを無害化 |
|
|
174
|
+
| `strip_zero_width_spaces(text) → str` | ゼロ幅スペース (U+200B) と BOM (U+FEFF) を除去(ZWJ 等の結合制御文字は保持) |
|
|
175
|
+
|
|
176
|
+
## 仕様
|
|
177
|
+
|
|
178
|
+
- 挙動仕様: [docs/spec-ja.md](docs/spec-ja.md)
|
|
179
|
+
- 英語仕様: [docs/spec.md](docs/spec.md)
|
|
180
|
+
- 非対応:
|
|
181
|
+
- `mrkdwn` 文字列の生成
|
|
182
|
+
- `mrkdwn` のみ送信可能なクライアント/MCP ツール
|
|
183
|
+
|
|
184
|
+
## コントリビュート
|
|
185
|
+
|
|
186
|
+
不具合報告、ドキュメント改善、コードの提案を歓迎します。
|
|
187
|
+
Issue / Pull Request を作成する前に [CONTRIBUTING.md](CONTRIBUTING.md) を参照してください。Slack 表示のメンテナ向け検証資料は、利用者向け README ではなく CONTRIBUTING 側から案内しています。
|
|
188
|
+
|
|
189
|
+
## 変更履歴
|
|
190
|
+
|
|
191
|
+
リリース履歴は [CHANGELOG.md](CHANGELOG.md) で管理しています。
|
|
192
|
+
|
|
193
|
+
## 連絡先
|
|
194
|
+
|
|
195
|
+
- GitHub Issue / Pull Request
|
|
196
|
+
- X: [@darkgaldragon](https://x.com/darkgaldragon)
|
|
197
|
+
|
|
198
|
+
## ライセンス
|
|
199
|
+
|
|
200
|
+
MIT
|