1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Telegram rich-message support (Bot API "rich messages", 2026-06).
//!
//! Pipeline: markdown text → [`ast::Block`] AST ([`parse`]) → either Telegram's
//! `InputRichMessage` JSON (rich-first path, finalized against the Bot API
//! field schema) or Telegram HTML ([`render_html`], the fallback path).
//!
//! The AST and parser are deliberately independent of the wire schema, so the
//! markdown front-end and its tests don't churn when the serializer lands, and
//! the same AST drives both the rich and fallback renderers.
//!
//! Files are kept small and single-purpose: [`ast`] (types), [`inline`] /
//! [`table`] / [`list`] / [`parse`] (front-end), [`render_html`] (fallback),
//! [`render_json`] (rich-first serializer, #420 path B).
pub
pub
pub
pub use parse_markdown;
/// Whether `text` is better served by the AST renderer than the legacy
/// line-based converter: it contains a GitHub-flavored table or a task-list
/// checkbox, both of which the legacy path renders poorly (raw `| pipes |` and
/// literal `- [ ]` respectively).
pub
/// Whether `text` contains a GitHub-flavored pipe table.
pub
/// Whether a structured reply should be delivered as a native rich message:
/// the `channels.telegram.rich_messages` config flag is on AND the text has
/// block structure ([`has_rich_structure`]). On by default (#425); older
/// clients and Telegram Web show a "not supported" placeholder, so outdated
/// deployments opt out (onboard dialog or `richtext off`) and get the
/// universal HTML rendering. Read via the zero-disk config mirror.
pub
/// Whether `text` contains block-level markdown structure that native rich
/// rendering handles meaningfully better than plain/HTML: a table, ATX
/// heading, list item, fenced code block, or block math. Plain prose (even
/// with inline emphasis) returns false, so it stays on the existing path and
/// is never reinterpreted by Telegram's markdown parser. Gates the native
/// `sendRichMessage` path (together with the config flag).
///
/// A message is NEVER disqualified from rich (the #476 fence-disqualify was
/// reverted: it dragged tables in mixed table+fence messages onto the HTML
/// path, where tables unwrap to raw pipes). Fence mangling under the rich
/// markdown parser is a separate cosmetic issue whose real fix is the
/// native-block serializer (#420 path B), not exclusion.
pub
/// A `# `..`###### ` ATX heading line (1-6 hashes followed by a space).
/// Whether `text` contains a `- [ ]` / `- [x]` task-list item.
pub
/// Parse `text` into the native `InputRichMessage` block value (#476 path
/// B): `{"blocks": [...]}`, sent via `api::send_rich_blocks_id`. No
/// server-side markdown re-parsing, so tables AND code fences render
/// natively with no parser to mangle them (the fence-artifact bug the
/// markdown input mode cannot avoid). Falls back to the markdown/HTML send
/// paths on any API rejection.
pub
/// Parse `text` and render it as Telegram HTML in one call (the fallback path).
pub