
Converts CommonMark (GFM tables, strikethrough) into Telegram MarkdownV2, escapes characters, downgrades unsupported constructs, and performs structure-safe truncation or lossless chunking.
Kotlin Multiplatform 库:把 CommonMark(含 GFM 表格与删除线)转换为 Telegram MarkdownV2,并对超长内容做保持结构完整的截断或无损分片(Telegram 消息上限 4096 字符,分片按序发送即可完整送达——文本不丢字符,接缝处实体按段闭合)。为 LLM 机器人输出而生——模型回复是任意长度、任意结构的 Markdown,还经常带 Telegram 渲染不了的构造。
发布于 Maven Central,版本跟随 v* git tag。支持 Android(minSdk 23)、JVM 11+、JS、Wasm、Linux(x64/Arm64)、macOS(Arm64)、Windows(mingwX64)、iOS(设备与模拟器)。
repositories { mavenCentral() }
dependencies {
// KMP 消费方在 commonMain 引用根坐标(Gradle module metadata 自动解析平台变体);
// 需要钉住具体变体时加后缀:-android / -jvm / -js / -wasm-js / -linuxx64 /
// -linuxarm64 / -macosarm64 / -mingwx64 / -iosarm64 / -iosx64 / -iossimulatorarm64
implementation("io.github.kamiiroawase:telegram-markdownv2:2.4.0")
}import io.github.kamiiroawase.markdownv2.MarkdownV2
val text = MarkdownV2.render("**hello** world") // 直接配 parse_mode = MarkdownV2 发送
val clipped = MarkdownV2.render(reply, MarkdownV2.MAX_MESSAGE_LENGTH) // 超限截断,仍是合法 MarkdownV2
val parts = MarkdownV2.renderChunked(reply) // 无损分片,每段 ≤ 4096 且各自合法,按序发送
val literal = MarkdownV2.escape(userInput) // 手动拼 MarkdownV2 时转义动态文本
val fallback = MarkdownV2.toPlainText(rejectedPart) // 被拒收时还原纯文本、不带 parse_mode 重发RenderOptions 定制)、HTML 映射为实体或字面文本、列表项内的引用块降级为原内容(Bot API 只接受行首的未转义 >,跟在列表标记或续行缩进后的 > 会导致整条消息被 400 拒收)、会与相邻 _/__ 标记粘连的下划线族强调降级(解析器会把紧贴的 _/__ 重新配对成无法闭合的实体)MarkdownV2.defaultExtensions 之上传入自建 Parser;未知扩展节点按纯内容遍历,不崩溃<!-- -->、<!DOCTYPE> 按段落内联处理);强调内部的闭合 HTML 标签(如 *a<b>x</b>* 中的 </b>)不被识别为行内 HTML__ 是下划线不是粗体,不要把渲染结果再当普通 Markdown 二次加工git clone https://github.com/kamiiroawase/telegram-markdownv2.git
cd telegram-markdownv2
./gradlew build # JDK 21+:编译全部 target + 宿主可执行测试 + 格式检查
./gradlew jvmTest # 单独跑某个平台
./gradlew benchmark # 性能基准:常规消息 ~0.1ms 量级,百万字符 ~10ms;发版时 CI 复跑输出附在 GitHub Release321 个行为级测试(输入/输出断言),全部平台运行。质量门禁全挂在 build 上:Spotless 格式、explicitApi() 显式 API、binary-compatibility-validator 公开 API 快照(有意变更时跑 ./gradlew apiDump)。
The Unlicense —— 公共领域,随意使用。
Kotlin Multiplatform 库:把 CommonMark(含 GFM 表格与删除线)转换为 Telegram MarkdownV2,并对超长内容做保持结构完整的截断或无损分片(Telegram 消息上限 4096 字符,分片按序发送即可完整送达——文本不丢字符,接缝处实体按段闭合)。为 LLM 机器人输出而生——模型回复是任意长度、任意结构的 Markdown,还经常带 Telegram 渲染不了的构造。
发布于 Maven Central,版本跟随 v* git tag。支持 Android(minSdk 23)、JVM 11+、JS、Wasm、Linux(x64/Arm64)、macOS(Arm64)、Windows(mingwX64)、iOS(设备与模拟器)。
repositories { mavenCentral() }
dependencies {
// KMP 消费方在 commonMain 引用根坐标(Gradle module metadata 自动解析平台变体);
// 需要钉住具体变体时加后缀:-android / -jvm / -js / -wasm-js / -linuxx64 /
// -linuxarm64 / -macosarm64 / -mingwx64 / -iosarm64 / -iosx64 / -iossimulatorarm64
implementation("io.github.kamiiroawase:telegram-markdownv2:2.4.0")
}import io.github.kamiiroawase.markdownv2.MarkdownV2
val text = MarkdownV2.render("**hello** world") // 直接配 parse_mode = MarkdownV2 发送
val clipped = MarkdownV2.render(reply, MarkdownV2.MAX_MESSAGE_LENGTH) // 超限截断,仍是合法 MarkdownV2
val parts = MarkdownV2.renderChunked(reply) // 无损分片,每段 ≤ 4096 且各自合法,按序发送
val literal = MarkdownV2.escape(userInput) // 手动拼 MarkdownV2 时转义动态文本
val fallback = MarkdownV2.toPlainText(rejectedPart) // 被拒收时还原纯文本、不带 parse_mode 重发RenderOptions 定制)、HTML 映射为实体或字面文本、列表项内的引用块降级为原内容(Bot API 只接受行首的未转义 >,跟在列表标记或续行缩进后的 > 会导致整条消息被 400 拒收)、会与相邻 _/__ 标记粘连的下划线族强调降级(解析器会把紧贴的 _/__ 重新配对成无法闭合的实体)MarkdownV2.defaultExtensions 之上传入自建 Parser;未知扩展节点按纯内容遍历,不崩溃<!-- -->、<!DOCTYPE> 按段落内联处理);强调内部的闭合 HTML 标签(如 *a<b>x</b>* 中的 </b>)不被识别为行内 HTML__ 是下划线不是粗体,不要把渲染结果再当普通 Markdown 二次加工git clone https://github.com/kamiiroawase/telegram-markdownv2.git
cd telegram-markdownv2
./gradlew build # JDK 21+:编译全部 target + 宿主可执行测试 + 格式检查
./gradlew jvmTest # 单独跑某个平台
./gradlew benchmark # 性能基准:常规消息 ~0.1ms 量级,百万字符 ~10ms;发版时 CI 复跑输出附在 GitHub Release321 个行为级测试(输入/输出断言),全部平台运行。质量门禁全挂在 build 上:Spotless 格式、explicitApi() 显式 API、binary-compatibility-validator 公开 API 快照(有意变更时跑 ./gradlew apiDump)。
The Unlicense —— 公共领域,随意使用。