On the morning of September 21, a dozen changes were made over three hours in the libprisma repository — which Telegram uses to color code blocks in messages. Tolk, the primary TON smart contract language, was added to the language table, the definitions for Tact and FunC were updated, and for the first time since November 20, 2023, the file read by applications was recompiled.
This is not yet visible in applications. Each client carries its own copy of the table, and all three copies are from 2023.

How Telegram Colors Code
A code block in a message is parsed not by the server, but by the client itself. Parsing is handled by libprisma — a C++ port of the browser library Prism.js, which Telegram released in autumn 2023. The generator collects language rules from two places — from the Prism.js package and from several files written directly in the repository, which is where the TON languages come from — runs them through normalization, and compiles them into a single binary file, grammars.dat. The client loads this file on startup and then queries it for tokens for each code block — identifying keywords, strings, and comments.
Such a file represents the entire list of supported languages. If a language is not in the table, the block remains gray monospace text, even if the author honestly signed it tolk after three backticks.
Android is structured differently: the Prism engine there is rewritten in Java, and it uses its own table, codelng.gzip, which arrived with version 10.2 at the end of October 2023. The different regular expression engines for the same table — Boost in C++ and java.util.regex in Java — will later prove to be the main reason why there were twelve changes instead of two.
Why TON Languages Are Still Gray
They remain gray not because no one wrote rules for TON. Definitions for four languages — Tact, FunC, Fift, and TL-B — were added to the libprisma source code in May 2024. Four months later, an update was brought to the same repository: Tact from version 1.2.0 to 1.6.0, and a completely rewritten FunC from 0.2.0 to 0.4.4.
Neither of these reached the applications, and the reason is not with the applications themselves. Language rules reside in the repository as regular files, but clients read a binary table compiled from them — and this table was last compiled on November 20, 2023, half a year before the first TON language was added to the repository. Everything added afterward remained in the source code and was not deployed.
The build is performed by a GitHub Actions workflow, and it hadn't run since: GitHub deprecated actions/upload-artifact@v3, after which the task was marked as failed before its first step could even execute. The Tact and FunC update thus remained in the queue for two years.
Tolk is a separate story. The language emerged as an evolution of FunC and is now designated as recommended in the TON documentation, while FunC itself has been moved to the deprecated category. It was proposed for libprisma in May 2026 and kept as a draft with a note that it was necessary to first understand how to roll it out to all clients.
What Happened on September 21
First, the build was fixed. Action versions were updated, Node 18 was replaced with 22, and the task now runs again — manually and automatically whenever language rules change — after which it opens a pull request with the recompiled table. After this, Tolk and the Tact and FunC updates were accepted.
An error was found in the update along the way, which caused FunC not to be fully highlighted. The rule for function operators (_+_, _<=>_, and others where underscores denote argument positions) was built from another rule, which ended with a check for "whitespace next". In its compiled form, the check required a space exactly where the closing underscore was mandatory — an impossible condition, so the rule never triggered.
The remaining changes do not concern TON, but explain why one table is suitable for two engines at once. Boost reads expressions byte by byte and does not understand \uXXXX notation: inside a character class, such notation turns into a set of arbitrary ASCII characters. Because of this, in the Dhall language, the operator class ate the first letter of each type name, and the quantifier ∀ was not highlighted in any language where it is described. Table serialization truncated the high byte for characters beyond the first two hundred fifty-six, and the BQN symbol • written in the grammar arrived in the table as a double quote, ∞ as a control character, π as the letter À.
The third change concerns the divergence of engines. \v compiles in both and means different things in them: in one, it's a single vertical tab character, in the other, it's the entire class of vertical whitespace including a newline, which caused values in ini to escape past the end of their line. A "does it compile" check doesn't catch this, so now for each pull request, the table is recompiled, and each of the almost four thousand expressions is run through both engines.
When This Will Be Seen in Applications
No deadline is set in any of them. Clients do not retrieve the table from the repository on the fly; instead, they carry their own copy, and each copy is older than the very first TON language in libprisma.
| Client | Where it gets the table | Copy date |
|---|---|---|
| Telegram Desktop | libprisma fork, pinned as a submodule | April 2024, table inside is November 2023 |
| Telegram for iOS | grammars.dat file in the client repository itself | October 31, 2023 |
| Telegram for Android | codelng.gzip file in application resources | October 28, 2023 |
Updating the copy is a decision for each client team, and the Tolk draft explicitly stated this: the PR was awaiting an answer on how to roll out the new table to all applications. Until there is an answer, a block signed tolk, tact, or func looks the same in correspondence as it did yesterday.



