Repository navigation
Telegram announcements split long sections; nested lists render on Telegram and XDA - #42
Merged
Merged
Conversation
The 5.0.8 announcement's "What's New" section is 5,767 characters with no divider inside it. chunk_telegram_html only split at dividers, so the bot would have posted the intro and then had the second message refused for being over Telegram's 4,096-character limit, leaving half an announcement. post_telegram.py: - Messages end at the last divider that fits, else the last blank line, line break or space, never inside a tag or entity. Length is visible text in UTF-16 units, as Telegram counts it. A tag open at a split (a quote) is closed there and reopened in the next message. - Every message is checked before the first is sent: length, tags Telegram supports, nesting. A failure exits 1 with nothing sent; a dry run reports the message count and sizes. - Text is escaped, so a stray <, > or & can't break the HTML parse; the notes' own tags are kept. <br> becomes a newline. - Indented bullets render as nested "◦" items, and an item's indented second paragraph loses its stray indent. - Non-web links (obtainium://) show their address as code instead of raw Markdown. format_xda.py: indented bullets open a nested [LIST], and an indented paragraph stays inside its list item instead of closing and reopening the list. 5.0.8 notes: "the attached APK" becomes "this build", since Telegram and XDA link to the APK rather than attach it. Tests cover every announcement in docs/release_notes (each splits into messages Telegram accepts with no words lost; every XDA render has balanced lists), plus splitting, tag balancing, escaping and the refusal checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP
There is no bot token on the release Mac, and announcements are posted by hand in Telegram Desktop, which reads its own markdown (**bold**, __italic__, ||spoiler||, `code`) rather than the HTML render. post_telegram.py --desktop-parts DIR writes each message the chunker makes as DIR/part-N.txt in that markdown, so each part stays under Telegram's limit and keeps its formatting. Links show their address unless Telegram links the label itself (a bare address or an @name). Stale parts are removed first. The 5.0.8 notes gain a Download line linking the release, since Telegram and XDA readers otherwise only get the repository link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP
Owner
Author
|
Generated by Claude Code |
Telegram Desktop applies only the outermost of nested markers, so the 5.0.8 riddle answer, <tg-spoiler><b>…</b>…</tg-spoiler>, would have been sent as ||**An app's Overview preview!**…|| with the asterisks showing. post_telegram.py: - Desktop parts write only the outermost marker, map strikethrough to ~~ and pre to ```, and unescape a link address once. They are measured after links are written out and re-split with a smaller budget until each part fits. Text that holds **, __, ||, ~~ or a backtick, and markers next to a letter, digit or dash (which Telegram Desktop won't format), are reported as warnings. - The whole post's markup is checked before splitting, since a split closes any tag left open. An empty post, or a message with no text, is refused. Refusals exit 4 (EXIT_NOT_POSTABLE) and release_unified.py reports "Telegram would refuse the rendered notes, nothing was sent" instead of asking to check for partial posts. - A run of dividers is one break, and a piece with no text of its own (a divider, or a tag cut off at a split) joins its neighbour. A break right after a heading line is the last resort, and a line break before a top-level line beats one inside a nested list. - Entities the notes spell out (&, —) show as their characters, except inside `code`, where GitHub shows them as typed. format_xda.py: an indented paragraph after a sub-list closes it and joins the parent item (5.0.4's hand-fixed BBCode now comes out as committed); tabs count as 4 columns; a bullet outdented between two levels stays beside the deeper one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP
- Telegram: an indented paragraph inside a list stays under its bullet instead of becoming a separate line at the left edge, and sub-bullets render as indented hollow bullets. - Telegram: HTML entities in the notes are held as placeholders while markdown is converted, so `> ` is never read as a quote and an escaped `*` or `-` stays literal. - Telegram: the divider-run pattern is linear, a heading counts as a break point after a blank line or an emoji prefix, and Desktop marker warnings use an allow-list of separators and skip code spans. - XDA: list nesting follows the item's content column, so tabs and uneven indents nest correctly and a wrapped line continues its item. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP
5.0.8 has now run on the Pixel 7 Pro as the recents provider: previews, card actions, Clear all and Screenshot worked with no crashes. Say so, say that Overview's own Share and Lens buttons haven't been tried on a phone, and point reports at setups where Expressive runs Overview. Regenerate the Telegram changelog and the XDA thread BBCode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP
denson9874
marked this pull request as ready for review
October 30, 2026 22:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Follow-up to #41 for the published 5.0.8 (70). No app code changes, so the sealed APKs are unaffected.
The 5.0.8 announcement's "What's New" block is 5,767 characters with no divider inside it.
chunk_telegram_htmlonly split at dividers, so a bot post would have sent the intro and then had message 2 refused for being over Telegram's 4,096-character limit, leaving half an announcement. The renders also had list problems on both Telegram and XDA.scripts/post_telegram.pyEXIT_NOT_POSTABLE) with nothing sent, andrelease_unified.pyreports it as such. A dry run prints the message count and sizes.<,>or&can't break Telegram's HTML parse; the notes' own tags are kept, and entities they spell out show as their characters (except insidecode). Entities are held as placeholders while Markdown is converted, so>is never read as a quote and an escaped*or-stays literal.<br>becomes a newline.◦items, and a list item's indented paragraph stays under its bullet.obtainium://) show their address as code instead of raw Markdown.--desktop-parts DIRwrites each message as Telegram Desktop markdown (**bold**,__italic__,||spoiler||,~~strike~~,`code`) toDIR/part-N.txt. The Mac has no bot token, and announcements are posted by hand in Telegram Desktop, which doesn't read the HTML. Only the outermost of nested markers is written, since Telegram Desktop applies only that one. Parts are measured after link addresses are written out and re-split until each fits, and markers that won't format are reported (an allow-list of the separators Telegram Desktop accepts; code spans are skipped).scripts/format_xda.py: list nesting follows each item's content column, so tabs and uneven indents nest correctly; an indented paragraph stays inside its list item, after any sub-list it follows, and a wrapped line continues its item.docs/release_notes/5.0.8_announcement.md: "the attached APK" becomes "this build", since Telegram and XDA link to the APK rather than attach it. A Download line linksqa-v5.0.8-70. Validation now carries the Pixel 7 Pro result for 5.0.8 (built into the ROM as the recents provider: previews, card actions, Clear all and Screenshot worked with no crashes; Overview's Share and Lens weren't on that phone to test), and section 1 says Share and Lens are checked in code only.TELEGRAM_CHANGELOG.txt,docs/release_notes/xda_thread_post_5.0.8.bbcode: generated from the final notes. The BBCode is the one posted on XDA (post #40) with Daryl's approval; both GitHub release bodies were edited to the same text.Testing
python3 -m unittest discover -s ci/tests: 406 tests OK (1 skipped).docs/release_notes(31 files): each splits into messages Telegram accepts with no words lost, and each XDA render has balanced lists and no indented lines. Others cover the split rules, tag balancing, the refusal checks and exit codes (with and without a token, and in a dry run), escaping and entities, nested bullets and item paragraphs, non-web links, a long divider run (linear time), and the Telegram Desktop parts (outermost markers, link addresses, warnings, fitting after links are expanded).check-stylefails on the base branch too (Spotless on 66 Kotlin files this PR doesn't touch); see the earlier comment.Type of change
✅ Bug fix (A non-breaking change that fixes an issue)
❌ New feature (A non-breaking change that adds functionality)
❌ Breaking change (A fix or feature that would cause existing functionality to not work as expected)
❌ Refactor (A code change that neither fixes a bug nor adds a feature)
❌ Performance (A code change that improves performance)
❌ Style (Code style changes)
✅ Docs (Changes to documentation)
✅ Chore (Changes to the build process or other tooling)
🤖 Generated with Claude Code
https://claude.ai/code/session_01Csz3takA5by6WEejggRjcP