telega/format

Provides utilities for text formatting in Telegram messages. Supports HTML, Markdown, and MarkdownV2 parse modes.

Quick Start

import telega/format as fmt

// Simple formatting
let text = fmt.bold("Important!") <> " " <> fmt.italic("Read this")

// Complex formatting with builder
let message = fmt.build()
  |> fmt.text("Hello ")
  |> fmt.bold_text("World")
  |> fmt.line_break()
  |> fmt.link_text("Click here", "https://example.com")
  |> fmt.to_html()

Types

Builder pattern for constructing formatted text

pub opaque type FormatBuilder

Formatted text container

pub opaque type FormattedText

Supported parse modes for Telegram

pub type ParseMode {
  HTML
  Markdown
  MarkdownV2
}

Constructors

  • HTML
  • Markdown
  • MarkdownV2

Values

pub fn bold(text: String) -> String

Format text as bold (HTML)

pub fn bold_text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add bold text using builder

pub fn build() -> FormatBuilder

Create a new format builder with HTML as default

pub fn code(text: String) -> String

Format text as inline code (HTML)

pub fn code_text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add inline code using builder

pub fn custom_emoji_text(
  builder: FormatBuilder,
  emoji: String,
  id: String,
) -> FormatBuilder

Add custom emoji using builder

pub fn entities(
  formatted: FormattedText,
) -> #(String, List(types.MessageEntity))

Render FormattedText to a plain string plus the MessageEntity list that describes its formatting.

This is the escape-free way to send formatted text: no parse mode is involved, so no character in the text is special. Offsets and lengths are in UTF-16 code units, as the Bot API requires — an emoji outside the BMP counts as two.

let #(text, entities) =
  format.build()
  |> format.text("Result: ")
  |> format.bold_text(user_supplied)
  |> format.to_formatted
  |> format.entities

Zero-length segments produce no entity — Telegram rejects those. A Mention renders as @username with a mention entity over it, and a Nested group contributes its children’s entities without one of its own.

pub fn escape_html(text: String) -> String

Escape special characters for HTML

pub fn escape_markdown(text: String) -> String

Escape special characters for Markdown

pub fn escape_markdown_code(text: String) -> String

Escape the contents of a code or pre entity.

Telegram unescapes only ` and \ inside those, so escaping the full set would leave literal backslashes in the code; escaping nothing (what this used to do) lets a backtick close the span and the rest of the message be read as the user’s formatting.

pub fn escape_markdown_url(url: String) -> String

Escape a URL for the (...) part of a MarkdownV2 link or custom emoji.

Only ) and \ are special there. Running the full escape over a URL backslash-escaped -, ., = and friends, which Telegram then leaves in the link verbatim.

pub fn escape_markdown_v2(text: String) -> String

Escape special characters for MarkdownV2

pub fn italic(text: String) -> String

Format text as italic (HTML)

pub fn italic_text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add italic text using builder

pub fn line_break(builder: FormatBuilder) -> FormatBuilder

Add line break

pub fn link(text: String, url: String) -> String

Format text as hyperlink (HTML)

pub fn link_text(
  builder: FormatBuilder,
  text: String,
  url: String,
) -> FormatBuilder

Add hyperlink using builder

pub fn mention(username: String) -> String

Format text as mention (HTML)

pub fn mention_text(
  builder: FormatBuilder,
  username: String,
) -> FormatBuilder

Add mention using builder

pub fn parse_mode_to_string(mode: ParseMode) -> String

Convert ParseMode to string for API

pub fn pre(
  code: String,
  language: option.Option(String),
) -> String

Format text as code block (HTML)

pub fn pre_text(
  builder: FormatBuilder,
  code: String,
  language: option.Option(String),
) -> FormatBuilder

Add code block using builder

pub fn render(formatted: FormattedText) -> #(String, ParseMode)

Render FormattedText to string with parse mode

pub fn spoiler(text: String) -> String

Format text as spoiler (HTML)

pub fn spoiler_text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add spoiler text using builder

pub fn strikethrough(text: String) -> String

Format text as strikethrough (HTML)

pub fn strikethrough_text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add strikethrough text using builder

pub fn text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add plain text

pub fn to_formatted(builder: FormatBuilder) -> FormattedText

Convert to FormattedText for use with reply functions

pub fn to_html(builder: FormatBuilder) -> String

Build to HTML string

pub fn to_markdown(builder: FormatBuilder) -> String

Build to Markdown string

pub fn to_markdown_v2(builder: FormatBuilder) -> String

Build to MarkdownV2 string

pub fn underline(text: String) -> String

Format text as underline (HTML)

pub fn underline_text(
  builder: FormatBuilder,
  text: String,
) -> FormatBuilder

Add underlined text using builder

pub fn with_mode(
  builder: FormatBuilder,
  mode: ParseMode,
) -> FormatBuilder

Set parse mode for builder

Search Document