Supported markdown
slackmark accepts CommonMark, GFM (tables, task lists, strikethrough, and autolinks), footnotes, Slack entity tokens, Mermaid charts, GitHub-style admonitions, and optional math and frontmatter. Each construct maps to the most native Slack block available; when a capability is off or a limit is hit, it falls down an ordered chain and records a degradation.
Block-level constructs
| Markdown | Native output | Fallback chain |
|---|---|---|
| Heading 1–4 | header with level | header without level (needs headerLevel) |
| Heading 5–6, > 150 chars, or with inline markup | Bold rich_text section | — (Slack headers stop at level 4 / plain text) |
| Paragraph | rich_text section | — (adjacent sections coalesce into one block) |
| Bullet / numbered list | rich_text_list (nested, ordered start kept) | Indent clamped at 6 levels |
Task list (- [x]) | markdown block with checkboxes (needs markdownBlock) | rich_text_list with ☑ / ☐ characters |
| GFM table ≤ 50 rows | table (needs tableBlock) | markdown pipe table → preformatted text |
| GFM table ≤ 200 data rows | data_table (needs dataTable) | Truncated table → markdown → preformatted |
| GFM table > 20 columns | markdown pipe table | Preformatted text |
| Code fence | Image via matching configured renderer | rich_text_preformatted with language → same without language |
mermaid fence, pie / xychart-beta | data_visualization (needs dataVisualization) | Image via configured renderer → preformatted mermaid source |
mermaid fence, other diagrams | Image via configured renderer | Preformatted mermaid source |
Math block $$…$$ (enableMath) | Image via matching configured renderer | rich_text_preformatted with latex language → same without it |
| Blockquote | rich_text_quote | Nested lists / code inside quotes flatten to text lines |
Admonition (> [!NOTE] etc.) | rich_text_quote with emoji + bold title line | NOTE 📝, TIP 💡, IMPORTANT ❗, WARNING ⚠️, CAUTION 🚫 |
| Image on its own line | image block | Link or text unless a public http(s) png/jpg/gif ≤ 3000 chars |
Thematic break --- | divider | — |
Footnotes [^1] | [n] markers + trailing divider + context blocks | Duplicate definitions: first wins |
<details><summary> HTML | Collapsible container (needs containerBlock) | Bold title + body section; inline content becomes plain text |
| Other block HTML | Tags stripped; text kept as a section | Slack tokens convert but may keep surrounding tags as literal text |
Frontmatter (enableFrontmatter) | Skipped | Always a degradation record |
HTML degradation reporting is incomplete; see Validating output.
Several rows above appear nowhere else in these docs. Here is a sampler of them, all default options:
> Plain quote with a [link](https://example.com). 1. First 1. Nested 2. Second --- <details> <summary>Rollback plan</summary> Revert the deploy, then page the on-call. </details> See the runbook[^1]. [^1]: https://example.com/runbook
Block Kit JSON
…
Inline constructs
| Markdown | Output |
|---|---|
**bold**, *italic*, ~~strike~~ | Rich text styles (combinable) |
`code` | Code-styled text; never scanned for mentions or emoji |
[label](https://…), autolinks | link element; http(s) and mailto only, other schemes become text + URL |
Reference links [label][ref] | Resolved against definitions; unresolved stay text |
| Inline image | Hoisted to an image block; link left in place |
<@U…>, <#C…>, <!here>, <!subteam^…>, <!date^…> | Native mention / broadcast / date elements (details) |
<https://…|label> | link element with the label |
:emoji: | emoji element, including custom workspace emoji |
@handle, #channel | Mentions via mentionResolvers; else literal text |
Inline HTML <b>, <i>, <s>, <code>, <a>, <br> | Corresponding styles, links, and line breaks |
| Other inline HTML | Stripped to text with a degradation |
Inline math $x$ (enableInlineMath) | Code-styled text with a degradation; literal text unless opted in |
| Hard break | Newline within the section |
Limits enforced during conversion
The converter enforces Slack's documented Block Kit limits plus a small number of explicitly labeled defensive choices. It truncates or falls back with a degradation rather than emitting a payload it knows exceeds those limits:
| Limit | Value |
|---|---|
| Blocks per message | 50 |
| Header text | 150 chars |
| Section text | 3,000 chars |
| Image URL / alt text | 3,000 / 2,000 chars |
| Table rows / columns | 100 / 20 |
data_table data rows | 200 |
Cumulative markdown block text | 12,000 chars |
| Chart segments / series / points | 12 / 12 / 20 |
| Chart title / labels | 50 / 20 chars |
| Charts per message | 2 (defensive, community-reported) |
Notification text | 40,000 chars |
validateBlocks asserts the block
limits above offline; the notification-text clamp is applied separately
during message assembly.