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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Text-structure detection that gates the rich paths.
//!
//! Pure predicates over the reply text: does it contain a table, a task
//! list, an ATX heading, any block structure worth native rich rendering?
//! The gates live together here so the decision surface is one file: the
//! verdict fns ([`should_send_native_rich`], [`should_send_native_rich_for`])
//! log their inputs, and the raw structure probes they compose
//! ([`contains_table`], [`contains_task_list`], [`has_rich_structure`],
//! [`is_atx_heading`]) stay quiet and cheap.
//!
//! Split out of `mod.rs` when it went declarations-only (#1293 era):
//! functions never live in `mod.rs` (see CONTRIBUTING.md).
use ;
/// 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.
///
/// #132: the scan runs on the NORMALIZED text — collapsed one-line tables are
/// reflowed first, exactly what the rich renderer receives (rich/api.rs calls
/// the same `normalize_tables` entry). Before this, the gate read raw text
/// while the renderer read normalized text: a collapsed table was invisible
/// here (still rich, via other structure) and then rendered as raw pipes —
/// the MIIDAS cron-card defect. Gate and renderer can no longer disagree.
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
/// #45 variant: `has_buttons` forces the rich plane for plain prose that ends
/// on a `suggest_options` surface. The tap rewrite preserves the host plane,
/// so a classic prose host would keep the pick record in plain HTML even
/// though the turn carries interactive buttons — button-bearing answers ride
/// rich instead. The `rich_messages` flag still gates everything (richtext
/// off = never rich, buttons or not).
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, block math, or a `<details>`
/// collapse block — matched by `<details>` line prefix so the inline
/// `<details><summary>` openers count too (the #15 receipt cards emitted that shape before the parser-safe block form).
/// 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 `<details>` collapse opener, bare or with attributes (`<details open>`).
/// Shared by the rich gate and the classic HTML ladder so the two can never
/// disagree about who renders a collapse block: [`has_rich_structure`] sends
/// it to `sendRichMessage`, and when that send fails [`prefers_rich_render`]
/// must route the fallback through the rich AST too. The line-based ladder
/// escapes unknown tags, so a collapse that reached it surfaced its literal
/// `<details>` / `<summary>` markup as visible text.
pub
/// Whether `text` opens a `<details>` collapse block on any line.
pub
/// A `# `..`###### ` ATX heading line (1-6 hashes followed by a space).
/// Shared by the rich gate and the classic HTML ladder so the two parsers
/// can never disagree on `#N`-style lines (#1257).
pub
/// Whether `text` contains a `- [ ]` / `- [x]` task-list item.
pub