#nullable enable using System; using System.Collections.Generic; using System.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; namespace Kruzya.TelegramBot.Core.Service; internal class EntityFormatter { private static readonly Dictionary HtmlMap = new() { { MessageEntityType.Bold, "{0}" }, { MessageEntityType.Code, "{0}" }, { MessageEntityType.Italic, "{0}" }, { MessageEntityType.TextMention, "{0}" }, { MessageEntityType.Pre, "
{0}
" }, { MessageEntityType.Underline, "{0}" }, { MessageEntityType.TextLink, "{0}" } }; private static readonly Dictionary MarkdownMap = new() { { MessageEntityType.Bold, "*{0}*" }, { MessageEntityType.Code, "```{0}```" }, { MessageEntityType.Italic, "_{0}_" }, { MessageEntityType.TextMention, "[{0}](tg://user?id={1})" }, { MessageEntityType.Pre, "```{0}```" }, { MessageEntityType.Underline, "__{0}__" }, { MessageEntityType.TextLink, "[{0}]({1})" } }; /// /// Performs the formatting a text representation of message from entity with /// /// /// /// public string? FormatMessage(Message msg, ParseMode parseMode = ParseMode.Html) { var text = ""; var entities = msg.Entities; if (entities != null) { // Suppress the warning about possibility using empty ref (CS8602). text = msg.Text!; // TODO: Currently, this algo don't support inherited entities. This need thinking. foreach (var entity in entities.Reverse()) { var entityText = text.Substring(entity.Offset, entity.Length); text = text.Replace(entityText, FormatEntity(entity, entityText, parseMode)); } } return text; } public string FormatEntity(MessageEntity entity, string text, ParseMode parseMode) { var dict = parseMode switch { ParseMode.Html => HtmlMap, ParseMode.Markdown => MarkdownMap, ParseMode.MarkdownV2 => MarkdownMap, _ => throw new Exception("Unsupported parse mode") }; var arg = entity.Type switch { MessageEntityType.TextMention => entity.User!.Id.ToString(), MessageEntityType.TextLink => entity.Url!, _ => "" }; return dict[entity.Type].Replace("{0}", text) .Replace("{1}", arg); } }